[{"content":"Postgres Internals 14 阅读笔记 Egor Rogov 的 PostgreSQL 14 Internals 读书笔记入口。中文在线版方便查阅，英文 PDF 方便离线精读。\n资料 中文在线版：PostgreSQL 14 Internals（中文） 英文 PDF（本站电子书库）：postgresql_internals-14_parts1-3_en.pdf PostgreSQL 14 Internals (EN, Parts 1–3) 新窗口打开 下载 数据组织 数据库 当初始化一个 PG 实例之后，PGDATA 会自动创建以下三种基础数据库：\ntemplate0: 用来通过逻辑复制，或创建不同编码数据库的原型/样板； template1: 用户在此实例下创建所有其他数据库的模版，新建库都基于它； postgres: 自带的一个常规库； ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/postgresinternal/","summary":"\u003ch1 id=\"postgres-internals-14-阅读笔记\"\u003ePostgres Internals 14 阅读笔记\u003c/h1\u003e\n\u003cp\u003eEgor Rogov 的 \u003cem\u003ePostgreSQL 14 Internals\u003c/em\u003e 读书笔记入口。中文在线版方便查阅，英文 PDF 方便离线精读。\u003c/p\u003e\n\u003ch2 id=\"资料\"\u003e资料\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e中文在线版：\u003ca href=\"https://postgres-internals.cn/docs/chapter01/\"\u003ePostgreSQL 14 Internals（中文）\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e英文 PDF（本站电子书库）：\u003ca href=\"/ebooks/postgresql_internals-14_parts1-3_en.pdf\"\u003epostgresql_internals-14_parts1-3_en.pdf\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cfigure class=\"pdf-embed\"\u003e\n  \u003cdiv class=\"pdf-embed__bar\"\u003e\n    \u003cspan class=\"pdf-embed__title\"\u003ePostgreSQL 14 Internals (EN, Parts 1–3)\u003c/span\u003e\n    \u003ca class=\"pdf-embed__link\" href=\"/ebooks/postgresql_internals-14_parts1-3_en.pdf\" target=\"_blank\" rel=\"noopener\"\u003e新窗口打开\u003c/a\u003e\n    \u003ca class=\"pdf-embed__link\" href=\"/ebooks/postgresql_internals-14_parts1-3_en.pdf\" download\u003e下载\u003c/a\u003e\n  \u003c/div\u003e\n  \u003ciframe\n    class=\"pdf-embed__frame\"\n    src=\"/ebooks/postgresql_internals-14_parts1-3_en.pdf\"\n    title=\"PostgreSQL 14 Internals (EN, Parts 1–3)\"\n    height=\"720\"\n    loading=\"lazy\"\n  \u003e\u003c/iframe\u003e\n\u003c/figure\u003e\n\n\u003chr\u003e\n\u003ch2 id=\"数据组织\"\u003e数据组织\u003c/h2\u003e\n\u003ch3 id=\"数据库\"\u003e数据库\u003c/h3\u003e\n\u003cp\u003e当初始化一个 PG 实例之后，PGDATA 会自动创建以下三种基础数据库：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003etemplate0: 用来通过逻辑复制，或创建不同编码数据库的原型/样板；\u003c/li\u003e\n\u003cli\u003etemplate1: 用户在此实例下创建所有其他数据库的模版，新建库都基于它；\u003c/li\u003e\n\u003cli\u003epostgres: 自带的一个常规库；\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg alt=\"image\" loading=\"lazy\" src=\"/images/uploads/image.png\"\u003e\u003c/p\u003e","title":"PostgresInternal"},{"content":"4 安全架构 4.1 威胁模型 | STRIDE类别 | 威胁描述 | 针对的生命周期阶段 | 对应安全功能（章节） | |------------|----------|------------------|----------------------| | **S** 欺骗 | 攻击者伪造合法用户/系统身份 | 访问、传输 | 身份认证、安全传输（TLS/TLCP） | | **T** 篡改 | 攻击者修改数据或代码 | 传输、计算、存储 | 安全传输、数据防篡改（账本表）、全密态加密、审计日志防篡改 | | **R** 否认 | 用户否认执行过某操作 | 所有阶段 | 安全审计（不可否认记录） | | **I** 信息泄露 | 敏感数据被未授权读取 | 访问、传输、计算、存储 | 访问控制、安全传输、透明加密、全密态加密、机密计算、数据脱敏 | | **D** 拒绝服务 | 攻击者使系统不可用 | 访问、网络 | 网络ACL、SQL防火墙（阻断异常大查询） | | **E** 权限提升 | 普通用户获得更高权限 | 访问、计算 | 访问控制（三权分立、最小权限）、数据库防火墙 | 角色 动机 目标 技术 分类 黑客 售卖获利 鉴别数据 不可信IP登录 欺骗 内部运维人员 勒索获利 用户表 暴力破解 篡改 内部研发人员 情报窃取 系统表 凭证重放 否认 系统维护人员 蓄意报复 事务日志 默认账户攻击 信息泄露 供应链 规避审计 审计日志 过期账号攻击 拒绝服务 网络中间人 炫耀技能 内存数据 弱口令攻击 权限提升 机房管理人员 人为过失 配置文件 内存凭证残留 - - - - 认证耗尽 - - - - 密码泄露 - - - - 数据泄露 - - - - 流量伪造 - - - - 流量重放 - - - - 密钥泄露 - - - - 证书伪造 - - - - 身份伪造 - - - - 未授权访问 - - - - 越权访问 - - - - 权限提升 - - - - 权限滥用 - - - - 磁盘窃取 - - - - 恶意软件 - - - - 系统隔离失效 - - - - 文件篡改 - - - - 日志伪造 - - - - 特权窥探 - - - - 供应链后门 - - - - 内存嗅探 - - - - 调试工具滥用 - - - - 操作抵赖 - - - - 攻击隐匿 - - - - 合规证据缺失 - 攻击者画像 攻击动机 攻击阶段 攻击类型 攻击目标 攻击技术（ATT\u0026amp;CK） 影响的安全域（GB/T 20273） 风险等级 安全功能与标准映射 外部渗透测试者 数据窃取 侦察 欺骗(S) 认证凭据 暴力破解(T1110) 身份鉴别(4.1) 高 身份认证；GB/T 20273 4.1；ISO 27001 A.9；NIST IA-5 内部恶意DBA 数据篡改 武器化 篡改(T) 会话令牌 中间人攻击(T1557) 传输数据保密性(4.8.2) 高 TLS双向认证；GB/T 20273 4.8.2；ISO 27001 A.13.2；NIST SC-8 内部开发人员 权限提升 投递 否认(R) 数据字典 账户操纵(T1098) 安全审计(4.6) 高 统一审计；GB/T 20273 4.6；ISO 27001 A.12.4；NIST AU-3 第三方运维人员 拒绝服务 利用 信息泄露(I) 用户表数据 SQL注入(T1190) 自主访问控制(4.2) 高 数据脱敏；GB/T 20273 4.2；PCI DSS 3.2 网络中间人 规避审计 安装 拒绝服务(D) 审计日志 日志清除(T1070) 用户数据完整性(4.7) 高 审计日志防篡改；GB/T 20273 4.7；ISO 27001 A.12.4；NIST AU-9 云租户（恶意） 勒索 命令与控制 权限提升(E) 存储过程/函数 服务器软件组件劫持(T1505) 强制访问控制(4.4) 中 最小权限原则；GB/T 20273 4.4；NIST AC-6 恶意应用程序 报复 目标达成 - 备份集 数据加密（防御绕过）(T1022) 存储数据保密性(4.8.1) 高 透明加密(TDE)；GB/T 20273 4.8.1；ISO 27001 A.10.1 恶意OS管理员 间谍活动 - - 内存中的明文 进程注入(T1055) 标记(4.3) 高 机密计算(TEE)；NIST SC-3 物理入侵者 误操作 - - 配置文件 系统信息发现(T1082) 可信路径(4.9) 中 网络ACL；GB/T 20273 4.9；ISO 27001 A.13.1 - 身份伪造 - - 数据导出文件 数据破坏(T1485) - 低 备份加密 - 会话劫持 - - 数据库链接 服务停止(T1489) - - SQL防火墙 - - - - 索引/分区 通过API攻击(T1559) - - 行级安全(RLS) - - - - 物化视图 客户端连接劫持(T1184) - - 列级加密 - - - - 同义词 网络嗅探(T1040) - - 三权分立 - - - - 触发器等对象 创建账户(T1136) - - 密钥管理(KMS/HSM) - - - - 临时表空间 数据从本地拉取(T1213) - - 全密态执行 - - - - Undo日志 禁用安全工具(T1562) - - 权限分析工具 - - - - 控制文件 受信关系利用(T1199) - - - - - - - 监听器/端口 反向工程(T1598) - - - - - - - SSL证书私钥 数据加密(自身通讯)(T1573) - - - - - - - 数据库参数 域策略修改(T1484) - - - - - - - 数据库进程内存 - - - - - - - - 数据快照 - - - - - - - - 数据库服务端口 - - - - gemini 攻击者画像 攻击动机 攻击阶段 (Kill Chain) 攻击类型 (STRIDE) 攻击目标 (数据库资产) 攻击技术（MITRE ATT\u0026amp;CK） ISO 15408 (CC) 功能组件映射 商业标杆对标 (Oracle企业版组件) 本内核架构防御机制基线 外部黑客/APT组织 经济利益(勒索/售卖) 侦察 (Recon) 欺骗(Spoofing) 认证凭据 (Hash/密码) T1190 利用面向公众的应用 FIA_UAU.2 (用户鉴别) Oracle Centrally Managed Users (CMU) 统一身份认证与多因素(MFA) 内部恶意超管/DBA 商业间谍(数据窃密) 武器化 (Weaponization) 篡改(Tampering) 数据文件(MDF/PGDATA) T1110 暴力破解 FCS_COP.1 (密码运算) Oracle Advanced Security (TDE) 透明数据加密 (TDE) 内部研发/测试人员 蓄意破坏(报复社会) 投递 (Delivery) 否认(Repudiation) WAL/Redo/Undo日志 T1098 账户操纵 FAU_GEN.1 (审计数据产生) Oracle Audit Vault and DB Firewall (AVDF) 高性能异步统一审计与防篡改日志 供应链/第三方运维 掩盖罪行(规避审计) 漏洞利用 (Exploitation) 信息泄露(Info Disclosure) 系统目录/数据字典 T1078 有效账户(默认/后门) FDP_ACC.1 (子集访问控制) Oracle Database Vault (Realm特权隔离) 强三权分立与安全堡垒(Realm)隔离 网络中间人(MITM) 炫耀技能(黑客主义) 安装/植入 (Installation) 拒绝服务(DoS) 业务表核心数据 T1059 命令行解释器提权 FDP_DAU.1 (基本数据鉴别) Oracle Blockchain Tables / Immutable Tables 数据防篡改内核账本 (Ledger Hash) 恶意云租户/邻居 误操作(配置失误) 命令与控制 (C2) 特权提升(Elevation) 审计日志记录 T1552 访问非安全凭据 FMT_SMR.1 (安全管理角色) Oracle Label Security (OLS) 强制访问控制 (MAC 安全标签) 恶意OS管理员 资源盗用(挖矿) 横向移动 (Lateral Move) 侧信道探测(Side-Channel) 密钥/证书/Keystore T1040 网络嗅探 FDP_RIP.1 (残余信息保护) Oracle Advanced Security (Data Redaction) 动态数据脱敏 (DDM) 物理机房入侵者 合规性破坏(名誉打击) 目标达成 (Actions) - 存储过程/UDF/扩展插件 T1557 中间人攻击 FCS_CKM.1 (密码密钥产生与管理) Oracle Key Vault (OKV) 两级密钥管理架构 (KMS/HSM对接) 失陷的业务程序 - - - 数据库进程内存 (SGA) T1070 清除审计日志 FPT_ITT.1 (内部TOE传输保护) Oracle Virtual Private Database (VPD) 行级安全 / 列级安全 (RLS / CLS) 离职/僵尸账号 - - - 监听器/暴露网络端口 T1486 影响数据加密(勒索) FTA_TSE.1 (TOE会话建立) Oracle Data Safe (合规评估与发现) 敏感数据发现与分类分级扫描 - - - - 会话令牌/Session T1485 数据破坏(删库) FPT_PHP.3 (抗物理攻击的TSF) Always Encrypted (SQL Server标杆) 硬件级机密计算 (TEE/SGX 内核隔离) - - - - DBLink/跨库链接 T1005 收集本地系统数据 - - 全密态执行引擎 (内存密态运算) - - - - 物理备份集/快照 T1565 数据逻辑操纵 - - 全链路 TLS 1.3 / 国密 TLCP 加密通道 - - - - 视图/物化视图/触发器 T1184 客户端连接劫持 - - 细粒度网络准入 (IP/用户元组控制) - - - - 数据库配置文件 - - - 内核级 SQL 防火墙 (基于AST白名单) - - - - 临时表空间(Temp) - - - - deepseek 攻击者画像 攻击动机 攻击阶段 攻击类型 (STRIDE) 攻击目标 攻击技术 (ATT\u0026amp;CK) 影响的安全域 (GB/T 20273-2019) 风险等级 安全功能与标准映射（示例） 外部渗透测试者 数据窃取 侦察 欺骗 (S) 认证凭据 暴力破解 (T1110) 身份鉴别 (4.1) 高 多因素认证；GB/T 20273 4.1；ISO 27001 A.8.5 内部恶意DBA 权限提升 武器化 篡改 (T) 会话令牌 SQL注入 (T1190) 自主访问控制 (4.2) 中 TLS双向认证；GB/T 20273 4.7.2；NIST SC-8 内部开发人员 数据篡改 投递 否认 (R) 数据字典 中间人攻击 (T1557) 强制访问控制 (4.4) 低 统一审计；GB/T 20273 4.5；ISO 27001 A.8.15 第三方运维人员 拒绝服务 利用 信息泄露 (I) 用户表数据 账户操纵 (T1098) 安全审计 (4.5) - 数据脱敏；PCI DSS 3.2 网络中间人 规避审计 安装 拒绝服务 (D) 审计日志 日志清除 (T1070) 用户数据完整性 (4.6) - 审计日志防篡改；NIST AU-9 恶意应用程序 勒索 命令与控制 权限提升 (E) 存储过程/函数 进程注入 (T1055) 存储数据保密性 (4.7.1) - 最小权限原则；GB/T 20273 4.4；NIST AC-6 恶意OS管理员 报复 目标达成 - 备份集 服务器软件组件劫持 (T1505) 传输数据保密性 (4.7.2) - 透明加密 (TDE)；ISO 27001 A.8.24 物理入侵者 间谍活动 持久化 - 内存中的明文 数据加密（影响）(T1485) 可信路径 (4.8) - 机密计算 (TEE)；NIST SC-3 云租户（恶意） 误操作 收集 - 配置文件 系统信息发现 (T1082) 网络安全 (4.9) - 网络ACL；GB/T 20273 4.9 恶意内部员工 身份伪造 渗出 - 数据导出文件 服务停止 (T1489) - - 备份加密；DLP 外部攻击者 会话劫持 物理访问 - 数据库链接 数据破坏 (T1485) - - SQL防火墙；连接限制 内部运维人员 侦察 - - 索引/分区 通过API攻击 (T1559) - - 行级安全 (RLS) 内部用户 - - - 物化视图 客户端连接劫持 (T1184) - - 列级加密 - - - - 同义词 网络嗅探 (T1040) - - 三权分立 - - - - 触发器等对象 创建账户 (T1136) - - 密钥管理 (KMS/HSM) - - - - 临时表空间 数据从本地拉取 (T1213) - - 全密态执行 - - - - Undo日志 禁用安全工具 (T1562) - - 权限分析工具 - - - - 控制文件 受信关系利用 (T1199) - - 不可变备份 - - - - 监听器/端口 反向工程 (T1598) - - 配置基线检查 - - - - SSL证书私钥 数据加密(自身通信) (T1573) - - 端口隐藏 - - - - 数据库参数 域策略修改 (T1484) - - 内存加密 - - - - 数据库进程内存 内存刮削 (T1535) - - 快照加密 - - - - 数据快照 数据泄露 (T1213) - - 文件系统权限 - - - - 数据库服务端口 端口扫描 (T1046) - - - 攻击者画像 攻击动机 攻击阶段 (Kill Chain) 攻击类型 (STRIDE) 攻击目标 (数据库资产) 攻击技术 (ATT\u0026amp;CK) 影响的安全域 (GB/T 20273-2019) 风险等级 安全功能与标准映射（含商业组件 \u0026amp; 内核防御） 外部黑客/APT组织 经济利益（勒索/售卖） 侦察 欺骗 (S) 认证凭据（密码Hash/票据） 暴力破解 (T1110) 身份鉴别 (4.1) 高 多因素认证；Oracle CMU；ISO 27001 A.8.5；NIST IA-5 → 统一身份认证与MFA内核模块 网络中间人 会话劫持 利用 篡改 (T) 会话令牌/Cookie 中间人攻击 (T1557) 传输数据保密性 (4.7.2) 高 TLS双向认证；Oracle Advanced Security；GB/T 20273 4.7.2；NIST SC-8 → 全链路TLS 1.3/国密TLCP加密通道 内部恶意DBA 商业间谍（数据窃密） 武器化 否认 (R) 数据字典/系统编目 账户操纵 (T1098) 安全审计 (4.5) 高 统一审计+防篡改日志；Oracle Audit Vault；GB/T 20273 4.5；ISO 27001 A.8.15 → 高性能异步审计与只读日志内核 第三方运维人员 数据窃取 投递 信息泄露 (I) 业务核心表数据 SQL注入 (T1190) 自主访问控制 (4.2) 高 SQL防火墙+静态脱敏；Oracle AVDF；PCI DSS 3.2 → 内核级AST白名单SQL防火墙 恶意内部员工 规避审计 安装 篡改 (T) 审计日志记录 日志清除 (T1070) 用户数据完整性 (4.6) 高 审计日志防篡改（只读表空间）；Oracle Blockchain Table；NIST AU-9 → 内核防篡改账本（Ledger Hash） 云租户（恶意邻居） 勒索 命令与控制 权限提升 (E) 存储过程/函数/包 服务器软件组件劫持 (T1505) 强制访问控制 (4.4) 中 最小权限+代码签名；Oracle Database Vault；NIST AC-6 → 强三权分立与Realm特权隔离 恶意应用程序 报复 目标达成 拒绝服务 (D) 物理备份集/快照 数据破坏 (T1485) 存储数据保密性 (4.7.1) 高 不可变备份+离线存储；Oracle RMAN；ISO 27001 A.8.13 → 备份加密与防删除兜底策略 恶意OS管理员 间谍活动 横向移动 信息泄露 (I) 数据库进程内存(SGA/PGA) 进程注入/内存刮削 (T1055/T1535) 用户数据保密性 (4.7.1) 高 机密计算(TEE/SGX)；Oracle Database 23ai Secure Enclaves；NIST SC-3 → 内存密态运算引擎 物理入侵者 误操作/物理破坏 物理访问 信息泄露 (I) 配置文件(spfile/pg_hba) 系统信息发现 (T1082) 可信路径 (4.8) 中 文件系统权限+配置加密；Oracle Data Safe；GB/T 20273 4.8；ISO 27001 A.8.1 → 内核可信路径与完整性校验 离职/僵尸账号 身份伪造 利用 欺骗 (S) 数据库链接(DBLink) 有效账户滥用 (T1078) 身份鉴别 (4.1) 中 账户生命周期管理；Oracle CMU；ISO 27001 A.8.2 → 动态权限回收与实时拦截 失陷的业务程序 数据泄露 渗出 信息泄露 (I) 敏感数据列（身份证/手机号） 通过API攻击 (T1559) 存储数据保密性 (4.7.1) 中 动态数据脱敏+行级安全；Oracle VPD/OLS；ISO 27001 A.8.26 → 列级加密(CLS)与行级安全(RLS) 内部运维人员 侦察 侦察 信息泄露 (I) 索引/分区/物化视图 网络嗅探 (T1040) 网络安全 (4.9) 低 加密通信+网络ACL；Oracle CMAN；GB/T 20273 4.9；ISO 27001 A.8.20 → 细粒度网络准入控制 供应链/第三方开发 权限提升 持久化 权限提升 (E) 触发器/UDF/扩展插件 创建账户 (T1136) 强制访问控制 (4.4) 高 权限分析+代码审查；Oracle Database Vault；NIST AC-6 → 插件签名验证与默认拒绝策略 内部恶意DBA 掩盖罪行 目标达成 篡改 (T) Undo/Redo/WAL日志 禁用安全工具 (T1562) 用户数据完整性 (4.6) 高 防篡改日志+权限分析；Oracle Audit Vault；ISO 27001 A.8.15 → 写入只读日志流与篡改即报警 云租户（恶意） 权限提升 利用 欺骗 (S) 控制文件/密码文件 受信关系利用 (T1199) 身份鉴别 (4.1) 高 网络隔离+强认证；Oracle MFA；GB/T 20273 4.1；NIST IA-5 → 基于TEE的密钥保护 外部攻击者 勒索 利用 拒绝服务 (D) 数据库监听器/服务端口 服务停止 (T1489) 网络安全 (4.9) 中 端口隐藏+SQL防火墙；Oracle CMAN；ISO 27001 A.8.22 → 内核级连接限流与抗DDoS 网络中间人 数据窃取 利用 信息泄露 (I) SSL证书私钥/Keystore 数据加密(自身通信) (T1573) 传输数据保密性 (4.7.2) 高 HSM/KMS保护私钥；Oracle Key Vault；NIST SC-12 → 两级密钥管理架构 内部恶意DBA 规避审计 安装 篡改 (T) 数据库参数(init.ora) 域策略修改 (T1484) 安全审计 (4.5) 高 配置基线检查+变更审计；Oracle AVDF；CIS 基线 → 参数修改自动回滚与告警 恶意内部员工 数据窃取 收集 信息泄露 (I) 临时表空间/临时文件 数据从本地拉取 (T1213) 存储数据保密性 (4.7.1) 中 全密态执行+临时文件加密；Always Encrypted；ISO 27001 A.8.24 → 全密态查询处理引擎 物理入侵者 数据窃取 渗出 信息泄露 (I) 数据快照/克隆副本 数据泄露 (T1213) 存储数据保密性 (4.7.1) 中 快照加密+访问审计；Oracle RMAN；ISO 27001 A.8.12 → 存储级加密与快照防激活 外部渗透测试者 侦察 侦察 信息泄露 (I) 数据库服务端口/监听器 端口扫描 (T1046) 网络安全 (4.9) 低 防火墙策略+IPS；Oracle CMAN；GB/T 20273 4.9 → 端口敲门与隐身技术 chatgpt 攻击者画像 攻击动机 攻击阶段 攻击类型 攻击目标 攻击技术 影响安全域（GB/T 20273） 风险等级 安全功能与标准映射 外部攻击者 数据窃取 侦察 机密性攻击 用户凭据 暴力破解（T1110） 身份鉴别（4.1） 高 身份认证；GB/T 20273 4.1；ISO 27001 A.9；ISO 15408 FIA 内部恶意DBA 数据篡改 权限提升 完整性攻击 会话令牌 中间人攻击（T1557） 传输数据保密性（4.8.2） 中 TLS双向认证；GB/T 20273 4.8.2；ISO 27001 A.13.2；NIST SC-8 内部开发人员 权限提升 执行 否认攻击 数据字典 账户操纵（T1098） 安全审计（4.6） 高 统一审计；GB/T 20273 4.6；ISO 27001 A.12.4；NIST AU-3 第三方运维人员 拒绝服务 利用 信息泄露攻击 用户表数据 SQL注入（T1190） 自主访问控制（4.2） 高 数据脱敏；GB/T 20273 4.2；PCI DSS 3.2 网络中间人 规避审计 安装 可用性攻击 审计日志 日志清除（T1070） 用户数据完整性（4.7） 高 审计日志防篡改；GB/T 20273 4.7；ISO 27001 A.12.4；NIST AU-9 云租户 勒索 命令与控制 权限提升攻击 存储过程/函数 服务器组件劫持（T1505） 强制访问控制（4.4） 中 最小权限原则；GB/T 20273 4.4；NIST AC-6 恶意应用程序 报复 目标达成 机密性攻击 备份集 数据加密防绕过（T1022） 存储数据保密性（4.8.1） 高 透明加密(TDE)；GB/T 20273 4.8.1；ISO 27001 A.10.1 恶意操作系统管理员 间谍活动 - - 内存明文 进程注入（T1055） 标记（4.3） 高 机密计算(TEE)；NIST SC-3 物理入侵者 误操作 - - 配置文件 系统信息发现（T1082） 可信路径（4.9） 中 网络ACL；GB/T 20273 4.9；ISO 27001 A.13.1 - 身份伪造 - - 数据导出文件 数据破坏（T1485） - 低 备份加密 - 会话劫持 - - 数据库链接 服务停止（T1489） - - SQL防火墙 - - - - 索引/分区 通过API攻击（T1559） - - 行级安全(RLS) - - - - 物化视图 客户端连接劫持（T1184） - - 列级加密 - - - - 同义词 网络嗅探（T1040） - - 三权分立 - - - - 触发器等对象 创建账户（T1136） - - 密钥管理(KMS/HSM) - - - - 临时表空间 数据从本地拉取（T1213） - - 全密态执行 - - - - Undo日志 禁用安全工具（T1562） - - 权限分析工具 - - - - 控制文件 受信关系利用（T1199） - - - - - - - 监听器/端口 反向工程（T1598） - - - - - - - SSL证书私钥 数据加密（自身通讯）（T1573） - - - - - - - 数据库参数 域策略修改（T1484） - - - - - - - 数据库进程内存 - - - - - - - - 数据快照 - - - - - - - - 数据库服务端口 - - - - 关系数据库安全威胁维度字典（多维去重 · 结构化版） 攻击者画像 攻击动机 攻击阶段 攻击类型 攻击目标 攻击技术 影响安全域（GB/T 20273 / ISO 15408） 风险等级 安全功能与标准映射 外部攻击者 数据窃取 侦察 机密性攻击 用户凭据 暴力破解（T1110） 身份鉴别（4.1） 高 身份认证 / MFA 内部恶意DBA 数据篡改 初始访问 完整性攻击 会话令牌 SQL注入（T1190） 自主访问控制（4.2） 中 访问控制（RBAC/RLS） 内部开发人员 权限提升 执行 可用性攻击 数据字典 中间人攻击（T1557） 标记（4.3） 低 三权分立 第三方运维人员 拒绝服务 持久化 不可否认性攻击 用户表数据 账户操纵（T1098） 强制访问控制（4.4） - 最小权限 网络中间人 勒索 权限提升 - 索引/分区 日志清除（T1070） 安全审计（4.6） - 审计日志防篡改 云租户 报复 防御规避 - 物化视图 进程注入（T1055） 用户数据完整性（4.7） - 统一审计 恶意应用程序 间谍活动 凭据获取 - 同义词 服务器组件劫持（T1505） 存储数据保密性（4.8.1） - 透明加密（TDE） 恶意操作系统管理员 规避审计 内部侦察 - 存储过程/函数 数据加密防绕过（T1022） 传输数据保密性（4.8.2） - TLS / 双向认证 物理入侵者 误操作 横向移动 - 触发器等对象 系统信息发现（T1082） 可信路径（4.9） - 网络ACL 离职/僵尸账号 身份伪造 数据收集 - 临时表空间 通过API攻击（T1559） FIA / FDP / FAU / FMT / FCS / FPT - SQL防火墙 自动化攻击工具 会话劫持 数据外传 - Undo日志 客户端连接劫持（T1184） - - 行级安全（RLS） - - 影响/破坏 - 控制文件 创建账户（T1136） - - 列级安全（CLS） - - - - 监听器/端口 数据从本地拉取（T1213） - - 数据脱敏 - - - - SSL证书私钥 禁用安全工具（T1562） - - 密钥管理（KMS/HSM） - - - - 数据库参数 受信关系利用（T1199） - - 全密态执行 - - - - 数据库进程内存 反向工程（T1598） - - 机密计算（TEE） - - - - 数据快照 数据加密（自身通讯）（T1573） - - 数据分类分级 - - - - 数据库服务端口 - - - 配置基线检查 4.2 防御模型 一、访问安全 威胁ID 威胁描述 STRIDE 风险等级 缓解的安全功能 T-ACS-01 弱口令爆破或默认账户攻击 S 高 身份认证（密码策略、账户锁定、MFA） T-ACS-02 重放攻击（抓取认证报文后重放） S 中 身份认证（Challenge-Response、Kerberos时间戳） T-ACS-03 从不可信IP或恶意主机连接 S/D 中 网络ACL（IP白名单） T-ACS-04 SQL注入攻击绕过权限检查 E 高 SQL防火墙（SQL白名单）、最小权限原则 T-ACS-05 内部人员滥用合法权限（如DBA偷看数据） I/E 高 访问控制（三权分立、行级安全）、数据脱敏 T-ACS-06 权限过度授予导致横向越权 E 高 访问控制（RBAC、最小权限）、权限分析工具 T-ACS-07 用户否认执行了某项敏感操作 R 高 安全审计（统一审计、细粒度审计） 二、传输安全 威胁ID 威胁描述 STRIDE 风险等级 缓解的安全功能 T-TRP-01 网络嗅探窃听数据库通信 I 高 安全传输（TLS 1.3、国密TLCP） T-TRP-02 中间人攻击（MITM）篡改或劫持会话 T/S 高 安全传输（证书双向验证、防降级攻击） T-TRP-03 会话劫持后模拟合法用户 S 高 安全传输（会话加密、绑定认证） 三、计算安全 威胁ID 威胁描述 STRIDE 风险等级 缓解的安全功能 T-CPT-01 数据库管理员或恶意进程在内存中读取敏感数据 I 高 全密态加密、机密计算（TEE） T-CPT-02 通过侧信道攻击（如Cache时间）推断数据 I 中-高 机密计算（恒定时间执行）、全密态加密 T-CPT-03 SQL执行计划中泄露敏感值（如错误消息、执行计划） I 中 数据脱敏（返回结果遮盖）、错误消息泛化 T-CPT-04 攻击者调用加密函数进行暴力破解或穷举 I/D 中 加密函数（密钥强度限制、防暴力调用策略） T-CPT-05 云环境下虚拟机管理器直接读取数据库进程内存 I 高 机密计算（TEE内执行、加密内存） T-CPT-06 已授权用户通过脱敏绕过机制看到原始数据 I 中 数据脱敏（权限校验、防绕过） 四、存储安全 威胁ID 威胁描述 STRIDE 风险等级 缓解的安全功能 T-STR-01 攻击者窃取磁盘或备份介质，绕过数据库直接读取数据文件 I 高 透明加密（TDE）、备份加密 T-STR-02 攻击者或恶意OS篡改数据文件中的数据块 T 高 数据防篡改（哈希链、账本表）、块级校验 T-STR-03 未授权用户通过文件系统直接拷贝数据文件 I 高 透明加密（TDE）+ 文件权限保护 T-STR-04 备份介质丢失导致数据泄露 I 高 透明加密（备份加密） T-STR-05 密钥管理不当（硬编码、弱密钥、不轮换）导致加密失效 I/T 高 密钥管理（KMS、HSM、自动轮换） T-STR-06 敏感数据未被识别（未分类分级）导致保护缺失 I 高 数据发现（自动扫描、分类分级） 五、合法合规 威胁ID 威胁描述 STRIDE 风险等级 缓解的安全功能 T-AUD-01 攻击者或恶意管理员删除/篡改审计日志以掩盖痕迹 T/R 高 审计日志防篡改（只写一次、WORM存储、加密） T-AUD-02 审计日志被未授权读取（泄露用户行为） I 中 审计日志加密存储、访问控制 T-AUD-03 审计数据量过大导致性能下降或日志溢出 D 中 统一审计（条件审计、采样审计） T-AUD-04 合规性检查时无法证明对敏感数据的控制措施 R 高 合规对标（等保、ISO、GDPR）、审计记录完整性 4.3 安全功能 一、访问安全 身份认证、访问控制（自主访问控制、强制访问控制、角色访问控制（三权分立）、行级访问控制） 二、传输安全 SSL 三、计算安全 加密函数、全密态、机密计算、动态脱敏 四、存储安全 透明加密、防篡改 五、合法合规 安全审计、密钥管理 一、接入安全\n1. 网络防火墙\n- 不可信IP登录\n2. 身份认证\n暴力破解\n凭证重放\n默认账户攻击\n过期账号攻击\n弱口令攻击\n内存凭证残留\n认证耗尽\n密码泄露\n二、传输安全\n3. 安全传输\n数据泄露\n流量伪造\n流量重放\n会话密钥泄露\n证书伪造\n身份伪造\n三、访问安全\n4. 访问控制\n未授权访问\n越权访问\n权限提升\n权限滥用\n权限提升\n四、存储安全\n6. 加密函数\n7. 透明加密\n磁盘窃取\n恶意软件\n操作系统隔离失效\n8. 数据防篡改\n数据文件篡改\n审计日志伪造\n五、计算安全\n9. 驱动加密\n10. 机密计算\n特权用户窥探\n供应链后门\n侧信道内存嗅探\n调试工具滥用\n六、合法合规\n11. 安全审计\n恶意操作抵赖\n攻击行为隐匿\n合规审计证据缺失\n动态脱敏\n账号过度可见\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/1-security-architecture/","summary":"\u003ch1 id=\"4-安全架构\"\u003e4 安全架构\u003c/h1\u003e\n\u003ch2 id=\"41-威胁模型\"\u003e4.1 威胁模型\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-fallback\" data-lang=\"fallback\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e| STRIDE类别 | 威胁描述 | 针对的生命周期阶段 | 对应安全功能（章节） |\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e|------------|----------|------------------|----------------------|\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e| **S** 欺骗 | 攻击者伪造合法用户/系统身份 | 访问、传输 | 身份认证、安全传输（TLS/TLCP） |\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e| **T** 篡改 | 攻击者修改数据或代码 | 传输、计算、存储 | 安全传输、数据防篡改（账本表）、全密态加密、审计日志防篡改 |\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e| **R** 否认 | 用户否认执行过某操作 | 所有阶段 | 安全审计（不可否认记录） |\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e| **I** 信息泄露 | 敏感数据被未授权读取 | 访问、传输、计算、存储 | 访问控制、安全传输、透明加密、全密态加密、机密计算、数据脱敏 |\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e| **D** 拒绝服务 | 攻击者使系统不可用 | 访问、网络 | 网络ACL、SQL防火墙（阻断异常大查询） |\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e| **E** 权限提升 | 普通用户获得更高权限 | 访问、计算 | 访问控制（三权分立、最小权限）、数据库防火墙 |\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth style=\"text-align: left\"\u003e角色\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e动机\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e目标\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e技术\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e分类\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e黑客\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e售卖获利\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e鉴别数据\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e不可信IP登录\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e欺骗\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e内部运维人员\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e勒索获利\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e用户表\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e暴力破解\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e篡改\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e内部研发人员\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e情报窃取\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e系统表\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e凭证重放\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e否认\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e系统维护人员\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e蓄意报复\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e事务日志\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e默认账户攻击\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e信息泄露\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e供应链\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e规避审计\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e审计日志\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e过期账号攻击\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e拒绝服务\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e网络中间人\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e炫耀技能\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e内存数据\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e弱口令攻击\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e权限提升\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e机房管理人员\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e人为过失\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e配置文件\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e内存凭证残留\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e认证耗尽\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e密码泄露\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e数据泄露\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e流量伪造\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e流量重放\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e密钥泄露\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e证书伪造\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e身份伪造\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e未授权访问\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e越权访问\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e权限提升\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e权限滥用\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e磁盘窃取\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e恶意软件\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e系统隔离失效\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e文件篡改\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e日志伪造\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e特权窥探\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e供应链后门\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e内存嗅探\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e调试工具滥用\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e操作抵赖\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e攻击隐匿\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e合规证据缺失\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e攻击者画像\u003c/th\u003e\n          \u003cth\u003e攻击动机\u003c/th\u003e\n          \u003cth\u003e攻击阶段\u003c/th\u003e\n          \u003cth\u003e攻击类型\u003c/th\u003e\n          \u003cth\u003e攻击目标\u003c/th\u003e\n          \u003cth\u003e攻击技术（ATT\u0026amp;CK）\u003c/th\u003e\n          \u003cth\u003e影响的安全域（GB/T 20273）\u003c/th\u003e\n          \u003cth\u003e风险等级\u003c/th\u003e\n          \u003cth\u003e安全功能与标准映射\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e外部渗透测试者\u003c/td\u003e\n          \u003ctd\u003e数据窃取\u003c/td\u003e\n          \u003ctd\u003e侦察\u003c/td\u003e\n          \u003ctd\u003e欺骗(S)\u003c/td\u003e\n          \u003ctd\u003e认证凭据\u003c/td\u003e\n          \u003ctd\u003e暴力破解(T1110)\u003c/td\u003e\n          \u003ctd\u003e身份鉴别(4.1)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e身份认证；GB/T 20273 4.1；ISO 27001 A.9；NIST IA-5\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e内部恶意DBA\u003c/td\u003e\n          \u003ctd\u003e数据篡改\u003c/td\u003e\n          \u003ctd\u003e武器化\u003c/td\u003e\n          \u003ctd\u003e篡改(T)\u003c/td\u003e\n          \u003ctd\u003e会话令牌\u003c/td\u003e\n          \u003ctd\u003e中间人攻击(T1557)\u003c/td\u003e\n          \u003ctd\u003e传输数据保密性(4.8.2)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003eTLS双向认证；GB/T 20273 4.8.2；ISO 27001 A.13.2；NIST SC-8\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e内部开发人员\u003c/td\u003e\n          \u003ctd\u003e权限提升\u003c/td\u003e\n          \u003ctd\u003e投递\u003c/td\u003e\n          \u003ctd\u003e否认(R)\u003c/td\u003e\n          \u003ctd\u003e数据字典\u003c/td\u003e\n          \u003ctd\u003e账户操纵(T1098)\u003c/td\u003e\n          \u003ctd\u003e安全审计(4.6)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e统一审计；GB/T 20273 4.6；ISO 27001 A.12.4；NIST AU-3\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e第三方运维人员\u003c/td\u003e\n          \u003ctd\u003e拒绝服务\u003c/td\u003e\n          \u003ctd\u003e利用\u003c/td\u003e\n          \u003ctd\u003e信息泄露(I)\u003c/td\u003e\n          \u003ctd\u003e用户表数据\u003c/td\u003e\n          \u003ctd\u003eSQL注入(T1190)\u003c/td\u003e\n          \u003ctd\u003e自主访问控制(4.2)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e数据脱敏；GB/T 20273 4.2；PCI DSS 3.2\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e网络中间人\u003c/td\u003e\n          \u003ctd\u003e规避审计\u003c/td\u003e\n          \u003ctd\u003e安装\u003c/td\u003e\n          \u003ctd\u003e拒绝服务(D)\u003c/td\u003e\n          \u003ctd\u003e审计日志\u003c/td\u003e\n          \u003ctd\u003e日志清除(T1070)\u003c/td\u003e\n          \u003ctd\u003e用户数据完整性(4.7)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e审计日志防篡改；GB/T 20273 4.7；ISO 27001 A.12.4；NIST AU-9\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e云租户（恶意）\u003c/td\u003e\n          \u003ctd\u003e勒索\u003c/td\u003e\n          \u003ctd\u003e命令与控制\u003c/td\u003e\n          \u003ctd\u003e权限提升(E)\u003c/td\u003e\n          \u003ctd\u003e存储过程/函数\u003c/td\u003e\n          \u003ctd\u003e服务器软件组件劫持(T1505)\u003c/td\u003e\n          \u003ctd\u003e强制访问控制(4.4)\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e最小权限原则；GB/T 20273 4.4；NIST AC-6\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e恶意应用程序\u003c/td\u003e\n          \u003ctd\u003e报复\u003c/td\u003e\n          \u003ctd\u003e目标达成\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e备份集\u003c/td\u003e\n          \u003ctd\u003e数据加密（防御绕过）(T1022)\u003c/td\u003e\n          \u003ctd\u003e存储数据保密性(4.8.1)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e透明加密(TDE)；GB/T 20273 4.8.1；ISO 27001 A.10.1\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e恶意OS管理员\u003c/td\u003e\n          \u003ctd\u003e间谍活动\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e内存中的明文\u003c/td\u003e\n          \u003ctd\u003e进程注入(T1055)\u003c/td\u003e\n          \u003ctd\u003e标记(4.3)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e机密计算(TEE)；NIST SC-3\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e物理入侵者\u003c/td\u003e\n          \u003ctd\u003e误操作\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e配置文件\u003c/td\u003e\n          \u003ctd\u003e系统信息发现(T1082)\u003c/td\u003e\n          \u003ctd\u003e可信路径(4.9)\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e网络ACL；GB/T 20273 4.9；ISO 27001 A.13.1\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e身份伪造\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据导出文件\u003c/td\u003e\n          \u003ctd\u003e数据破坏(T1485)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e低\u003c/td\u003e\n          \u003ctd\u003e备份加密\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e会话劫持\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据库链接\u003c/td\u003e\n          \u003ctd\u003e服务停止(T1489)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eSQL防火墙\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e索引/分区\u003c/td\u003e\n          \u003ctd\u003e通过API攻击(T1559)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e行级安全(RLS)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e物化视图\u003c/td\u003e\n          \u003ctd\u003e客户端连接劫持(T1184)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e列级加密\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e同义词\u003c/td\u003e\n          \u003ctd\u003e网络嗅探(T1040)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e三权分立\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e触发器等对象\u003c/td\u003e\n          \u003ctd\u003e创建账户(T1136)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e密钥管理(KMS/HSM)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e临时表空间\u003c/td\u003e\n          \u003ctd\u003e数据从本地拉取(T1213)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e全密态执行\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eUndo日志\u003c/td\u003e\n          \u003ctd\u003e禁用安全工具(T1562)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e权限分析工具\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e控制文件\u003c/td\u003e\n          \u003ctd\u003e受信关系利用(T1199)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e监听器/端口\u003c/td\u003e\n          \u003ctd\u003e反向工程(T1598)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eSSL证书私钥\u003c/td\u003e\n          \u003ctd\u003e数据加密(自身通讯)(T1573)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据库参数\u003c/td\u003e\n          \u003ctd\u003e域策略修改(T1484)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据库进程内存\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据快照\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据库服务端口\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"gemini\"\u003egemini\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth style=\"text-align: left\"\u003e攻击者画像\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e攻击动机\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e攻击阶段 (Kill Chain)\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e攻击类型 (STRIDE)\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e攻击目标 (数据库资产)\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e攻击技术（MITRE ATT\u0026amp;CK）\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003eISO 15408 (CC) 功能组件映射\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e商业标杆对标 (Oracle企业版组件)\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e本内核架构防御机制基线\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e外部黑客/APT组织\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e经济利益(勒索/售卖)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e侦察 (Recon)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e欺骗(Spoofing)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e认证凭据 (Hash/密码)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eT1190 利用面向公众的应用\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eFIA_UAU.2 (用户鉴别)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eOracle Centrally Managed Users (CMU)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e统一身份认证与多因素(MFA)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e内部恶意超管/DBA\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e商业间谍(数据窃密)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e武器化 (Weaponization)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e篡改(Tampering)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e数据文件(MDF/PGDATA)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eT1110 暴力破解\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eFCS_COP.1 (密码运算)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eOracle Advanced Security (TDE)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e透明数据加密 (TDE)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e内部研发/测试人员\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e蓄意破坏(报复社会)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e投递 (Delivery)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e否认(Repudiation)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eWAL/Redo/Undo日志\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eT1098 账户操纵\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eFAU_GEN.1 (审计数据产生)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eOracle Audit Vault and DB Firewall (AVDF)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e高性能异步统一审计与防篡改日志\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e供应链/第三方运维\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e掩盖罪行(规避审计)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e漏洞利用 (Exploitation)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e信息泄露(Info Disclosure)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e系统目录/数据字典\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eT1078 有效账户(默认/后门)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eFDP_ACC.1 (子集访问控制)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eOracle Database Vault (Realm特权隔离)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e强三权分立与安全堡垒(Realm)隔离\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e网络中间人(MITM)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e炫耀技能(黑客主义)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e安装/植入 (Installation)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e拒绝服务(DoS)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e业务表核心数据\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eT1059 命令行解释器提权\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eFDP_DAU.1 (基本数据鉴别)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eOracle Blockchain Tables / Immutable Tables\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e数据防篡改内核账本 (Ledger Hash)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e恶意云租户/邻居\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e误操作(配置失误)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e命令与控制 (C2)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e特权提升(Elevation)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e审计日志记录\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eT1552 访问非安全凭据\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eFMT_SMR.1 (安全管理角色)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eOracle Label Security (OLS)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e强制访问控制 (MAC 安全标签)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e恶意OS管理员\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e资源盗用(挖矿)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e横向移动 (Lateral Move)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e侧信道探测(Side-Channel)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e密钥/证书/Keystore\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eT1040 网络嗅探\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eFDP_RIP.1 (残余信息保护)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eOracle Advanced Security (Data Redaction)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e动态数据脱敏 (DDM)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e物理机房入侵者\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e合规性破坏(名誉打击)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e目标达成 (Actions)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e存储过程/UDF/扩展插件\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eT1557 中间人攻击\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eFCS_CKM.1 (密码密钥产生与管理)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eOracle Key Vault (OKV)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e两级密钥管理架构 (KMS/HSM对接)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e失陷的业务程序\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e数据库进程内存 (SGA)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eT1070 清除审计日志\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eFPT_ITT.1 (内部TOE传输保护)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eOracle Virtual Private Database (VPD)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e行级安全 / 列级安全 (RLS / CLS)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e离职/僵尸账号\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e监听器/暴露网络端口\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eT1486 影响数据加密(勒索)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eFTA_TSE.1 (TOE会话建立)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eOracle Data Safe (合规评估与发现)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e敏感数据发现与分类分级扫描\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e会话令牌/Session\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eT1485 数据破坏(删库)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eFPT_PHP.3 (抗物理攻击的TSF)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eAlways Encrypted (SQL Server标杆)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e硬件级机密计算 (TEE/SGX 内核隔离)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eDBLink/跨库链接\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eT1005 收集本地系统数据\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e全密态执行引擎 (内存密态运算)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e物理备份集/快照\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eT1565 数据逻辑操纵\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e全链路 TLS 1.3 / 国密 TLCP 加密通道\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e视图/物化视图/触发器\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eT1184 客户端连接劫持\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e细粒度网络准入 (IP/用户元组控制)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e数据库配置文件\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e内核级 SQL 防火墙 (基于AST白名单)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e临时表空间(Temp)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"deepseek\"\u003edeepseek\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e攻击者画像\u003c/th\u003e\n          \u003cth\u003e攻击动机\u003c/th\u003e\n          \u003cth\u003e攻击阶段\u003c/th\u003e\n          \u003cth\u003e攻击类型 (STRIDE)\u003c/th\u003e\n          \u003cth\u003e攻击目标\u003c/th\u003e\n          \u003cth\u003e攻击技术 (ATT\u0026amp;CK)\u003c/th\u003e\n          \u003cth\u003e影响的安全域 (GB/T 20273-2019)\u003c/th\u003e\n          \u003cth\u003e风险等级\u003c/th\u003e\n          \u003cth\u003e安全功能与标准映射（示例）\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e外部渗透测试者\u003c/td\u003e\n          \u003ctd\u003e数据窃取\u003c/td\u003e\n          \u003ctd\u003e侦察\u003c/td\u003e\n          \u003ctd\u003e欺骗 (S)\u003c/td\u003e\n          \u003ctd\u003e认证凭据\u003c/td\u003e\n          \u003ctd\u003e暴力破解 (T1110)\u003c/td\u003e\n          \u003ctd\u003e身份鉴别 (4.1)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e多因素认证；GB/T 20273 4.1；ISO 27001 A.8.5\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e内部恶意DBA\u003c/td\u003e\n          \u003ctd\u003e权限提升\u003c/td\u003e\n          \u003ctd\u003e武器化\u003c/td\u003e\n          \u003ctd\u003e篡改 (T)\u003c/td\u003e\n          \u003ctd\u003e会话令牌\u003c/td\u003e\n          \u003ctd\u003eSQL注入 (T1190)\u003c/td\u003e\n          \u003ctd\u003e自主访问控制 (4.2)\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003eTLS双向认证；GB/T 20273 4.7.2；NIST SC-8\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e内部开发人员\u003c/td\u003e\n          \u003ctd\u003e数据篡改\u003c/td\u003e\n          \u003ctd\u003e投递\u003c/td\u003e\n          \u003ctd\u003e否认 (R)\u003c/td\u003e\n          \u003ctd\u003e数据字典\u003c/td\u003e\n          \u003ctd\u003e中间人攻击 (T1557)\u003c/td\u003e\n          \u003ctd\u003e强制访问控制 (4.4)\u003c/td\u003e\n          \u003ctd\u003e低\u003c/td\u003e\n          \u003ctd\u003e统一审计；GB/T 20273 4.5；ISO 27001 A.8.15\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e第三方运维人员\u003c/td\u003e\n          \u003ctd\u003e拒绝服务\u003c/td\u003e\n          \u003ctd\u003e利用\u003c/td\u003e\n          \u003ctd\u003e信息泄露 (I)\u003c/td\u003e\n          \u003ctd\u003e用户表数据\u003c/td\u003e\n          \u003ctd\u003e账户操纵 (T1098)\u003c/td\u003e\n          \u003ctd\u003e安全审计 (4.5)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据脱敏；PCI DSS 3.2\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e网络中间人\u003c/td\u003e\n          \u003ctd\u003e规避审计\u003c/td\u003e\n          \u003ctd\u003e安装\u003c/td\u003e\n          \u003ctd\u003e拒绝服务 (D)\u003c/td\u003e\n          \u003ctd\u003e审计日志\u003c/td\u003e\n          \u003ctd\u003e日志清除 (T1070)\u003c/td\u003e\n          \u003ctd\u003e用户数据完整性 (4.6)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e审计日志防篡改；NIST AU-9\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e恶意应用程序\u003c/td\u003e\n          \u003ctd\u003e勒索\u003c/td\u003e\n          \u003ctd\u003e命令与控制\u003c/td\u003e\n          \u003ctd\u003e权限提升 (E)\u003c/td\u003e\n          \u003ctd\u003e存储过程/函数\u003c/td\u003e\n          \u003ctd\u003e进程注入 (T1055)\u003c/td\u003e\n          \u003ctd\u003e存储数据保密性 (4.7.1)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e最小权限原则；GB/T 20273 4.4；NIST AC-6\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e恶意OS管理员\u003c/td\u003e\n          \u003ctd\u003e报复\u003c/td\u003e\n          \u003ctd\u003e目标达成\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e备份集\u003c/td\u003e\n          \u003ctd\u003e服务器软件组件劫持 (T1505)\u003c/td\u003e\n          \u003ctd\u003e传输数据保密性 (4.7.2)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e透明加密 (TDE)；ISO 27001 A.8.24\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e物理入侵者\u003c/td\u003e\n          \u003ctd\u003e间谍活动\u003c/td\u003e\n          \u003ctd\u003e持久化\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e内存中的明文\u003c/td\u003e\n          \u003ctd\u003e数据加密（影响）(T1485)\u003c/td\u003e\n          \u003ctd\u003e可信路径 (4.8)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e机密计算 (TEE)；NIST SC-3\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e云租户（恶意）\u003c/td\u003e\n          \u003ctd\u003e误操作\u003c/td\u003e\n          \u003ctd\u003e收集\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e配置文件\u003c/td\u003e\n          \u003ctd\u003e系统信息发现 (T1082)\u003c/td\u003e\n          \u003ctd\u003e网络安全 (4.9)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e网络ACL；GB/T 20273 4.9\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e恶意内部员工\u003c/td\u003e\n          \u003ctd\u003e身份伪造\u003c/td\u003e\n          \u003ctd\u003e渗出\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据导出文件\u003c/td\u003e\n          \u003ctd\u003e服务停止 (T1489)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e备份加密；DLP\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e外部攻击者\u003c/td\u003e\n          \u003ctd\u003e会话劫持\u003c/td\u003e\n          \u003ctd\u003e物理访问\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据库链接\u003c/td\u003e\n          \u003ctd\u003e数据破坏 (T1485)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eSQL防火墙；连接限制\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e内部运维人员\u003c/td\u003e\n          \u003ctd\u003e侦察\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e索引/分区\u003c/td\u003e\n          \u003ctd\u003e通过API攻击 (T1559)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e行级安全 (RLS)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e内部用户\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e物化视图\u003c/td\u003e\n          \u003ctd\u003e客户端连接劫持 (T1184)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e列级加密\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e同义词\u003c/td\u003e\n          \u003ctd\u003e网络嗅探 (T1040)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e三权分立\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e触发器等对象\u003c/td\u003e\n          \u003ctd\u003e创建账户 (T1136)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e密钥管理 (KMS/HSM)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e临时表空间\u003c/td\u003e\n          \u003ctd\u003e数据从本地拉取 (T1213)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e全密态执行\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eUndo日志\u003c/td\u003e\n          \u003ctd\u003e禁用安全工具 (T1562)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e权限分析工具\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e控制文件\u003c/td\u003e\n          \u003ctd\u003e受信关系利用 (T1199)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e不可变备份\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e监听器/端口\u003c/td\u003e\n          \u003ctd\u003e反向工程 (T1598)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e配置基线检查\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eSSL证书私钥\u003c/td\u003e\n          \u003ctd\u003e数据加密(自身通信) (T1573)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e端口隐藏\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据库参数\u003c/td\u003e\n          \u003ctd\u003e域策略修改 (T1484)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e内存加密\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据库进程内存\u003c/td\u003e\n          \u003ctd\u003e内存刮削 (T1535)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e快照加密\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据快照\u003c/td\u003e\n          \u003ctd\u003e数据泄露 (T1213)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e文件系统权限\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据库服务端口\u003c/td\u003e\n          \u003ctd\u003e端口扫描 (T1046)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e攻击者画像\u003c/th\u003e\n          \u003cth\u003e攻击动机\u003c/th\u003e\n          \u003cth\u003e攻击阶段 (Kill Chain)\u003c/th\u003e\n          \u003cth\u003e攻击类型 (STRIDE)\u003c/th\u003e\n          \u003cth\u003e攻击目标 (数据库资产)\u003c/th\u003e\n          \u003cth\u003e攻击技术 (ATT\u0026amp;CK)\u003c/th\u003e\n          \u003cth\u003e影响的安全域 (GB/T 20273-2019)\u003c/th\u003e\n          \u003cth\u003e风险等级\u003c/th\u003e\n          \u003cth\u003e安全功能与标准映射（含商业组件 \u0026amp; 内核防御）\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e外部黑客/APT组织\u003c/td\u003e\n          \u003ctd\u003e经济利益（勒索/售卖）\u003c/td\u003e\n          \u003ctd\u003e侦察\u003c/td\u003e\n          \u003ctd\u003e欺骗 (S)\u003c/td\u003e\n          \u003ctd\u003e认证凭据（密码Hash/票据）\u003c/td\u003e\n          \u003ctd\u003e暴力破解 (T1110)\u003c/td\u003e\n          \u003ctd\u003e身份鉴别 (4.1)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e多因素认证；Oracle CMU；ISO 27001 A.8.5；NIST IA-5 → 统一身份认证与MFA内核模块\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e网络中间人\u003c/td\u003e\n          \u003ctd\u003e会话劫持\u003c/td\u003e\n          \u003ctd\u003e利用\u003c/td\u003e\n          \u003ctd\u003e篡改 (T)\u003c/td\u003e\n          \u003ctd\u003e会话令牌/Cookie\u003c/td\u003e\n          \u003ctd\u003e中间人攻击 (T1557)\u003c/td\u003e\n          \u003ctd\u003e传输数据保密性 (4.7.2)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003eTLS双向认证；Oracle Advanced Security；GB/T 20273 4.7.2；NIST SC-8 → 全链路TLS 1.3/国密TLCP加密通道\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e内部恶意DBA\u003c/td\u003e\n          \u003ctd\u003e商业间谍（数据窃密）\u003c/td\u003e\n          \u003ctd\u003e武器化\u003c/td\u003e\n          \u003ctd\u003e否认 (R)\u003c/td\u003e\n          \u003ctd\u003e数据字典/系统编目\u003c/td\u003e\n          \u003ctd\u003e账户操纵 (T1098)\u003c/td\u003e\n          \u003ctd\u003e安全审计 (4.5)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e统一审计+防篡改日志；Oracle Audit Vault；GB/T 20273 4.5；ISO 27001 A.8.15 → 高性能异步审计与只读日志内核\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e第三方运维人员\u003c/td\u003e\n          \u003ctd\u003e数据窃取\u003c/td\u003e\n          \u003ctd\u003e投递\u003c/td\u003e\n          \u003ctd\u003e信息泄露 (I)\u003c/td\u003e\n          \u003ctd\u003e业务核心表数据\u003c/td\u003e\n          \u003ctd\u003eSQL注入 (T1190)\u003c/td\u003e\n          \u003ctd\u003e自主访问控制 (4.2)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003eSQL防火墙+静态脱敏；Oracle AVDF；PCI DSS 3.2 → 内核级AST白名单SQL防火墙\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e恶意内部员工\u003c/td\u003e\n          \u003ctd\u003e规避审计\u003c/td\u003e\n          \u003ctd\u003e安装\u003c/td\u003e\n          \u003ctd\u003e篡改 (T)\u003c/td\u003e\n          \u003ctd\u003e审计日志记录\u003c/td\u003e\n          \u003ctd\u003e日志清除 (T1070)\u003c/td\u003e\n          \u003ctd\u003e用户数据完整性 (4.6)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e审计日志防篡改（只读表空间）；Oracle Blockchain Table；NIST AU-9 → 内核防篡改账本（Ledger Hash）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e云租户（恶意邻居）\u003c/td\u003e\n          \u003ctd\u003e勒索\u003c/td\u003e\n          \u003ctd\u003e命令与控制\u003c/td\u003e\n          \u003ctd\u003e权限提升 (E)\u003c/td\u003e\n          \u003ctd\u003e存储过程/函数/包\u003c/td\u003e\n          \u003ctd\u003e服务器软件组件劫持 (T1505)\u003c/td\u003e\n          \u003ctd\u003e强制访问控制 (4.4)\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e最小权限+代码签名；Oracle Database Vault；NIST AC-6 → 强三权分立与Realm特权隔离\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e恶意应用程序\u003c/td\u003e\n          \u003ctd\u003e报复\u003c/td\u003e\n          \u003ctd\u003e目标达成\u003c/td\u003e\n          \u003ctd\u003e拒绝服务 (D)\u003c/td\u003e\n          \u003ctd\u003e物理备份集/快照\u003c/td\u003e\n          \u003ctd\u003e数据破坏 (T1485)\u003c/td\u003e\n          \u003ctd\u003e存储数据保密性 (4.7.1)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e不可变备份+离线存储；Oracle RMAN；ISO 27001 A.8.13 → 备份加密与防删除兜底策略\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e恶意OS管理员\u003c/td\u003e\n          \u003ctd\u003e间谍活动\u003c/td\u003e\n          \u003ctd\u003e横向移动\u003c/td\u003e\n          \u003ctd\u003e信息泄露 (I)\u003c/td\u003e\n          \u003ctd\u003e数据库进程内存(SGA/PGA)\u003c/td\u003e\n          \u003ctd\u003e进程注入/内存刮削 (T1055/T1535)\u003c/td\u003e\n          \u003ctd\u003e用户数据保密性 (4.7.1)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e机密计算(TEE/SGX)；Oracle Database 23ai Secure Enclaves；NIST SC-3 → 内存密态运算引擎\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e物理入侵者\u003c/td\u003e\n          \u003ctd\u003e误操作/物理破坏\u003c/td\u003e\n          \u003ctd\u003e物理访问\u003c/td\u003e\n          \u003ctd\u003e信息泄露 (I)\u003c/td\u003e\n          \u003ctd\u003e配置文件(spfile/pg_hba)\u003c/td\u003e\n          \u003ctd\u003e系统信息发现 (T1082)\u003c/td\u003e\n          \u003ctd\u003e可信路径 (4.8)\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e文件系统权限+配置加密；Oracle Data Safe；GB/T 20273 4.8；ISO 27001 A.8.1 → 内核可信路径与完整性校验\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e离职/僵尸账号\u003c/td\u003e\n          \u003ctd\u003e身份伪造\u003c/td\u003e\n          \u003ctd\u003e利用\u003c/td\u003e\n          \u003ctd\u003e欺骗 (S)\u003c/td\u003e\n          \u003ctd\u003e数据库链接(DBLink)\u003c/td\u003e\n          \u003ctd\u003e有效账户滥用 (T1078)\u003c/td\u003e\n          \u003ctd\u003e身份鉴别 (4.1)\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e账户生命周期管理；Oracle CMU；ISO 27001 A.8.2 → 动态权限回收与实时拦截\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e失陷的业务程序\u003c/td\u003e\n          \u003ctd\u003e数据泄露\u003c/td\u003e\n          \u003ctd\u003e渗出\u003c/td\u003e\n          \u003ctd\u003e信息泄露 (I)\u003c/td\u003e\n          \u003ctd\u003e敏感数据列（身份证/手机号）\u003c/td\u003e\n          \u003ctd\u003e通过API攻击 (T1559)\u003c/td\u003e\n          \u003ctd\u003e存储数据保密性 (4.7.1)\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e动态数据脱敏+行级安全；Oracle VPD/OLS；ISO 27001 A.8.26 → 列级加密(CLS)与行级安全(RLS)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e内部运维人员\u003c/td\u003e\n          \u003ctd\u003e侦察\u003c/td\u003e\n          \u003ctd\u003e侦察\u003c/td\u003e\n          \u003ctd\u003e信息泄露 (I)\u003c/td\u003e\n          \u003ctd\u003e索引/分区/物化视图\u003c/td\u003e\n          \u003ctd\u003e网络嗅探 (T1040)\u003c/td\u003e\n          \u003ctd\u003e网络安全 (4.9)\u003c/td\u003e\n          \u003ctd\u003e低\u003c/td\u003e\n          \u003ctd\u003e加密通信+网络ACL；Oracle CMAN；GB/T 20273 4.9；ISO 27001 A.8.20 → 细粒度网络准入控制\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e供应链/第三方开发\u003c/td\u003e\n          \u003ctd\u003e权限提升\u003c/td\u003e\n          \u003ctd\u003e持久化\u003c/td\u003e\n          \u003ctd\u003e权限提升 (E)\u003c/td\u003e\n          \u003ctd\u003e触发器/UDF/扩展插件\u003c/td\u003e\n          \u003ctd\u003e创建账户 (T1136)\u003c/td\u003e\n          \u003ctd\u003e强制访问控制 (4.4)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e权限分析+代码审查；Oracle Database Vault；NIST AC-6 → 插件签名验证与默认拒绝策略\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e内部恶意DBA\u003c/td\u003e\n          \u003ctd\u003e掩盖罪行\u003c/td\u003e\n          \u003ctd\u003e目标达成\u003c/td\u003e\n          \u003ctd\u003e篡改 (T)\u003c/td\u003e\n          \u003ctd\u003eUndo/Redo/WAL日志\u003c/td\u003e\n          \u003ctd\u003e禁用安全工具 (T1562)\u003c/td\u003e\n          \u003ctd\u003e用户数据完整性 (4.6)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e防篡改日志+权限分析；Oracle Audit Vault；ISO 27001 A.8.15 → 写入只读日志流与篡改即报警\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e云租户（恶意）\u003c/td\u003e\n          \u003ctd\u003e权限提升\u003c/td\u003e\n          \u003ctd\u003e利用\u003c/td\u003e\n          \u003ctd\u003e欺骗 (S)\u003c/td\u003e\n          \u003ctd\u003e控制文件/密码文件\u003c/td\u003e\n          \u003ctd\u003e受信关系利用 (T1199)\u003c/td\u003e\n          \u003ctd\u003e身份鉴别 (4.1)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e网络隔离+强认证；Oracle MFA；GB/T 20273 4.1；NIST IA-5 → 基于TEE的密钥保护\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e外部攻击者\u003c/td\u003e\n          \u003ctd\u003e勒索\u003c/td\u003e\n          \u003ctd\u003e利用\u003c/td\u003e\n          \u003ctd\u003e拒绝服务 (D)\u003c/td\u003e\n          \u003ctd\u003e数据库监听器/服务端口\u003c/td\u003e\n          \u003ctd\u003e服务停止 (T1489)\u003c/td\u003e\n          \u003ctd\u003e网络安全 (4.9)\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e端口隐藏+SQL防火墙；Oracle CMAN；ISO 27001 A.8.22 → 内核级连接限流与抗DDoS\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e网络中间人\u003c/td\u003e\n          \u003ctd\u003e数据窃取\u003c/td\u003e\n          \u003ctd\u003e利用\u003c/td\u003e\n          \u003ctd\u003e信息泄露 (I)\u003c/td\u003e\n          \u003ctd\u003eSSL证书私钥/Keystore\u003c/td\u003e\n          \u003ctd\u003e数据加密(自身通信) (T1573)\u003c/td\u003e\n          \u003ctd\u003e传输数据保密性 (4.7.2)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003eHSM/KMS保护私钥；Oracle Key Vault；NIST SC-12 → 两级密钥管理架构\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e内部恶意DBA\u003c/td\u003e\n          \u003ctd\u003e规避审计\u003c/td\u003e\n          \u003ctd\u003e安装\u003c/td\u003e\n          \u003ctd\u003e篡改 (T)\u003c/td\u003e\n          \u003ctd\u003e数据库参数(init.ora)\u003c/td\u003e\n          \u003ctd\u003e域策略修改 (T1484)\u003c/td\u003e\n          \u003ctd\u003e安全审计 (4.5)\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e配置基线检查+变更审计；Oracle AVDF；CIS 基线 → 参数修改自动回滚与告警\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e恶意内部员工\u003c/td\u003e\n          \u003ctd\u003e数据窃取\u003c/td\u003e\n          \u003ctd\u003e收集\u003c/td\u003e\n          \u003ctd\u003e信息泄露 (I)\u003c/td\u003e\n          \u003ctd\u003e临时表空间/临时文件\u003c/td\u003e\n          \u003ctd\u003e数据从本地拉取 (T1213)\u003c/td\u003e\n          \u003ctd\u003e存储数据保密性 (4.7.1)\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e全密态执行+临时文件加密；Always Encrypted；ISO 27001 A.8.24 → 全密态查询处理引擎\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e物理入侵者\u003c/td\u003e\n          \u003ctd\u003e数据窃取\u003c/td\u003e\n          \u003ctd\u003e渗出\u003c/td\u003e\n          \u003ctd\u003e信息泄露 (I)\u003c/td\u003e\n          \u003ctd\u003e数据快照/克隆副本\u003c/td\u003e\n          \u003ctd\u003e数据泄露 (T1213)\u003c/td\u003e\n          \u003ctd\u003e存储数据保密性 (4.7.1)\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e快照加密+访问审计；Oracle RMAN；ISO 27001 A.8.12 → 存储级加密与快照防激活\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e外部渗透测试者\u003c/td\u003e\n          \u003ctd\u003e侦察\u003c/td\u003e\n          \u003ctd\u003e侦察\u003c/td\u003e\n          \u003ctd\u003e信息泄露 (I)\u003c/td\u003e\n          \u003ctd\u003e数据库服务端口/监听器\u003c/td\u003e\n          \u003ctd\u003e端口扫描 (T1046)\u003c/td\u003e\n          \u003ctd\u003e网络安全 (4.9)\u003c/td\u003e\n          \u003ctd\u003e低\u003c/td\u003e\n          \u003ctd\u003e防火墙策略+IPS；Oracle CMAN；GB/T 20273 4.9 → 端口敲门与隐身技术\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"chatgpt\"\u003echatgpt\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e攻击者画像\u003c/th\u003e\n          \u003cth\u003e攻击动机\u003c/th\u003e\n          \u003cth\u003e攻击阶段\u003c/th\u003e\n          \u003cth\u003e攻击类型\u003c/th\u003e\n          \u003cth\u003e攻击目标\u003c/th\u003e\n          \u003cth\u003e攻击技术\u003c/th\u003e\n          \u003cth\u003e影响安全域（GB/T 20273）\u003c/th\u003e\n          \u003cth\u003e风险等级\u003c/th\u003e\n          \u003cth\u003e安全功能与标准映射\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e外部攻击者\u003c/td\u003e\n          \u003ctd\u003e数据窃取\u003c/td\u003e\n          \u003ctd\u003e侦察\u003c/td\u003e\n          \u003ctd\u003e机密性攻击\u003c/td\u003e\n          \u003ctd\u003e用户凭据\u003c/td\u003e\n          \u003ctd\u003e暴力破解（T1110）\u003c/td\u003e\n          \u003ctd\u003e身份鉴别（4.1）\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e身份认证；GB/T 20273 4.1；ISO 27001 A.9；ISO 15408 FIA\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e内部恶意DBA\u003c/td\u003e\n          \u003ctd\u003e数据篡改\u003c/td\u003e\n          \u003ctd\u003e权限提升\u003c/td\u003e\n          \u003ctd\u003e完整性攻击\u003c/td\u003e\n          \u003ctd\u003e会话令牌\u003c/td\u003e\n          \u003ctd\u003e中间人攻击（T1557）\u003c/td\u003e\n          \u003ctd\u003e传输数据保密性（4.8.2）\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003eTLS双向认证；GB/T 20273 4.8.2；ISO 27001 A.13.2；NIST SC-8\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e内部开发人员\u003c/td\u003e\n          \u003ctd\u003e权限提升\u003c/td\u003e\n          \u003ctd\u003e执行\u003c/td\u003e\n          \u003ctd\u003e否认攻击\u003c/td\u003e\n          \u003ctd\u003e数据字典\u003c/td\u003e\n          \u003ctd\u003e账户操纵（T1098）\u003c/td\u003e\n          \u003ctd\u003e安全审计（4.6）\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e统一审计；GB/T 20273 4.6；ISO 27001 A.12.4；NIST AU-3\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e第三方运维人员\u003c/td\u003e\n          \u003ctd\u003e拒绝服务\u003c/td\u003e\n          \u003ctd\u003e利用\u003c/td\u003e\n          \u003ctd\u003e信息泄露攻击\u003c/td\u003e\n          \u003ctd\u003e用户表数据\u003c/td\u003e\n          \u003ctd\u003eSQL注入（T1190）\u003c/td\u003e\n          \u003ctd\u003e自主访问控制（4.2）\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e数据脱敏；GB/T 20273 4.2；PCI DSS 3.2\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e网络中间人\u003c/td\u003e\n          \u003ctd\u003e规避审计\u003c/td\u003e\n          \u003ctd\u003e安装\u003c/td\u003e\n          \u003ctd\u003e可用性攻击\u003c/td\u003e\n          \u003ctd\u003e审计日志\u003c/td\u003e\n          \u003ctd\u003e日志清除（T1070）\u003c/td\u003e\n          \u003ctd\u003e用户数据完整性（4.7）\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e审计日志防篡改；GB/T 20273 4.7；ISO 27001 A.12.4；NIST AU-9\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e云租户\u003c/td\u003e\n          \u003ctd\u003e勒索\u003c/td\u003e\n          \u003ctd\u003e命令与控制\u003c/td\u003e\n          \u003ctd\u003e权限提升攻击\u003c/td\u003e\n          \u003ctd\u003e存储过程/函数\u003c/td\u003e\n          \u003ctd\u003e服务器组件劫持（T1505）\u003c/td\u003e\n          \u003ctd\u003e强制访问控制（4.4）\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e最小权限原则；GB/T 20273 4.4；NIST AC-6\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e恶意应用程序\u003c/td\u003e\n          \u003ctd\u003e报复\u003c/td\u003e\n          \u003ctd\u003e目标达成\u003c/td\u003e\n          \u003ctd\u003e机密性攻击\u003c/td\u003e\n          \u003ctd\u003e备份集\u003c/td\u003e\n          \u003ctd\u003e数据加密防绕过（T1022）\u003c/td\u003e\n          \u003ctd\u003e存储数据保密性（4.8.1）\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e透明加密(TDE)；GB/T 20273 4.8.1；ISO 27001 A.10.1\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e恶意操作系统管理员\u003c/td\u003e\n          \u003ctd\u003e间谍活动\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e内存明文\u003c/td\u003e\n          \u003ctd\u003e进程注入（T1055）\u003c/td\u003e\n          \u003ctd\u003e标记（4.3）\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e机密计算(TEE)；NIST SC-3\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e物理入侵者\u003c/td\u003e\n          \u003ctd\u003e误操作\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e配置文件\u003c/td\u003e\n          \u003ctd\u003e系统信息发现（T1082）\u003c/td\u003e\n          \u003ctd\u003e可信路径（4.9）\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e网络ACL；GB/T 20273 4.9；ISO 27001 A.13.1\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e身份伪造\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据导出文件\u003c/td\u003e\n          \u003ctd\u003e数据破坏（T1485）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e低\u003c/td\u003e\n          \u003ctd\u003e备份加密\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e会话劫持\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据库链接\u003c/td\u003e\n          \u003ctd\u003e服务停止（T1489）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eSQL防火墙\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e索引/分区\u003c/td\u003e\n          \u003ctd\u003e通过API攻击（T1559）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e行级安全(RLS)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e物化视图\u003c/td\u003e\n          \u003ctd\u003e客户端连接劫持（T1184）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e列级加密\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e同义词\u003c/td\u003e\n          \u003ctd\u003e网络嗅探（T1040）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e三权分立\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e触发器等对象\u003c/td\u003e\n          \u003ctd\u003e创建账户（T1136）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e密钥管理(KMS/HSM)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e临时表空间\u003c/td\u003e\n          \u003ctd\u003e数据从本地拉取（T1213）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e全密态执行\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eUndo日志\u003c/td\u003e\n          \u003ctd\u003e禁用安全工具（T1562）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e权限分析工具\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e控制文件\u003c/td\u003e\n          \u003ctd\u003e受信关系利用（T1199）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e监听器/端口\u003c/td\u003e\n          \u003ctd\u003e反向工程（T1598）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eSSL证书私钥\u003c/td\u003e\n          \u003ctd\u003e数据加密（自身通讯）（T1573）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据库参数\u003c/td\u003e\n          \u003ctd\u003e域策略修改（T1484）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据库进程内存\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据快照\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据库服务端口\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch1 id=\"关系数据库安全威胁维度字典多维去重--结构化版\"\u003e关系数据库安全威胁维度字典（多维去重 · 结构化版）\u003c/h1\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e攻击者画像\u003c/th\u003e\n          \u003cth\u003e攻击动机\u003c/th\u003e\n          \u003cth\u003e攻击阶段\u003c/th\u003e\n          \u003cth\u003e攻击类型\u003c/th\u003e\n          \u003cth\u003e攻击目标\u003c/th\u003e\n          \u003cth\u003e攻击技术\u003c/th\u003e\n          \u003cth\u003e影响安全域（GB/T 20273 / ISO 15408）\u003c/th\u003e\n          \u003cth\u003e风险等级\u003c/th\u003e\n          \u003cth\u003e安全功能与标准映射\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e外部攻击者\u003c/td\u003e\n          \u003ctd\u003e数据窃取\u003c/td\u003e\n          \u003ctd\u003e侦察\u003c/td\u003e\n          \u003ctd\u003e机密性攻击\u003c/td\u003e\n          \u003ctd\u003e用户凭据\u003c/td\u003e\n          \u003ctd\u003e暴力破解（T1110）\u003c/td\u003e\n          \u003ctd\u003e身份鉴别（4.1）\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e身份认证 / MFA\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e内部恶意DBA\u003c/td\u003e\n          \u003ctd\u003e数据篡改\u003c/td\u003e\n          \u003ctd\u003e初始访问\u003c/td\u003e\n          \u003ctd\u003e完整性攻击\u003c/td\u003e\n          \u003ctd\u003e会话令牌\u003c/td\u003e\n          \u003ctd\u003eSQL注入（T1190）\u003c/td\u003e\n          \u003ctd\u003e自主访问控制（4.2）\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e访问控制（RBAC/RLS）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e内部开发人员\u003c/td\u003e\n          \u003ctd\u003e权限提升\u003c/td\u003e\n          \u003ctd\u003e执行\u003c/td\u003e\n          \u003ctd\u003e可用性攻击\u003c/td\u003e\n          \u003ctd\u003e数据字典\u003c/td\u003e\n          \u003ctd\u003e中间人攻击（T1557）\u003c/td\u003e\n          \u003ctd\u003e标记（4.3）\u003c/td\u003e\n          \u003ctd\u003e低\u003c/td\u003e\n          \u003ctd\u003e三权分立\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e第三方运维人员\u003c/td\u003e\n          \u003ctd\u003e拒绝服务\u003c/td\u003e\n          \u003ctd\u003e持久化\u003c/td\u003e\n          \u003ctd\u003e不可否认性攻击\u003c/td\u003e\n          \u003ctd\u003e用户表数据\u003c/td\u003e\n          \u003ctd\u003e账户操纵（T1098）\u003c/td\u003e\n          \u003ctd\u003e强制访问控制（4.4）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e最小权限\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e网络中间人\u003c/td\u003e\n          \u003ctd\u003e勒索\u003c/td\u003e\n          \u003ctd\u003e权限提升\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e索引/分区\u003c/td\u003e\n          \u003ctd\u003e日志清除（T1070）\u003c/td\u003e\n          \u003ctd\u003e安全审计（4.6）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e审计日志防篡改\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e云租户\u003c/td\u003e\n          \u003ctd\u003e报复\u003c/td\u003e\n          \u003ctd\u003e防御规避\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e物化视图\u003c/td\u003e\n          \u003ctd\u003e进程注入（T1055）\u003c/td\u003e\n          \u003ctd\u003e用户数据完整性（4.7）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e统一审计\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e恶意应用程序\u003c/td\u003e\n          \u003ctd\u003e间谍活动\u003c/td\u003e\n          \u003ctd\u003e凭据获取\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e同义词\u003c/td\u003e\n          \u003ctd\u003e服务器组件劫持（T1505）\u003c/td\u003e\n          \u003ctd\u003e存储数据保密性（4.8.1）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e透明加密（TDE）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e恶意操作系统管理员\u003c/td\u003e\n          \u003ctd\u003e规避审计\u003c/td\u003e\n          \u003ctd\u003e内部侦察\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e存储过程/函数\u003c/td\u003e\n          \u003ctd\u003e数据加密防绕过（T1022）\u003c/td\u003e\n          \u003ctd\u003e传输数据保密性（4.8.2）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eTLS / 双向认证\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e物理入侵者\u003c/td\u003e\n          \u003ctd\u003e误操作\u003c/td\u003e\n          \u003ctd\u003e横向移动\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e触发器等对象\u003c/td\u003e\n          \u003ctd\u003e系统信息发现（T1082）\u003c/td\u003e\n          \u003ctd\u003e可信路径（4.9）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e网络ACL\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e离职/僵尸账号\u003c/td\u003e\n          \u003ctd\u003e身份伪造\u003c/td\u003e\n          \u003ctd\u003e数据收集\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e临时表空间\u003c/td\u003e\n          \u003ctd\u003e通过API攻击（T1559）\u003c/td\u003e\n          \u003ctd\u003eFIA / FDP / FAU / FMT / FCS / FPT\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eSQL防火墙\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e自动化攻击工具\u003c/td\u003e\n          \u003ctd\u003e会话劫持\u003c/td\u003e\n          \u003ctd\u003e数据外传\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eUndo日志\u003c/td\u003e\n          \u003ctd\u003e客户端连接劫持（T1184）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e行级安全（RLS）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e影响/破坏\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e控制文件\u003c/td\u003e\n          \u003ctd\u003e创建账户（T1136）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e列级安全（CLS）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e监听器/端口\u003c/td\u003e\n          \u003ctd\u003e数据从本地拉取（T1213）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据脱敏\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eSSL证书私钥\u003c/td\u003e\n          \u003ctd\u003e禁用安全工具（T1562）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e密钥管理（KMS/HSM）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据库参数\u003c/td\u003e\n          \u003ctd\u003e受信关系利用（T1199）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e全密态执行\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据库进程内存\u003c/td\u003e\n          \u003ctd\u003e反向工程（T1598）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e机密计算（TEE）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据快照\u003c/td\u003e\n          \u003ctd\u003e数据加密（自身通讯）（T1573）\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据分类分级\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e数据库服务端口\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e配置基线检查\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"42-防御模型\"\u003e4.2 防御模型\u003c/h2\u003e\n\u003ch3 id=\"一访问安全\"\u003e一、访问安全\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e威胁ID\u003c/th\u003e\n          \u003cth\u003e威胁描述\u003c/th\u003e\n          \u003cth\u003eSTRIDE\u003c/th\u003e\n          \u003cth\u003e风险等级\u003c/th\u003e\n          \u003cth\u003e缓解的安全功能\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-ACS-01\u003c/td\u003e\n          \u003ctd\u003e弱口令爆破或默认账户攻击\u003c/td\u003e\n          \u003ctd\u003eS\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e身份认证（密码策略、账户锁定、MFA）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-ACS-02\u003c/td\u003e\n          \u003ctd\u003e重放攻击（抓取认证报文后重放）\u003c/td\u003e\n          \u003ctd\u003eS\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e身份认证（Challenge-Response、Kerberos时间戳）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-ACS-03\u003c/td\u003e\n          \u003ctd\u003e从不可信IP或恶意主机连接\u003c/td\u003e\n          \u003ctd\u003eS/D\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e网络ACL（IP白名单）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-ACS-04\u003c/td\u003e\n          \u003ctd\u003eSQL注入攻击绕过权限检查\u003c/td\u003e\n          \u003ctd\u003eE\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003eSQL防火墙（SQL白名单）、最小权限原则\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-ACS-05\u003c/td\u003e\n          \u003ctd\u003e内部人员滥用合法权限（如DBA偷看数据）\u003c/td\u003e\n          \u003ctd\u003eI/E\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e访问控制（三权分立、行级安全）、数据脱敏\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-ACS-06\u003c/td\u003e\n          \u003ctd\u003e权限过度授予导致横向越权\u003c/td\u003e\n          \u003ctd\u003eE\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e访问控制（RBAC、最小权限）、权限分析工具\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-ACS-07\u003c/td\u003e\n          \u003ctd\u003e用户否认执行了某项敏感操作\u003c/td\u003e\n          \u003ctd\u003eR\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e安全审计（统一审计、细粒度审计）\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"二传输安全\"\u003e二、传输安全\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e威胁ID\u003c/th\u003e\n          \u003cth\u003e威胁描述\u003c/th\u003e\n          \u003cth\u003eSTRIDE\u003c/th\u003e\n          \u003cth\u003e风险等级\u003c/th\u003e\n          \u003cth\u003e缓解的安全功能\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-TRP-01\u003c/td\u003e\n          \u003ctd\u003e网络嗅探窃听数据库通信\u003c/td\u003e\n          \u003ctd\u003eI\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e安全传输（TLS 1.3、国密TLCP）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-TRP-02\u003c/td\u003e\n          \u003ctd\u003e中间人攻击（MITM）篡改或劫持会话\u003c/td\u003e\n          \u003ctd\u003eT/S\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e安全传输（证书双向验证、防降级攻击）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-TRP-03\u003c/td\u003e\n          \u003ctd\u003e会话劫持后模拟合法用户\u003c/td\u003e\n          \u003ctd\u003eS\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e安全传输（会话加密、绑定认证）\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"三计算安全\"\u003e三、计算安全\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e威胁ID\u003c/th\u003e\n          \u003cth\u003e威胁描述\u003c/th\u003e\n          \u003cth\u003eSTRIDE\u003c/th\u003e\n          \u003cth\u003e风险等级\u003c/th\u003e\n          \u003cth\u003e缓解的安全功能\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-CPT-01\u003c/td\u003e\n          \u003ctd\u003e数据库管理员或恶意进程在内存中读取敏感数据\u003c/td\u003e\n          \u003ctd\u003eI\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e全密态加密、机密计算（TEE）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-CPT-02\u003c/td\u003e\n          \u003ctd\u003e通过侧信道攻击（如Cache时间）推断数据\u003c/td\u003e\n          \u003ctd\u003eI\u003c/td\u003e\n          \u003ctd\u003e中-高\u003c/td\u003e\n          \u003ctd\u003e机密计算（恒定时间执行）、全密态加密\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-CPT-03\u003c/td\u003e\n          \u003ctd\u003eSQL执行计划中泄露敏感值（如错误消息、执行计划）\u003c/td\u003e\n          \u003ctd\u003eI\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e数据脱敏（返回结果遮盖）、错误消息泛化\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-CPT-04\u003c/td\u003e\n          \u003ctd\u003e攻击者调用加密函数进行暴力破解或穷举\u003c/td\u003e\n          \u003ctd\u003eI/D\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e加密函数（密钥强度限制、防暴力调用策略）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-CPT-05\u003c/td\u003e\n          \u003ctd\u003e云环境下虚拟机管理器直接读取数据库进程内存\u003c/td\u003e\n          \u003ctd\u003eI\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e机密计算（TEE内执行、加密内存）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-CPT-06\u003c/td\u003e\n          \u003ctd\u003e已授权用户通过脱敏绕过机制看到原始数据\u003c/td\u003e\n          \u003ctd\u003eI\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e数据脱敏（权限校验、防绕过）\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"四存储安全\"\u003e四、存储安全\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e威胁ID\u003c/th\u003e\n          \u003cth\u003e威胁描述\u003c/th\u003e\n          \u003cth\u003eSTRIDE\u003c/th\u003e\n          \u003cth\u003e风险等级\u003c/th\u003e\n          \u003cth\u003e缓解的安全功能\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-STR-01\u003c/td\u003e\n          \u003ctd\u003e攻击者窃取磁盘或备份介质，绕过数据库直接读取数据文件\u003c/td\u003e\n          \u003ctd\u003eI\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e透明加密（TDE）、备份加密\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-STR-02\u003c/td\u003e\n          \u003ctd\u003e攻击者或恶意OS篡改数据文件中的数据块\u003c/td\u003e\n          \u003ctd\u003eT\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e数据防篡改（哈希链、账本表）、块级校验\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-STR-03\u003c/td\u003e\n          \u003ctd\u003e未授权用户通过文件系统直接拷贝数据文件\u003c/td\u003e\n          \u003ctd\u003eI\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e透明加密（TDE）+ 文件权限保护\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-STR-04\u003c/td\u003e\n          \u003ctd\u003e备份介质丢失导致数据泄露\u003c/td\u003e\n          \u003ctd\u003eI\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e透明加密（备份加密）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-STR-05\u003c/td\u003e\n          \u003ctd\u003e密钥管理不当（硬编码、弱密钥、不轮换）导致加密失效\u003c/td\u003e\n          \u003ctd\u003eI/T\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e密钥管理（KMS、HSM、自动轮换）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-STR-06\u003c/td\u003e\n          \u003ctd\u003e敏感数据未被识别（未分类分级）导致保护缺失\u003c/td\u003e\n          \u003ctd\u003eI\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e数据发现（自动扫描、分类分级）\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"五合法合规\"\u003e五、合法合规\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e威胁ID\u003c/th\u003e\n          \u003cth\u003e威胁描述\u003c/th\u003e\n          \u003cth\u003eSTRIDE\u003c/th\u003e\n          \u003cth\u003e风险等级\u003c/th\u003e\n          \u003cth\u003e缓解的安全功能\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-AUD-01\u003c/td\u003e\n          \u003ctd\u003e攻击者或恶意管理员删除/篡改审计日志以掩盖痕迹\u003c/td\u003e\n          \u003ctd\u003eT/R\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e审计日志防篡改（只写一次、WORM存储、加密）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-AUD-02\u003c/td\u003e\n          \u003ctd\u003e审计日志被未授权读取（泄露用户行为）\u003c/td\u003e\n          \u003ctd\u003eI\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e审计日志加密存储、访问控制\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-AUD-03\u003c/td\u003e\n          \u003ctd\u003e审计数据量过大导致性能下降或日志溢出\u003c/td\u003e\n          \u003ctd\u003eD\u003c/td\u003e\n          \u003ctd\u003e中\u003c/td\u003e\n          \u003ctd\u003e统一审计（条件审计、采样审计）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eT-AUD-04\u003c/td\u003e\n          \u003ctd\u003e合规性检查时无法证明对敏感数据的控制措施\u003c/td\u003e\n          \u003ctd\u003eR\u003c/td\u003e\n          \u003ctd\u003e高\u003c/td\u003e\n          \u003ctd\u003e合规对标（等保、ISO、GDPR）、审计记录完整性\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"43-安全功能\"\u003e4.3 安全功能\u003c/h2\u003e\n\u003ch3 id=\"一访问安全-1\"\u003e一、访问安全\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-fallback\" data-lang=\"fallback\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e身份认证、访问控制（自主访问控制、强制访问控制、角色访问控制（三权分立）、行级访问控制）\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"二传输安全-1\"\u003e二、传输安全\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-fallback\" data-lang=\"fallback\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eSSL\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"三计算安全-1\"\u003e三、计算安全\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-fallback\" data-lang=\"fallback\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e加密函数、全密态、机密计算、动态脱敏\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"四存储安全-1\"\u003e四、存储安全\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-fallback\" data-lang=\"fallback\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e透明加密、防篡改\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"五合法合规-1\"\u003e五、合法合规\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-fallback\" data-lang=\"fallback\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e安全审计、密钥管理\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e一、接入安全\u003cbr\u003e\n1. 网络防火墙\u003cbr\u003e\n- 不可信IP登录\u003cbr\u003e\n2. 身份认证\u003cbr\u003e\n暴力破解\u003cbr\u003e\n凭证重放\u003cbr\u003e\n默认账户攻击\u003cbr\u003e\n过期账号攻击\u003cbr\u003e\n弱口令攻击\u003cbr\u003e\n内存凭证残留\u003cbr\u003e\n认证耗尽\u003cbr\u003e\n密码泄露\u003cbr\u003e\n二、传输安全\u003cbr\u003e\n3. 安全传输\u003cbr\u003e\n数据泄露\u003cbr\u003e\n流量伪造\u003cbr\u003e\n流量重放\u003cbr\u003e\n会话密钥泄露\u003cbr\u003e\n证书伪造\u003cbr\u003e\n身份伪造\u003cbr\u003e\n三、访问安全\u003cbr\u003e\n4. 访问控制\u003cbr\u003e\n未授权访问\u003cbr\u003e\n越权访问\u003cbr\u003e\n权限提升\u003cbr\u003e\n权限滥用\u003cbr\u003e\n权限提升\u003c/p\u003e","title":"安全架构"},{"content":"CREATE SCHEMA pgcrypto_2_text; SET search_path TO pgcrypto_2_text; /* ------------------------------------------------------------------------------------------------ * part 0: create some utils functions * ------------------------------------------------------------------------------------------------ */ CREATE FUNCTION strtoraw(string VARCHAR2) RETURN RAW IS BEGIN RETURN utl_raw.cast_to_raw(string); END; / CREATE FUNCTION rawtostr(rawdata RAW) RETURN VARCHAR2 IS BEGIN RETURN utl_raw.cast_to_varchar2(rawdata); END; / -- get data type name CREATE OR REPLACE FUNCTION oidgettype(typeoid OID) RETURNS TEXT AS $$ BEGIN RETURN (SELECT typname FROM pg_type WHERE oid = typeoid); END; $$ LANGUAGE plpgsql; CREATE OR REPLACE FUNCTION oidgettype(typeoids OIDVECTOR) RETURNS TEXT[] AS $$ DECLARE result TEXT[] := \u0026#39;{}\u0026#39;; typoid OID; typename TEXT; BEGIN FOREACH typoid IN ARRAY typeoids LOOP SELECT typname INTO typename FROM pg_type WHERE oid = typoid; result := array_append(result, COALESCE(typename, \u0026#39;Unknown OID\u0026#39;)); END LOOP; RETURN result; END; $$ LANGUAGE plpgsql; -- find all functions from dbms_obfuscation_toolkit CREATE VIEW allfuncs AS SELECT proname name,pronargs args,oidgettype(prorettype) output,oidgettype(proargtypes) input FROM pg_proc WHERE pronamespace = (SELECT oid FROM pg_namespace WHERE nspname = \u0026#39;dbms_obfuscation_toolkit\u0026#39;) ORDER BY 1,3,2; /* ------------------------------------------------------------------------------------------------ * part 1: install pgcrypt with different versions * ------------------------------------------------------------------------------------------------ */ -- available version SELECT * FROM pg_available_extension_versions WHERE name = \u0026#39;pgcrypto\u0026#39;; -- 2.0 (default version) CREATE EXTENSION pgcrypto; SELECT * FROM pg_extension WHERE extname = \u0026#39;pgcrypto\u0026#39;; SELECT * FROM allfuncs; DROP EXTENSION pgcrypto; -- 1.2 (old version) CREATE EXTENSION pgcrypto WITH VERSION \u0026#39;1.2\u0026#39;; SELECT * FROM pg_extension WHERE extname = \u0026#39;pgcrypto\u0026#39;; SELECT * FROM allfuncs; DROP EXTENSION pgcrypto; -- 2.0 --\u0026gt; 1.2 CREATE EXTENSION pgcrypto; SELECT * FROM pg_extension WHERE extname = \u0026#39;pgcrypto\u0026#39;; ALTER EXTENSION pgcrypto UPDATE TO \u0026#39;1.2\u0026#39;; SELECT * FROM pg_extension WHERE extname = \u0026#39;pgcrypto\u0026#39;; SELECT * FROM allfuncs; DROP EXTENSION pgcrypto; -- 1.2 --\u0026gt; 2.0 CREATE EXTENSION pgcrypto WITH VERSION \u0026#39;1.2\u0026#39;; SELECT * FROM pg_extension WHERE extname = \u0026#39;pgcrypto\u0026#39;; ALTER EXTENSION pgcrypto UPDATE TO \u0026#39;2.0\u0026#39;; SELECT * FROM pg_extension WHERE extname = \u0026#39;pgcrypto\u0026#39;; SELECT * FROM allfuncs; DROP EXTENSION pgcrypto; /* ------------------------------------------------------------------------------------------------ * part 2: core functions * ------------------------------------------------------------------------------------------------ */ CREATE EXTENSION pgcrypto; -- 1 desencrypt SELECT dbms_obfuscation_toolkit.desencrypt(strtoraw(\u0026#39;11111111\u0026#39;), strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; SELECT dbms_obfuscation_toolkit.desencrypt(strtoraw(\u0026#39;1111111111111111\u0026#39;), strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 2 desdecrypt SELECT rawtostr(dbms_obfuscation_toolkit.desdecrypt(hextoraw(\u0026#39;655EA628CF62585F\u0026#39;), strtoraw(\u0026#39;11111111\u0026#39;))) FROM dual; SELECT rawtostr(dbms_obfuscation_toolkit.desdecrypt(hextoraw(\u0026#39;655EA628CF62585F20D3B8A6E657876B\u0026#39;), strtoraw(\u0026#39;11111111\u0026#39;))) FROM dual; -- 3 des3encrypt SELECT dbms_obfuscation_toolkit.des3encrypt(strtoraw(\u0026#39;11111111\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;), 0, strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; SELECT dbms_obfuscation_toolkit.des3encrypt(strtoraw(\u0026#39;1111111111111111\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;), 0, strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 4 des3decrypt SELECT rawtostr(dbms_obfuscation_toolkit.des3decrypt(hextoraw(\u0026#39;0D28E17571051319\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;), 0, strtoraw(\u0026#39;11111111\u0026#39;))) FROM dual; SELECT rawtostr(dbms_obfuscation_toolkit.des3decrypt(hextoraw(\u0026#39;0D28E17571051319ACCE2D19D9AED5C8\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;), 0, strtoraw(\u0026#39;11111111\u0026#39;))) FROM dual; -- 5 des3encrypt -- without iv SELECT dbms_obfuscation_toolkit.des3encrypt(strtoraw(\u0026#39;11111111\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;)) FROM dual; SELECT dbms_obfuscation_toolkit.des3encrypt(strtoraw(\u0026#39;1111111111111111\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;)) FROM dual; -- 6 des3decrypt -- without iv SELECT rawtostr(dbms_obfuscation_toolkit.des3decrypt(hextoraw(\u0026#39;7934131269E334A2\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;))) FROM dual; SELECT rawtostr(dbms_obfuscation_toolkit.des3decrypt(hextoraw(\u0026#39;7934131269E334A2BCC64878CC5A075A\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;))) FROM dual; /* ------------------------------------------------------------------------------------------------ * part 3: different args * ------------------------------------------------------------------------------------------------ */ -- 1 des CREATE TABLE tplain (id INT, plain TEXT, key TEXT); INSERT INTO tplain VALUES (1, \u0026#39;\u0026#39;, \u0026#39;\u0026#39;), (2, NULL, NULL), -- different plain (11, NULL, \u0026#39;88888888\u0026#39;), (12, \u0026#39;\u0026#39;, \u0026#39;88888888\u0026#39;), (13, \u0026#39;1\u0026#39;, \u0026#39;88888888\u0026#39;), (14, \u0026#39;7777777\u0026#39;, \u0026#39;88888888\u0026#39;), (15, \u0026#39;88888888\u0026#39;, \u0026#39;88888888\u0026#39;), (16, \u0026#39;999999999\u0026#39;, \u0026#39;88888888\u0026#39;), (17, \u0026#39;17171717171717171\u0026#39;, \u0026#39;88888888\u0026#39;), (18, \u0026#39;242424242424242422424242\u0026#39;,\u0026#39;88888888\u0026#39;), -- different key (31, \u0026#39;88888888\u0026#39;, NULL), (32, \u0026#39;88888888\u0026#39;, \u0026#39;\u0026#39;), (33, \u0026#39;88888888\u0026#39;, \u0026#39;1\u0026#39;), (34, \u0026#39;88888888\u0026#39;, \u0026#39;7777777\u0026#39;), (37, \u0026#39;88888888\u0026#39;, \u0026#39;88888888\u0026#39;), (38, \u0026#39;88888888\u0026#39;, \u0026#39;999999999\u0026#39;), (37, \u0026#39;88888888\u0026#39;, \u0026#39;17171717171717171\u0026#39;), (38, \u0026#39;88888888\u0026#39;, \u0026#39;242424242424242422424242\u0026#39;); CREATE TABLE tcipher (id INT, key TEXT, cipher RAW); INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 1; INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 2; INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 11; INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 12; INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 13; INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 14; INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 15; INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 16; INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 17; INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 18; INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 31; INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 32; INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 33; INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 34; INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 35; INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 36; INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 37; INSERT INTO tcipher SELECT id, key, dbms_obfuscation_toolkit.desencrypt(strtoraw(plain), strtoraw(key)) FROM tplain WHERE id = 38; SELECT id,cipher,length(cipher) FROM tcipher ORDER BY id; SELECT id,rawtostr(dbms_obfuscation_toolkit.desdecrypt(cipher, strtoraw(key))) FROM tcipher ORDER BY id; DROP TABLE tplain,tcipher; -- 2 3des CREATE TABLE tplain (id INT, plain TEXT, keymod INT, key TEXT, iv TEXT); INSERT INTO tplain VALUES (1, \u0026#39;\u0026#39;, 0, \u0026#39;\u0026#39;, \u0026#39;\u0026#39;), (2, NULL, 0, NULL, NULL), -- different plain (11, NULL, 0, \u0026#39;1616161616161616\u0026#39;, \u0026#39;88888888\u0026#39;), (12, \u0026#39;\u0026#39;, 0, \u0026#39;1616161616161616\u0026#39;, \u0026#39;88888888\u0026#39;), (13, \u0026#39;1\u0026#39;, 0, \u0026#39;1616161616161616\u0026#39;, \u0026#39;88888888\u0026#39;), (14, \u0026#39;7777777\u0026#39;, 0, \u0026#39;1616161616161616\u0026#39;, \u0026#39;88888888\u0026#39;), (15, \u0026#39;88888888\u0026#39;, 0, \u0026#39;1616161616161616\u0026#39;, \u0026#39;88888888\u0026#39;), (16, \u0026#39;999999999\u0026#39;, 0, \u0026#39;1616161616161616\u0026#39;, \u0026#39;88888888\u0026#39;), (17, \u0026#39;17171717171717171\u0026#39;, 0, \u0026#39;1616161616161616\u0026#39;, \u0026#39;88888888\u0026#39;), (18, \u0026#39;242424242424242422424242\u0026#39;,0, \u0026#39;1616161616161616\u0026#39;, \u0026#39;88888888\u0026#39;), -- different keymod (31, \u0026#39;1616161616161616\u0026#39;, NULL, \u0026#39;1616161616161616\u0026#39;, \u0026#39;88888888\u0026#39;), (32, \u0026#39;1616161616161616\u0026#39;, -1, \u0026#39;1616161616161616\u0026#39;, \u0026#39;88888888\u0026#39;), (33, \u0026#39;1616161616161616\u0026#39;, -1.1, \u0026#39;1616161616161616\u0026#39;, \u0026#39;88888888\u0026#39;), (34, \u0026#39;1616161616161616\u0026#39;, 1.1, \u0026#39;1616161616161616\u0026#39;, \u0026#39;88888888\u0026#39;), (35, \u0026#39;1616161616161616\u0026#39;, 2, \u0026#39;1616161616161616\u0026#39;, \u0026#39;88888888\u0026#39;), (36, \u0026#39;1616161616161616\u0026#39;, \u0026#39;0\u0026#39;, \u0026#39;1616161616161616\u0026#39;, \u0026#39;88888888\u0026#39;), (37, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;242424242424242422424242\u0026#39;, \u0026#39;88888888\u0026#39;), -- different key (51, \u0026#39;1616161616161616\u0026#39;, 0, NULL, \u0026#39;88888888\u0026#39;), (52, \u0026#39;1616161616161616\u0026#39;, 0, \u0026#39;\u0026#39;, \u0026#39;88888888\u0026#39;), (53, \u0026#39;1616161616161616\u0026#39;, 0, \u0026#39;1\u0026#39;, \u0026#39;88888888\u0026#39;), (54, \u0026#39;1616161616161616\u0026#39;, 0, \u0026#39;7777777\u0026#39;, \u0026#39;88888888\u0026#39;), (55, \u0026#39;1616161616161616\u0026#39;, 0, \u0026#39;88888888\u0026#39;, \u0026#39;88888888\u0026#39;), (56, \u0026#39;1616161616161616\u0026#39;, 0, \u0026#39;999999999\u0026#39;, \u0026#39;88888888\u0026#39;), (57, \u0026#39;1616161616161616\u0026#39;, 0, \u0026#39;17171717171717171\u0026#39;, \u0026#39;88888888\u0026#39;), (58, \u0026#39;1616161616161616\u0026#39;, 0, \u0026#39;242424242424242422424242\u0026#39;, \u0026#39;88888888\u0026#39;), (59, \u0026#39;1616161616161616\u0026#39;, 0, \u0026#39;272727272727272727272727272\u0026#39;, \u0026#39;88888888\u0026#39;), (61, \u0026#39;1616161616161616\u0026#39;, 1, NULL, \u0026#39;88888888\u0026#39;), (62, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;\u0026#39;, \u0026#39;88888888\u0026#39;), (63, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;1\u0026#39;, \u0026#39;88888888\u0026#39;), (64, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;7777777\u0026#39;, \u0026#39;88888888\u0026#39;), (65, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;88888888\u0026#39;, \u0026#39;88888888\u0026#39;), (66, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;999999999\u0026#39;, \u0026#39;88888888\u0026#39;), (67, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;17171717171717171\u0026#39;, \u0026#39;88888888\u0026#39;), (68, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;242424242424242422424242\u0026#39;, \u0026#39;88888888\u0026#39;), (69, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;272727272727272727272727272\u0026#39;, \u0026#39;88888888\u0026#39;), -- different iv (81, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;242424242424242422424242\u0026#39;, NULL), (82, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;242424242424242422424242\u0026#39;, \u0026#39;\u0026#39;), (83, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;242424242424242422424242\u0026#39;, \u0026#39;1\u0026#39;), (84, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;242424242424242422424242\u0026#39;, \u0026#39;7777777\u0026#39;), (85, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;242424242424242422424242\u0026#39;, \u0026#39;88888888\u0026#39;), (86, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;242424242424242422424242\u0026#39;, \u0026#39;999999999\u0026#39;), (87, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;242424242424242422424242\u0026#39;, \u0026#39;17171717171717171\u0026#39;), (88, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;242424242424242422424242\u0026#39;, \u0026#39;242424242424242422424242\u0026#39;), (89, \u0026#39;1616161616161616\u0026#39;, 1, \u0026#39;242424242424242422424242\u0026#39;, \u0026#39;272727272727272727272727272\u0026#39;); CREATE TABLE tcipher (id INT, CIPHER RAW, keymod INT, key TEXT, iv TEXT); INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 1; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 2; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 11; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 12; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 13; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 14; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 15; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 16; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 17; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 18; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 31; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 32; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 33; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 34; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 35; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 36; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 37; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 51; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 52; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 53; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 54; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 55; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 56; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 57; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 58; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 59; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 61; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 62; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 63; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 64; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 65; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 66; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 67; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 68; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 69; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 81; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 82; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 83; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 84; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 85; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 86; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 87; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 88; INSERT INTO tcipher SELECT id, dbms_obfuscation_toolkit.des3encrypt(strtoraw(plain), strtoraw(key), keymod, strtoraw(iv)), keymod, key, iv FROM tplain WHERE id = 89; SELECT * FROM tcipher; SELECT id, rawtostr(dbms_obfuscation_toolkit.des3decrypt(cipher, strtoraw(key), keymod, strtoraw(iv))) FROM tcipher ORDER BY id; DROP TABLE tplain, tcipher; /* ------------------------------------------------------------------------------------------------ * part 4: other functions * ------------------------------------------------------------------------------------------------ */ SELECT length(dbms_obfuscation_toolkit.desgetkey(strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;))) FROM dual; SELECT length(dbms_obfuscation_toolkit.des3getkey(0, strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;))) FROM dual; SELECT length(dbms_obfuscation_toolkit.des3getkey(1, strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;))) FROM dual; SELECT dbms_obfuscation_toolkit.md5(strtoraw(\u0026#39;1111111111111111\u0026#39;)) FROM dual; CREATE TABLE deskey(id INT, key RAW); CREATE TABLE des3key0 (id INT, key RAW); CREATE TABLE des3key1 (id INT, key RAW); INSERT INTO deskey SELECT generate_series(1, 1000), dbms_obfuscation_toolkit.desgetkey(strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;)); INSERT INTO des3key0 SELECT generate_series(1, 1000), dbms_obfuscation_toolkit.des3getkey(0, strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;)); INSERT INTO des3key1 SELECT generate_series(1, 1000), dbms_obfuscation_toolkit.des3getkey(1, strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;)); CREATE TABLE allcnt (cnt INT); INSERT INTO allcnt SELECT count(*) FROM deskey GROUP BY key; INSERT INTO allcnt SELECT count(*) FROM des3key0 GROUP BY key; INSERT INTO allcnt SELECT count(*) FROM des3key1 GROUP BY key; SELECT cnt,count(*) FROM allcnt GROUP BY cnt; -- test (need to spend too much time) -- CREATE TABLE moretime(id INT, key RAW); -- INSERT INTO moretime SELECT generate_series(1, 100000), -- dbms_obfuscation_toolkit.desgetkey(strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;)); -- -- 预期 key列重复的字符不多 -- SELECT * FROM moretime ORDER BY key ASC LIMIT 10; -- SELECT * FROM moretime ORDER BY key DESC LIMIT 10; -- DROP TABLE moretime; DROP TABLE deskey, des3key0, des3key1, allcnt; DROP EXTENSION pgcrypto; RESET search_path; DROP SCHEMA pgcrypto_2_text CASCADE; ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/1-testcase-oracle-crypto-func/","summary":"\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSCHEMA\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgcrypto_2_text\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSET\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esearch_path\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgcrypto_2_text\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* ------------------------------------------------------------------------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * part 0: create some utils functions\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * ------------------------------------------------------------------------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFUNCTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estring\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eVARCHAR2\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eRETURN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eRAW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIS\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eRETURN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eutl_raw\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecast_to_raw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eEND\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFUNCTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erawtostr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erawdata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eRAW\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eRETURN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eVARCHAR2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIS\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eRETURN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eutl_raw\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecast_to_varchar2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erawdata\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eEND\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- get data type name\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eREPLACE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFUNCTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eoidgettype\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etypeoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eOID\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eRETURNS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$$\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eRETURN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etypname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_type\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etypeoid\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eEND\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e$$\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLANGUAGE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eplpgsql\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eREPLACE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFUNCTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eoidgettype\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etypeoids\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eOIDVECTOR\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eRETURNS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e[]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$$\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDECLARE\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eresult\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e[]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;{}\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003etypoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eOID\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003etypename\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eFOREACH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etypoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eARRAY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etypeoids\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eLOOP\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etypname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etypename\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_type\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etypoid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"k\"\u003eresult\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003earray_append\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003eresult\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eCOALESCE\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etypename\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;Unknown OID\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eEND\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eLOOP\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eRETURN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eresult\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eEND\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e$$\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLANGUAGE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eplpgsql\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- find all functions from dbms_obfuscation_toolkit\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVIEW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eallfuncs\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eproname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003epronargs\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eargs\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eoidgettype\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eprorettype\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eoutput\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eoidgettype\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eproargtypes\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003einput\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_proc\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epronamespace\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_namespace\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003enspname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;dbms_obfuscation_toolkit\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* ------------------------------------------------------------------------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * part 1: install pgcrypt with different versions\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * ------------------------------------------------------------------------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- available version\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_available_extension_versions\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pgcrypto\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2.0 (default version)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eEXTENSION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgcrypto\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_extension\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eextname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pgcrypto\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eallfuncs\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eEXTENSION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgcrypto\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 1.2 (old version)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eEXTENSION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgcrypto\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVERSION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1.2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_extension\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eextname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pgcrypto\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eallfuncs\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eEXTENSION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgcrypto\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2.0 --\u0026gt; 1.2\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eEXTENSION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgcrypto\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_extension\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eextname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pgcrypto\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eEXTENSION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgcrypto\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUPDATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1.2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_extension\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eextname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pgcrypto\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eallfuncs\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eEXTENSION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgcrypto\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 1.2 --\u0026gt; 2.0\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eEXTENSION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgcrypto\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVERSION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1.2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_extension\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eextname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pgcrypto\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eEXTENSION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgcrypto\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUPDATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;2.0\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_extension\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eextname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pgcrypto\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eallfuncs\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eEXTENSION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgcrypto\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* ------------------------------------------------------------------------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * part 2: core functions\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * ------------------------------------------------------------------------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eEXTENSION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgcrypto\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 1 desencrypt\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;11111111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;11111111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edual\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1111111111111111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;11111111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edual\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2 desdecrypt\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erawtostr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesdecrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehextoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;655EA628CF62585F\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;11111111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edual\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erawtostr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesdecrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehextoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;655EA628CF62585F20D3B8A6E657876B\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;11111111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edual\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 des3encrypt\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;11111111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1111111122222222\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;11111111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edual\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1111111111111111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1111111122222222\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;11111111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edual\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 4 des3decrypt\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erawtostr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3decrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehextoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;0D28E17571051319\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1111111122222222\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;11111111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edual\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erawtostr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3decrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehextoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;0D28E17571051319ACCE2D19D9AED5C8\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1111111122222222\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;11111111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edual\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 5 des3encrypt -- without iv\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;11111111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1111111122222222\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edual\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1111111111111111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1111111122222222\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edual\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 6 des3decrypt -- without iv\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erawtostr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3decrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehextoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;7934131269E334A2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1111111122222222\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edual\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erawtostr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3decrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehextoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;7934131269E334A2BCC64878CC5A075A\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1111111122222222\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edual\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* ------------------------------------------------------------------------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * part 3: different args\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * ------------------------------------------------------------------------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 1 des\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- different plain\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e11\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e12\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                        \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e13\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                       \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e14\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;7777777\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                 \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e15\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e16\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;999999999\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e               \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e17\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;17171717171717171\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e       \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e18\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;242424242424242422424242\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- different key\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e31\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e32\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e33\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e34\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;7777777\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e37\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e38\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;999999999\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e37\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;17171717171717171\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e38\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;242424242424242422424242\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eRAW\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e11\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e12\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e13\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e14\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e15\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e16\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e17\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e18\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e31\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e32\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e33\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e34\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e35\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e36\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e37\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e38\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ecipher\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003elength\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecipher\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003erawtostr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesdecrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecipher\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e)))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2 3des\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- different plain\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e11\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                      \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e12\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                        \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e13\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                       \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e14\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;7777777\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                 \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e15\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e16\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;999999999\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e               \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e17\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;17171717171717171\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e       \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e18\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;242424242424242422424242\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- different keymod\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e31\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e   \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e32\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e33\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e   \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e34\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e35\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e36\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;0\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e37\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;242424242424242422424242\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- different key\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e51\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"k\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                           \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e52\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                             \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e53\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                            \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e54\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;7777777\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e55\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                     \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e56\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;999999999\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                    \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e57\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;17171717171717171\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e            \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e58\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;242424242424242422424242\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e59\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;272727272727272727272727272\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e61\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"k\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                           \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e62\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                             \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e63\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                            \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e64\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;7777777\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e65\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                     \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e66\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;999999999\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e                    \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e67\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;17171717171717171\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e            \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e68\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;242424242424242422424242\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e69\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;272727272727272727272727272\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- different iv\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e81\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;242424242424242422424242\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"k\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e82\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;242424242424242422424242\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e83\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;242424242424242422424242\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e84\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;242424242424242422424242\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;7777777\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e85\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;242424242424242422424242\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;88888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e86\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;242424242424242422424242\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;999999999\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e87\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;242424242424242422424242\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;17171717171717171\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e88\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;242424242424242422424242\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;242424242424242422424242\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e89\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1616161616161616\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;242424242424242422424242\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;272727272727272727272727272\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eCIPHER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eRAW\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e11\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e12\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e13\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e14\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e15\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e16\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e17\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e18\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e31\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e32\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e33\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e34\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e35\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e36\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e37\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e51\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e52\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e53\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e54\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e55\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e56\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e57\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e58\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e59\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e61\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e62\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e63\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e64\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e65\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e66\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e67\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e68\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e69\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e81\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e82\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e83\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e84\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e85\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e86\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e87\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e88\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3encrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e89\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erawtostr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3decrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecipher\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ekeymod\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eiv\u003c/span\u003e\u003cspan class=\"p\"\u003e)))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etplain\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etcipher\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* ------------------------------------------------------------------------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * part 4: other functions\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * ------------------------------------------------------------------------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003elength\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesgetkey\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edual\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003elength\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3getkey\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edual\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003elength\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3getkey\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edual\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003emd5\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1111111111111111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edual\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edeskey\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eRAW\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edes3key0\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eRAW\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edes3key1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eRAW\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edeskey\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egenerate_series\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1000\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesgetkey\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edes3key0\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egenerate_series\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1000\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3getkey\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edes3key1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egenerate_series\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1000\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edes3getkey\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estrtoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eallcnt\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecnt\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eallcnt\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edeskey\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eGROUP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eallcnt\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edes3key0\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eGROUP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eallcnt\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edes3key1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eGROUP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecnt\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eallcnt\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eGROUP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecnt\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- test (need to spend too much time)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- CREATE TABLE moretime(id INT, key RAW);\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- INSERT INTO moretime SELECT generate_series(1, 100000),\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e--     dbms_obfuscation_toolkit.desgetkey(strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;));\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- -- 预期 key列重复的字符不多\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- SELECT * FROM moretime ORDER BY key ASC LIMIT 10;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- SELECT * FROM moretime ORDER BY key DESC LIMIT 10;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- DROP TABLE moretime;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edeskey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edes3key0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edes3key1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eallcnt\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eEXTENSION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgcrypto\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eRESET\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esearch_path\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSCHEMA\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgcrypto_2_text\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCASCADE\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"海量 1 用例 oracle加密函数"},{"content":"1 设置默认版本\ncontrib/pgcrypto/pgcrypto.control defaultl_version = \u0026#39;2.0\u0026#39; dbcompatibilities = \u0026#39;A, B, PG\u0026#39; 生成同名的sql文件\ntouch contrib/pgcrypto/pgcrypto-2.0.sql 安装sql文件\n# pgcrypto.control与pgcrypt.*.sql文件 ll $GAUSSHOME/share/postgresql/extension | grep pgcrypto 加载插件\n# 执行：CREATE EXTENSION pgcrypto .. CreateExtension check_valild_extension_name # 检查插件名：要求不含 \u0026#39;-\u0026#39;、不含\u0026#39;..\u0026#39;等路径字符 get_extension_oid heap_open(\u0026#39;pg_extension\u0026#39;) systable_beginscan # 遍历系统表 pg_extension：确保插件存在 read_extension_control_file parse_extension_control_file get_extension_control_filename sprintf(\u0026#34;{share}/extension/{extension_name}.control\u0026#34;) ParreConfigFp # 获取 directory, default_version, module_pathname, dbcompatibilities 等参数 get_extension_script_filename get_extension_script_direcotry if name is \u0026#39;pgcrypto\u0026#39;: sprintf(\u0026#34;{script_dir}/crypto-a.sql\u0026#34;) read_extension_script_file InsertExtensionTuple # 插入系统表 pg_extension execute_extension_script ApplyExtensionUpdates ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/1-design-oracle-crypto-func/","summary":"\u003ch1 id=\"1\"\u003e1\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e设置默认版本\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003econtrib/pgcrypto/pgcrypto.control\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003edefaultl_version\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;2.0\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003edbcompatibilities\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;A, B, PG\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e生成同名的sql文件\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etouch contrib/pgcrypto/pgcrypto-2.0.sql\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e安装sql文件\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#  pgcrypto.control与pgcrypt.*.sql文件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ell \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/share/postgresql/extension \u003cspan class=\"p\"\u003e|\u003c/span\u003e grep pgcrypto\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e加载插件\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 执行：CREATE EXTENSION pgcrypto\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"o\"\u003e..\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eCreateExtension\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003echeck_valild_extension_name\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 检查插件名：要求不含 \u0026#39;-\u0026#39;、不含\u0026#39;..\u0026#39;等路径字符\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eget_extension_oid\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eheap_open\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pg_extension\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003esystable_beginscan\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 遍历系统表 pg_extension：确保插件存在\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eread_extension_control_file\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eparse_extension_control_file\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eget_extension_control_filename\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003esprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e{share}\u003c/span\u003e\u003cspan class=\"s2\"\u003e/extension/\u003c/span\u003e\u003cspan class=\"si\"\u003e{extension_name}\u003c/span\u003e\u003cspan class=\"s2\"\u003e.control\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eParreConfigFp\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"c1\"\u003e# 获取 directory, default_version, module_pathname, dbcompatibilities 等参数\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eget_extension_script_filename\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eget_extension_script_direcotry\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003ename\u003c/span\u003e \u003cspan class=\"ow\"\u003eis\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;pgcrypto\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003esprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"si\"\u003e{script_dir}\u003c/span\u003e\u003cspan class=\"s2\"\u003e/crypto-a.sql\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eread_extension_script_file\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eInsertExtensionTuple\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 插入系统表 pg_extension\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eexecute_extension_script\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eApplyExtensionUpdates\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ol\u003e","title":"海量 1 设计 oracle加密函数"},{"content":"1 简介 1.1 目的 早期版本的oracle提供一个包含多个加密函数的包，用户可通过SQL语法调用加密函数，实现数据加密功能。本文主要介绍以下几点：\noracle加密包的功能与使用方法 vastbase实现oracle加密包 vastbase加密包的功能与使用方法 本文档可指导开发者、测试者熟悉vastbase加密包特性的功能场景。\n本文档的内容已被上传至tapd，tapd上，排版更好看，测试用例更方便复制。建议直接从tapd上查看本文档原文： https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007194\n1.2 适用范围 vastbase 3.0.8及之后版本。\n1.3 术语定义、首字母缩写词和缩略语 DES：Data Encryption Standard，数据加密标准，一种早期通用的加密算法 3DES：Triple DES，基于DES演进的一种早期通用的加密算法 MD5：Message-Digest Algorithm，一种早期通用的数据摘要算法 1.3 参考资料 oracle dbms_obfuscation_toolkit 函数介绍：https://docs.oracle.com/cd/A97630_01/appdev.920/a96590/adgsec04.htm oracle dbms_obfuscation_toolkit 函数参数：https://docs.oracle.com/cd/B10500_01/appdev.920/a96612/d_obtoo2.htm tapd上，本需求文档： https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007194 tapd上，本需求的测试用例： https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007197 2 支持oracle加密插件dbms_obfuscation_toolkit 2.1 功能简述 早期版本oracle提供7个内置加密函数。早在4年或更早之前的旧版本vastbase中，也提供7个与oracle一致的加密函数，这7个函数，函数名、函数入参与oracle一致，但是，6个函数输出、15个函数参数约束与oracle不一致，本特性将重构这些加密函数，确保函数的输出、约束等与oracle一致。\n一、基础知识 加密的原理\n加密算法有很多种，不同场景中，适合的加密算法类型不同。对存储数据加密，通常采用对称密码算法，此处主要介绍对称密码算法：\n加密原理：输入1个明文，输入1个密钥，对明文和密钥进行一些可逆的运算（比如异或，代换），可得到1个密文。密钥通常是随机生成的 加密算法：DES算法，发布于1977年，已确定为不安全加密算法。3DES算法，调用3次DES算法，生成3个密钥，安全性与DES差别不大，也属于不安全的加密算法。AES算法，发布于2001年，通用的国际标准，替代不安全的DES算法 数据库加密函数\n几乎所有数据库，都提供内置加密函数，让用户通过SQL语句调用。最典型的场景如下：\n-- 假设，数据库提供函数encrypt(明文，密钥，加密算法)，输出为密文 -- 用户想表\u0026#39;t1\u0026#39;中存储数据\u0026#39;shenkun\u0026#39;，则存储的语法如下：（用户自己保管密钥） INSERT INTO t1 VALUES (encrypt(\u0026#39;shenkun\u0026#39;, \u0026#39;一串随机的密钥\u0026#39;, \u0026#39;aes\u0026#39;)); 二、Oracle加密包 早期版本的oracle中，包含1个名为dbms_obfuscation_toolkit的包，提供7个函数，主要实现加密、解密等功能：\n版本信息：oracle 8i版本开始提供，oracle 10g版本开始不被推荐使用，由dbms_crypto代替，oracle 21c版本正式移除 函数列表： 生成随机数：desgetkey(seed) -\u0026gt; key 加密：desencrypt(input, key) -\u0026gt; encrypted_data 解密：descdecrypt(input, key) -\u0026gt; decrypted_data 生成随机数：des3getkey(which=\u0026gt;0, seed) -\u0026gt; key 加密：des3encrypt(input, key, which=\u0026gt;0, iv=\u0026gt;012345678abcdef) -\u0026gt; encrypted_data 解密：des3decrypt(input, key, which=\u0026gt;0, iv=\u0026gt;012345678abcdef) -\u0026gt; decrypted_data 哈希：md5(input) -\u0026gt; checksum 函数参数：函数参数有2种数据类型：varchar2, raw。与raw类型相比，如果是varchar2类型，参数名需加上_string后缀。比如，raw类型的入参名为input，则varcha2类型入参名为input_string 函数限制： desgetkey：seed长度最短为80字节 desencrypt：input长度是8字节的整数倍；key最短为8字节，超过8字节的部分被丢弃 descdecrypt：input长度是8字节的整数倍；key最短为8字节，超过8字节的部分被丢弃 des3getkey: seed长度最短为80字节 des3encrypt：input长度是8字节的整数倍；which为0时，key最短为16字节，超过16字节的部分被丢弃；which为1时，key最短为24字节，超过24字节的部分被丢弃 des3dencrypt：input长度是8字节的整数倍；which为0时，key最短为16字节，超过16字节的部分被丢弃；which为1时，key最短为24字节，超过24字节的部分被丢弃 md5：无 参考文档 函数介绍：函数背景、注意事项等：https://docs.oracle.com/cd/A97630_01/appdev.920/a96590/adgsec04.htm 函数参数：参数类型、调用示例等：https://docs.oracle.com/cd/B10500_01/appdev.920/a96612/d_obtoo2.htm 以下是上述函数的调用示例：\n创建辅助函数\n简单封住数据类型转换函数，方便阅读函数：\nCREATE FUNCTION strtoraw(string VARCHAR2) RETURN RAW IS BEGIN RETURN utl_raw.cast_to_raw(string); END; / CREATE FUNCTION rawtostr(rawdata RAW) RETURN VARCHAR2 IS BEGIN RETURN utl_raw.cast_to_varchar2(rawdata); END; / DES生成密钥\nSELECT dbms_obfuscation_toolkit.desgetkey(seed=\u0026gt;strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;)) FROM dual; -- seed最短长度为80字节，每次输出的值都是随机的，长度为8字节 DES加密\nSELECT dbms_obfuscation_toolkit.desencrypt(input=\u0026gt;strtoraw(\u0026#39;1111111111111111\u0026#39;), key=\u0026gt;strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 输出 655EA628CF62585F20D3B8A6E657876B DES解密\nSELECT rawtostr(dbms_obfuscation_toolkit.desdecrypt(input=\u0026gt;hextoraw(\u0026#39;655EA628CF62585F20D3B8A6E657876B\u0026#39;), key=\u0026gt;strtoraw(\u0026#39;11111111\u0026#39;))) FROM dual; -- 输出 1111111111111111 3DES生成密钥\nSELECT dbms_obfuscation_toolkit.des3getkey(which=\u0026gt;0, seed=\u0026gt;strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;)) FROM dual; -- seed最短长度为80字节，每次输出的值都是随机的，which=0，输出16字节，which=1，输出24字节 3DES加密\nSELECT dbms_obfuscation_toolkit.des3encrypt(input=\u0026gt;strtoraw(\u0026#39;1111111111111111\u0026#39;), key=\u0026gt;strtoraw(\u0026#39;1111111122222222\u0026#39;), which=\u0026gt;0, iv=\u0026gt;strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 输出 0D28E17571051319ACCE2D19D9AED5C8 3DES解密\nSELECT rawtostr(dbms_obfuscation_toolkit.des3decrypt(input=\u0026gt;hextoraw(\u0026#39;0D28E17571051319ACCE2D19D9AED5C8\u0026#39;), key=\u0026gt;strtoraw(\u0026#39;1111111122222222\u0026#39;), which=\u0026gt;0, iv=\u0026gt;strtoraw(\u0026#39;11111111\u0026#39;))) FROM dual; -- 输出 1111111111111111 MD5哈希\nSELECT dbms_obfuscation_toolkit.md5(input=\u0026gt;strtoraw(\u0026#39;1111111111111111\u0026#39;)) FROM dual; -- 输出 FA1D3EB08A879DE9A4CD9995A1AA91E1 三、vasebase 加密包（旧版本1.2及之前） vastbase也提供dbms_obfuscation_toolkit包，代码在4年前或更早前合入，函数个数，函数名，函数参数等与oracle保持一致：\n函数列表： 生成随机数：desgetkey(seed) -\u0026gt; key 加密：desencrypt(input, key) -\u0026gt; encrypted_data 解密：descdecrypt(input, key) -\u0026gt; decrypted_data 生成随机数：des3getkey(seed) / des3getkey(which, seed) -\u0026gt; key 加密：des3encrypt(input, key, which = 0) | des3encrypt(input, key, iv) | des3encrypt(input, key, which, iv) -\u0026gt; encrypted_data 解密：des3decrypt(input, key, which = 0) | des3decrypt(input, key, iv) | des3decrypt(input, key, which, iv) -\u0026gt; encrypted_data -\u0026gt; decrypted_data 哈希：md5(input) -\u0026gt; checksum 函数参数：函数参数有3种数据类型: text, bytea, raw 以下是上述函数的调用示例：\n创建辅助函数与安装加密插件\n简单封住数据类型转换函数，方便阅读函数：\nCREATE FUNCTION strtoraw(string VARCHAR2) RETURN RAW IS BEGIN RETURN utl_raw.cast_to_raw(string); END; / CREATE FUNCTION rawtostr(rawdata RAW) RETURN VARCHAR2 IS BEGIN RETURN utl_raw.cast_to_varchar2(rawdata); END; / -- 安装加解密插件 CREATE EXTENSION pgcrypto; DES生成密钥\nSELECT dbms_obfuscation_toolkit.desgetkey(strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;)) FROM dual; -- seed最短长度为80字节，每次输出的值都是随机的，长度为8字节 -- 输出 (vastbase) 可见字符 {a-z, A-Z, 0-9, 特殊符号} -- 输出 (oracle) 随机的任意数据 DES加密\nSELECT dbms_obfuscation_toolkit.desencrypt(strtoraw(\u0026#39;1111111111111111\u0026#39;), strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 输出 (vastbase) 5A56366D4B4D3969574638673037696D356C65486138A7616167394370743236 -- 输出（oracle） 655EA628CF62585F20D3B8A6E657876B DES解密\nSELECT rawtostr(dbms_obfuscation_toolkit.desdecrypt(hextoraw(\u0026#39;655EA628CF62585F20D3B8A6E657876B\u0026#39;), strtoraw(\u0026#39;11111111\u0026#39;))) FROM dual; -- 输出 (vastbase) ERROR: invalid symbol -- 输出（oracle） 1111111111111111 3DES生成密钥\nSELECT dbms_obfuscation_toolkit.des3getkey(0, strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;)) FROM dual; -- seed最短长度为80字节，每次输出的值都是随机的，which=0，输出16字节，which=1，输出24字节 -- 输出 (vastbase) 可见字符 {a-z, A-Z, 0-9, 特殊符号} -- 输出 (oracle) 随机的任意数据 3DES加密\nSELECT dbms_obfuscation_toolkit.des3encrypt(strtoraw(\u0026#39;1111111111111111\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;), 0, strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 输出 (vastbase) 4F7A53663334507232592F3542747033644975635673765966543477414C5737 -- 输出（oracle） 0D28E17571051319ACCE2D19D9AED5C8 3DES解密\nSELECT rawtostr(dbms_obfuscation_toolkit.des3decrypt(hextoraw(\u0026#39;0D28E17571051319ACCE2D19D9AED5C8\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;), 0, strtoraw(\u0026#39;11111111\u0026#39;))) FROM dual; -- 输出 (vastbase) ERROR: invalid symbol -- 输出（oracle） 1111111111111111 MD5哈希\nSELECT dbms_obfuscation_toolkit.md5(strtoraw(\u0026#39;1111111111111111\u0026#39;)) FROM dual; -- 输出 FA1D3EB08A879DE9A4CD9995A1AA91E1 四、需求场景 以前，客户使用oracle，并通过dbms_obfuscation_toolkit插件加密存储数据。现在，客户使用vastbase，并将数据迁移到vastbase中，包括以前由dbms_obfuscation_toolkit插件加密后的数据。在该场景中，需要满足2个要求：\n解密旧数据：oracle加密数据，将密文迁移至vasebase，vastbase可解密迁移来的密文 加密新数据：客户系统中，vastbase与oracle混用，在数据库运维、数据共享等场景中，确保多个系统中数据一致，存在加密新数据的场景 五、需求背景 旧版本vastbase也提供了dbms_obfuscation_toolkit包，该包提供7个函数，函数名与函数参数个数与oracle一致。\n但是，实际使用过程中，这7个函数与oracle的函数存在一些差异，在上述场景中，该差异可能导致客户应用不可用。\n函数输出不一致：比如，相同的加密函数、明文、密钥、加密算法，vastbase与oracle的输出内容、输出长度不一致。 示例：desencrypt()函数，加密16字节，oracle密文为16字节，vastbase密文为32字节，vastbase的密文中，会携带分组填充，并且以base64编码 示例：desgetkey()函数，用于生成随机数，oracle随机数为密码学中的随机数，vastbase的随机数为可见字符串[0,9], [a,z], [A,Z]等，不符合密码学中的随机数要求 参数约束不一致：比如，相同的加密函数，vastbase与oracle的参数长度限制不一致 六、需求目标 为解决上述问题，本版本的vastbase需达到以下要求：\n加密函数输出结果与oracle一致 解密函数输出结果与oracle一致 函数参数约束与oracle一致 保持前向兼容，即可解密旧版本vastbase加密的结果（需用户主动控制加密函数的版本） 七、相关问题 bytea特殊字符转换\n将text转换为bytea的过程中，可能出现text被阶段的问题。\n比如一串text数据abc\\0cd，长度为6，转换为bytea的过程为：先将text转换为cstring，再讲csting转换为bytea，由于cstring无法携带数据长度，所以，csting转换为bytea时，根据\\0来判断数据结尾。\nSELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;) FROM dual; -- 预期输出：8字节，实际输出：3字节 des3encrypt ------------ @jx SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;)::bytea FROM dual; -- 预期输出：8字节，实际输出：4字节（oracle无bytea类型） des3encrypt ------------ \\x40826a58 SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;::bytea, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;) FROM dual; des3encrypt ------------------- \\x40826a5800608c87 SELECT utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;)); des3encrypt ------------------- 40826A5800608C87 在实际使用场景中，示例如下：\nCREATE TABLE t1 (c1 TEXT, c2 BYTEA, c3 RAW, c4 BYTEA); -- 加密 INSERT INTO t1 VALUES ( dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;), dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;)::bytea, utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;)), dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;::bytea, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;) ); SELECT * FROM t1; c1 | c2 | c3 | c4 -----+------------+------------------+-------------------- @jx | \\x40826a58 | 40826A5800608C87 | \\x40826a5800608c87 -- 解密 SELECT dbms_obfuscation_toolkit.des3decrypt(c1, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;) FROM t1; SELECT dbms_obfuscation_toolkit.des3decrypt(c2, \u0026#39;1111111111111111\u0026#39;::bytea, 0, \u0026#39;11111111\u0026#39;::bytea) FROM t1; -- 解密失败 SELECT dbms_obfuscation_toolkit.des3decrypt(c3, utl_raw.cast_to_raw(\u0026#39;1111111111111111\u0026#39;), 0, utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;)) FROM t1; SELECT dbms_obfuscation_toolkit.des3decrypt(c4, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;) FROM t1; 上述场景中，该问题的规避方法是，建议用户手动强制将入参函数的类型转换为bytea类型。\n但是，如果用户没有规避，可能会导致c2列解密失败，因此，只能考虑直接禁用bytea类型。可以考虑解决text转bytea的阶段问题，但该问题是公共问题，且影响范围大，本版本来不及解决。\noracle只有raw类型，无bytea类型。\nCREATE TABLE t1 (c1 VARCHAR2(100), c2 RAW(100), c3 RAW(100)); -- 加密 INSERT INTO t1 VALUES ( dbms_obfuscation_toolkit.des3encrypt(input_string=\u0026gt;\u0026#39;11111111\u0026#39;, key_string=\u0026gt;\u0026#39;1111111111111111\u0026#39;, which=\u0026gt;0, iv_string=\u0026gt;\u0026#39;11111111\u0026#39;), utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(input_string=\u0026gt;\u0026#39;11111111\u0026#39;, key_string=\u0026gt;\u0026#39;1111111111111111\u0026#39;, which=\u0026gt;0, iv_string=\u0026gt;\u0026#39;11111111\u0026#39;)), dbms_obfuscation_toolkit.des3encrypt(input=\u0026gt;utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;), key=\u0026gt;utl_raw.cast_to_raw(\u0026#39;1111111111111111\u0026#39;), which=\u0026gt;0, iv=\u0026gt;utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;)) ); SELECT * FROM t1; raw类型自动转换\nvastbase的::raw实现与utl_raw.cast_to_raw不一致\nSELECT dbms_obfuscation_toolkit.desencrypt(utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;), utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 输出 655EA628CF62585F SELECT dbms_obfuscation_toolkit.desencrypt(\u0026#39;11111111\u0026#39;::raw, \u0026#39;11111111\u0026#39;::raw) FROM dual; -- 底层的加解密函数中，输入的长度变成了4字节，输出结果与上面不一致 SELECT utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;) FROM dual; -- 输出 3131313131313131 SELECT \u0026#39;11111111\u0026#39;::raw FROM dual; -- 输出 1111111 oracle无::raw用法\nSELECT dbms_obfuscation_toolkit.desencrypt(input=\u0026gt;utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;), key=\u0026gt;utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 输出 655EA628CF62585F SELECT utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;) FROM dual; -- 输出 3131313131313131 八、需求实现 为实现上述目标，主要的工作量如下：\n加密算法：黑盒识别oracle的des与3des算法的具体实现，包括分组加密模式、分组填充、默认IV值等，确保新版本vastbase的输出与oracle一致 数据类型：分析不同类型数据之间的相互转换，比如oracle的[varchar2, raw]，vastbase的[text, bytea, raw] 前向兼容：识别旧版本vastbase的des与3des算法的具体实现，包括分组加密模式、分组填充、默认IV值、输出输出编码解码等，避免新版本vastbase无法解密旧版本vastbase加密的数据 报错信息：旧版本vastbase对异常入参的报错信息较模糊 代码质量：旧版本vastbase的加解密函数不符合cleancode规范，参数命名较模糊 九、需求约束 插件版本：安装dbms_obfuscation_toolkit插件时，默认安装新版本2.0插件，如需使用旧版本1.2插件，需主动指定旧版本。新版本插件与旧版本插件不兼容 解释：vastbase旧版本（本需求交付前的版本）插件的加密结果与oracle不一致，vastbase新版本（本需求交付的版本）插件的加密结果与oracle保持一致，因此，vastbase的新版本插件无法解密旧版本插件加密的数据。加密结果中，并没有存储版本号，即无法自动识别加密结果的版本 数据类型：使用dbms_obfuscation_toolkit插件时，加密与解密函数中，参数类型支持text或raw类型，不支持bytea类型 解释：oracle仅支持text和raw类型，无bytea类型。vastbase旧版本插件支持bytea类型，但是，text转bytea时存在截断的公共问题，本版本无法解决，因此，本版本无法支持bytea类型 函数入参： 编号 函数 参数 oracle约束 vasebase约束（旧版本pgcrypto） vasebase约束（新版本pgcrypto） 1 desgetkey(seed) seed 长度为[80, max]字节 长度为[0, max]字节 与oracle一致 2 des3getkey(which, seed) seed 长度为[80, max]字节 长度为[0, max]字节 与oracle一致 3 des3getkey(which, seed) which 0或1 所有整数，除0和1，其他整数与0效果一致 与oracle一致 4 desencrypt(input, key) input 长度为8字节整数倍 长度为[0, max]字节 与oracle一致 5 desencrypt(input, key) key 长度为[8, max] 字节 长度为[0, max]字节 与oracle一致 6 desdecrypt(input, key) input 长度为8字节整数倍 长度为[0, max] 与oracle一致 7 desdecrypt(input, key) key 长度为[8, max] 字节 长度为[0, max]字节 与oracle一致 8 des3encrypt(input, key, which=0，iv) input 长度为8字节整数倍 长度为[0, max]字节 与oracle一致 9 des3encrypt(input, key, which=0，iv) key which=0，key长度[16, max]字节；which=1，key长度[24, max]字节 which=0，key长度[16, max]字节，前8字节与后8字节不能一致。which=1，key长度[24, max]字节，前，中，后8字节不能一致 与oracle一致 10 des3encrypt(input, key, which=0，iv) which 0或1 所有整数，除0和1，其他整数与0效果一致 与oracle一致 11 des3encrypt(input, key, which=0，iv) iv 长度为[8, max]字节 长度为[0, max]字节 与oracle一致 12 des3encrypt(input, key, which=0，iv) input 长度为8字节整数倍 长度为[0, max]字节 与oracle一致 13 des3decrypt(input, key, which=0，iv) key which=0，key长度[16, max]字节；which=1，key长度[24, max]字节 which=0，key长度[16, max]字节，前8字节与后8字节不能一致。which=1，key长度[24, max]字节，前，中，后8字节不能一致 与oracle一致 14 des3decrypt(input, key, which=0，iv) which 0或1 所有整数，除0和1，其他整数与0效果一致 与oracle一致 15 des3decrypt(input, key, which=0，iv) iv 长度为[8, max]字节 长度为[0, max]字节 与oracle一致 2.2 功能说明 2.2.1 使用流程 一、安装不同版本的加密插件 查看pgcrypto可用的版本\nSELECT * FROM pg_available_extension_versions WHERE name = \u0026#39;pgcrypto\u0026#39;; -- 预期输出 可用版本包括1.2和2.0 安装pgcrypto-2.0版本\nCREATE EXTENSION pgcrypto; SELECT * FROM pg_extension WHERE extname = \u0026#39;pgcrypto\u0026#39;; -- 预期输出 默认版本为 2.0 \\df dbms_obfuscation_toolkit.desencrypt -- 预期输出 入参不支持bytea类型 Schema Name Result data type Argument data types Type --------------------------+------------+--------------------+-----------------------+-------+----- dbms_obfunscation_toolkit | desencrypt | raw | raw, raw | nomal | .. dbms_obfunscation_toolkit | desencrypt | text | text, text | nomal | .. DROP EXTENSION pgcrypto; 安装pgcrypto-1.2版本\nCREATE EXTENSION pgcrypto WITH VERSION \u0026#39;1.2\u0026#39;; SELECT * FROM pg_extension WHERE extname = \u0026#39;pgcrypto\u0026#39;; -- 预期输出 版本为 1.2 \\df dbms_obfuscation_toolkit.desencrypt -- 预期输出 入参支持bytea类型 Schema Name Result data type Argument data types Type --------------------------+------------+--------------------+-----------------------+-------+----- dbms_obfunscation_toolkit | desencrypt | raw | raw, raw | nomal | .. dbms_obfunscation_toolkit | desencrypt | text | text, text | nomal | .. dbms_obfunscation_toolkit | desencrypt | bytea | bytea, bytea | nomal | .. DROP EXTENSION pgcrypto; 从pgcrypto-2.0降级为pgcrypto-1.2\nCREATE EXTENSION pgcrypto; ALTER EXTENSION pgcrypto UPDATE TO \u0026#39;1.2\u0026#39;; SELECT * FROM pg_extension WHERE extname = \u0026#39;pgcrypto\u0026#39;; -- 预期输出 版本为 1.2 \\df dbms_obfuscation_toolkit.desencrypt -- 预期输出 入参支持bytea类型 Schema Name Result data type Argument data types Type --------------------------+------------+--------------------+-----------------------+-------+----- dbms_obfunscation_toolkit | desencrypt | raw | raw, raw | nomal | .. dbms_obfunscation_toolkit | desencrypt | text | text, text | nomal | .. dbms_obfunscation_toolkit | desencrypt | bytea | bytea, bytea | nomal | .. DROP EXTENSION pgcrypto; 从pgcrypto-1.2升级为pgcrypto-2.0\nCREATE EXTENSION pgcrypto WITH VERSION \u0026#39;1.2\u0026#39;; ALTER EXTENSION pgcrypto UPDATE TO \u0026#39;2.0\u0026#39;; SELECT * FROM pg_extension WHERE extname = \u0026#39;pgcrypto\u0026#39;; -- 预期输出 版本为 2.0 \\df dbms_obfuscation_toolkit.desencrypt -- 预期输出 入参不支持bytea类型 Schema Name Result data type Argument data types Type --------------------------+------------+--------------------+-----------------------+-------+----- dbms_obfunscation_toolkit | desencrypt | raw | raw, raw | nomal | .. dbms_obfunscation_toolkit | desencrypt | text | text, text | nomal | .. DROP EXTENSION pgcrypto; 二、使用加密插件的核心函数 客户核心需求是，在dbms_obfuscation_toolkit加密包中，加密函数与解密函数与oracle保持一致。即本场景为核心场景。\ndes加密函数\n首先，简单封装2个数据类型转换函数，方便阅读SQL语句\nCREATE FUNCTION strtoraw(string VARCHAR2) RETURN RAW IS BEGIN RETURN utl_raw.cast_to_raw(string); END; / CREATE FUNCTION rawtostr(rawdata RAW) RETURN VARCHAR2 IS BEGIN RETURN utl_raw.cast_to_varchar2(rawdata); END; / 本场景中，预期输出需与oracle保持一致\n-- 安装加解密插件 CREATE EXTENSION pgcrypto; SELECT dbms_obfuscation_toolkit.desencrypt(strtoraw(\u0026#39;1111111111111111\u0026#39;), strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 预期输出 655EA628CF62585F20D3B8A6E657876B des解密函数\n本场景中，预期输出需与oracle保持一致\nSELECT rawtostr(dbms_obfuscation_toolkit.desdecrypt(hextoraw(\u0026#39;655EA628CF62585F20D3B8A6E657876B\u0026#39;), strtoraw(\u0026#39;11111111\u0026#39;))) FROM dual; -- 预期输出 1111111111111111 3des加密函数\n本场景中，预期输出需与oracle保持一致\nSELECT dbms_obfuscation_toolkit.des3encrypt(strtoraw(\u0026#39;1111111111111111\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;), 0, strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 预期输出 0D28E17571051319ACCE2D19D9AED5C8 3des解密函数\n本场景中，预期输出需与oracle保持一致\nSELECT rawtostr(dbms_obfuscation_toolkit.des3decrypt(hextoraw(\u0026#39;0D28E17571051319ACCE2D19D9AED5C8\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;), 0, strtoraw(\u0026#39;11111111\u0026#39;))) FROM dual; -- 预期输出 1111111111111111 3des加密函数iv为空\n本场景中，预期输出需与oracle保持一致\nSELECT dbms_obfuscation_toolkit.des3encrypt(strtoraw(\u0026#39;1111111111111111\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;)) FROM dual; -- 预期输出 7934131269E334A2BCC64878CC5A075A 3des解密函数iv为空\n本场景中，预期输出需与oracle保持一致\nSELECT rawtostr(dbms_obfuscation_toolkit.des3decrypt(hextoraw(\u0026#39;7934131269E334A2BCC64878CC5A075A\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;))) FROM dual; -- 预期输出 1111111111111111 三、测试加密插件的不同入参 des加密超长数据\n首先，创建1个表存储加解密结果\nCREATE TABLE plain (c1 RAW); CREATE TABLE cipher (c1 RAW); 此处，待加密的数据长度为80000字节\nINSERT INTO plain VALUES (strtoraw(repeat(\u0026#39;0123456789\u0026#39;, 8000))); INSERT INTO CIPHER VALUES (dbms_obfuscation_toolkit.desencrypt(strtoraw(repeat(\u0026#39;0123456789\u0026#39;, 8000)), strtoraw(\u0026#39;11111111\u0026#39;))); SELECT length(c1) FROM plain; SELECT length(c1) FROM cipher; SELECT (SELECT c1 FROM plain) = (SELECT c1 FROM cipher); -- 预期输出 f des解密超长数据\nSELECT (SELECT c1 FROM plain) = (SELECT dbms_obfuscation_toolkit.desdecrypt(c1, strtoraw(\u0026#39;11111111\u0026#39;))FROM cipher); -- 预期输出 t TRUNCATE plain; TRUNCATE cipher; 3des加密超长数据\nINSERT INTO plain VALUES (strtoraw(repeat(\u0026#39;0123456789\u0026#39;, 8000))); INSERT INTO CIPHER VALUES (dbms_obfuscation_toolkit.des3encrypt(strtoraw(repeat(\u0026#39;0123456789\u0026#39;, 8000)), strtoraw(\u0026#39;1111111122222222\u0026#39;), 0, strtoraw(\u0026#39;11111111\u0026#39;))); SELECT length(c1) FROM plain; SELECT length(c1) FROM cipher; SELECT (SELECT c1 FROM plain) = (SELECT c1 FROM cipher); -- 预期输出 f 3des解密超长数据\nSELECT (SELECT c1 FROM plain) = (SELECT dbms_obfuscation_toolkit.des3decrypt(c1, strtoraw(\u0026#39;1111111122222222\u0026#39;), 0, strtoraw(\u0026#39;11111111\u0026#39;)) FROM cipher); -- 预期输出 t DROP TABLE plain; DROP TABLE cipher; 3des中keymode参数为1\nSELECT dbms_obfuscation_toolkit.des3encrypt(strtoraw(\u0026#39;1111111111111111\u0026#39;), strtoraw(\u0026#39;111111112222222233333333\u0026#39;), 1, strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; SELECT dbms_obfuscation_toolkit.des3decrypt(hextoraw(\u0026#39;7934131269E334A2BCC64878CC5A075A\u0026#39;), strtoraw(\u0026#39;111111112222222233333333\u0026#39;), 1, strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; 四、使用加密插件的非核心函数 desgetkey生成随机数\nseed最短长度为80字节，每次输出的值都是随机的，长度为8字节\nSELECT dbms_obfuscation_toolkit.desgetkey(strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;)) FROM dual; des3getkey生成随机数\nseed最短长度为80字节，每次输出的值都是随机的，which=0，输出16字节，which=1，输出24字节\nSELECT dbms_obfuscation_toolkit.des3getkey(0, strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;)) FROM dual; SELECT dbms_obfuscation_toolkit.des3getkey(1, strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;)) FROM dual; md5生成哈希值\nSELECT dbms_obfuscation_toolkit.md5(strtoraw(\u0026#39;1111111111111111\u0026#39;)) FROM dual; -- 预期输出 FA1D3EB08A879DE9A4CD9995A1AA91E1 验证desgetkey生成随机数的熵\nCREATE TABLE moretime(id INT, key RAW); INSERT INTO moretime SELECT generate_series(1, 100000), dbms_obfuscation_toolkit.desgetkey(strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;)); SELECT * FROM moretime ORDER BY key ASC LIMIT 10; -- 预期 以01开始 SELECT * FROM moretime ORDER BY key DESC LIMIT 10; -- 预期 以FF结尾 DROP TABLE moretime; 验证des3getkey生成随机数的熵\nCREATE TABLE moretime(id INT, key RAW); INSERT INTO moretime SELECT generate_series(1, 100000), dbms_obfuscation_toolkit.des3getkey(0, strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;))； SELECT * FROM moretime ORDER BY key ASC LIMIT 10; -- 预期 以01开始 SELECT * FROM moretime ORDER BY key DESC LIMIT 10; -- 预期 以FF结尾 DROP TABLE moretime; 验证des3getkey生成随机数的熵\nCREATE TABLE moretime(id INT, key RAW); INSERT INTO moretime SELECT generate_series(1, 100000), dbms_obfuscation_toolkit.des3getkey(1, strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;))； SELECT * FROM moretime ORDER BY key ASC LIMIT 10; -- 预期 以01开始 SELECT * FROM moretime ORDER BY key DESC LIMIT 10; -- 预期 以FF结尾 DROP TABLE moretime; 五、验证加密插件的参数约束 由于参数较多，此处便不分别列举每个测试场景：\n编号 函数 参数 oracle约束 vasebase约束（旧版本pgcrypto） vasebase约束（新版本pgcrypto） 1 desgetkey(seed) seed 长度为[80, max]字节 长度为[0, max]字节 与oracle一致 2 des3getkey(which, seed) seed 长度为[80, max]字节 长度为[0, max]字节 与oracle一致 3 des3getkey(which, seed) which 0或1 所有整数，除0和1，其他整数与0效果一致 与oracle一致 4 desencrypt(input, key) input 长度为8字节整数倍 长度为[0, max]字节 与oracle一致 5 desencrypt(input, key) key 长度为[8, max] 字节 长度为[0, max]字节 与oracle一致 6 desdecrypt(input, key) input 长度为8字节整数倍 长度为[0, max] 与oracle一致 7 desdecrypt(input, key) key 长度为[8, max] 字节 长度为[0, max]字节 与oracle一致 8 des3encrypt(input, key, which=0，iv) input 长度为8字节整数倍 长度为[0, max]字节 与oracle一致 9 des3encrypt(input, key, which=0，iv) key which=0，key长度[16, max]字节；which=1，key长度[24, max]字节 which=0，key长度[16, max]字节，前8字节与后8字节不能一致。which=1，key长度[24, max]字节，前，中，后8字节不能一致 与oracle一致 10 des3encrypt(input, key, which=0，iv) which 0或1 所有整数，除0和1，其他整数与0效果一致 与oracle一致 11 des3encrypt(input, key, which=0，iv) iv 长度为[8, max]字节 长度为[0, max]字节 与oracle一致 12 des3encrypt(input, key, which=0，iv) input 长度为8字节整数倍 长度为[0, max]字节 与oracle一致 13 des3decrypt(input, key, which=0，iv) key which=0，key长度[16, max]字节；which=1，key长度[24, max]字节 which=0，key长度[16, max]字节，前8字节与后8字节不能一致。which=1，key长度[24, max]字节，前，中，后8字节不能一致 与oracle一致 14 des3decrypt(input, key, which=0，iv) which 0或1 所有整数，除0和1，其他整数与0效果一致 与oracle一致 15 des3decrypt(input, key, which=0，iv) iv 长度为[8, max]字节 长度为[0, max]字节 与oracle一致 六、验证前后向兼容 使用旧版本des加密\n创建2个表，存储中间结果\nCREATE TABLE told(c1 TEXT, c2 RAW); CREATE TABLE tnew(c1 TEXT, c2 RAW); 使用\nCREATE EXTENSION pgcrypto WITH VERSION \u0026#39;1.2\u0026#39;; INSERT INTO told VALUES ( dbms_obfuscation_toolkit.desencrypt(strtoraw(\u0026#39;1111111111111111\u0026#39;), strtoraw(\u0026#39;11111111\u0026#39;)), dbms_obfuscation_toolkit.desencrypt(\u0026#39;1111111111111111\u0026#39;, \u0026#39;11111111\u0026#39;)); 使用新版本des加密\nALTER EXTENSION pgcrypto UPDATE TO \u0026#39;2.0\u0026#39;; INSERT INTO tnew VALUES ( dbms_obfuscation_toolkit.desencrypt(strtoraw(\u0026#39;1111111111111111\u0026#39;), strtoraw(\u0026#39;11111111\u0026#39;)), dbms_obfuscation_toolkit.desencrypt(\u0026#39;1111111111111111\u0026#39;, \u0026#39;11111111\u0026#39;)); 使用新版本des解密旧版本密文\nSELECT dbms_obfuscation_toolkit.desencrypt(c1, \u0026#39;11111111\u0026#39;) FROM told; -- 预期输出 解密成功，但结果与原明文不一致 SELECT dbms_obfuscation_toolkit.desencrypt(c1, strtoraw(\u0026#39;11111111\u0026#39;)) FROM told; -- 预期输出 解密成功，但结果与原明文不一致 使用旧版本des解密新版本密文\nALTER EXTENSION pgcrypto UPDATE TO \u0026#39;1.2\u0026#39;; SELECT dbms_obfuscation_toolkit.desencrypt(c1, \u0026#39;11111111\u0026#39;) FROM told; -- 预期输出 解密成功，但结果与原明文不一致 SELECT dbms_obfuscation_toolkit.desencrypt(c1, strtoraw(\u0026#39;11111111\u0026#39;)) FROM told; -- 预期输出 解密成功，但结果与原明文不一致 使用3des算法重复上述操作\n只需将1至5步中的des算法替换为3des算法即可，此处不再重复描述。\n2.2.2 配置参数和文件 安装pgcrypto插件后，即可使用本特性，无需设置GUC参数，无需设置配置文件。本特性仅修改pgcrypto中的部分加密函数，未新增函数。\nCREATE EXTENSION pgcrypto; 2.2.3 数据相关性 无\n2.3 接口信息 插件：pgcrypto插件可用版本由[1.2]变更为[1.2, 2.0]，2.0版本与1.2的主要区别是几个内置函数的入参约束、输出结果不同： 修改dbms_obfuscation_toolkit.desgetkey()的入参约束、输出结果 修改dbms_obfuscation_toolkit.desencrypt()的入参约束、输出结果 修改dbms_obfuscation_toolkit.desdecrypt()的入参约束、输出结果 修改dbms_obfuscation_toolkit.des3getkey()的入参约束、输出结果 修改dbms_obfuscation_toolkit.des3encrypt()的入参约束、输出结果 修改dbms_obfuscation_toolkit.des3decrypt()的入参约束、输出结果 2.4 正反向行为 2.4.1 生效说明 特性可用\n执行CREATE EXTENSION pgcrypto;可开启加密函数，执行SELECT * FROM pg_extension WHERE extname = 'pgcrypto';可查看加密函数的版本，如果版本是2.0，则本特性可用\n特性正常\n执行上述提到的desencrypt、desdecrypt、des3encrypt、des3decrypt函数，入参相同时，输出结果与oracle一致，则本特性功能正常\n2.4.2 提示信息 使用dbms_obfuscation_toolkit中的加密函数时，如果函数入参不符合约束，则会出现相关报错\n2.4.3 约束和依赖 上文已解释过约束，此处不重新解释。\n插件版本：安装dbms_obfuscation_toolkit插件时，默认安装新版本2.0插件，如需使用旧版本1.2插件，需主动指定旧版本。新版本插件与旧版本插件不兼容 数据类型：使用dbms_obfuscation_toolkit插件时，加密与解密函数中，参数类型支持text或raw类型，不支持bytea类型 函数入参： 编号 函数 参数 oracle约束 vasebase约束（旧版本pgcrypto） vasebase约束（新版本pgcrypto） 1 desgetkey(seed) seed 长度为[80, max]字节 长度为[0, max]字节 与oracle一致 2 des3getkey(which, seed) seed 长度为[80, max]字节 长度为[0, max]字节 与oracle一致 3 des3getkey(which, seed) which 0或1 所有整数，除0和1，其他整数与0效果一致 与oracle一致 4 desencrypt(input, key) input 长度为8字节整数倍 长度为[0, max]字节 与oracle一致 5 desencrypt(input, key) key 长度为[8, max] 字节 长度为[0, max]字节 与oracle一致 6 desdecrypt(input, key) input 长度为8字节整数倍 长度为[0, max] 与oracle一致 7 desdecrypt(input, key) key 长度为[8, max] 字节 长度为[0, max]字节 与oracle一致 8 des3encrypt(input, key, which=0，iv) input 长度为8字节整数倍 长度为[0, max]字节 与oracle一致 9 des3encrypt(input, key, which=0，iv) key which=0，key长度[16, max]字节；which=1，key长度[24, max]字节 which=0，key长度[16, max]字节，前8字节与后8字节不能一致。which=1，key长度[24, max]字节，前，中，后8字节不能一致 与oracle一致 10 des3encrypt(input, key, which=0，iv) which 0或1 所有整数，除0和1，其他整数与0效果一致 与oracle一致 11 des3encrypt(input, key, which=0，iv) iv 长度为[8, max]字节 长度为[0, max]字节 与oracle一致 12 des3encrypt(input, key, which=0，iv) input 长度为8字节整数倍 长度为[0, max]字节 与oracle一致 13 des3decrypt(input, key, which=0，iv) key which=0，key长度[16, max]字节；which=1，key长度[24, max]字节 which=0，key长度[16, max]字节，前8字节与后8字节不能一致。which=1，key长度[24, max]字节，前，中，后8字节不能一致 与oracle一致 14 des3decrypt(input, key, which=0，iv) which 0或1 所有整数，除0和1，其他整数与0效果一致 与oracle一致 15 des3decrypt(input, key, which=0，iv) iv 长度为[8, max]字节 长度为[0, max]字节 与oracle一致 2.5 安全性 2.5.1 权限控制 不涉及。本特性仅修改原有函数的输入、输出，未修改原权限检查机制。\n2.5.2 审计 不涉及。本特性仅修改原有函数的输入、输出，未修改原审计机制。\n2.6 影响范围 2.6.1 对已有UDT,UDF, ECPG的影响 2.6.2 对系统函数的影响 pgcrypto插件可用版本由[1.2]变更为[1.2, 2.0]，2.0版本与1.2的主要区别是几个内置函数的入参约束、输出不同。\n2.6.3 对系统CATALOG的影响 2.6.4 对xlog日志格式、数据格式的影响 2.6.5 与其他功能交互时的行为表现 2.6.6 版本兼容性 pgcrypto插件可用版本由[1.2]变更为[1.2, 2.0]，2.0版本与1.2的主要区别是几个内置函数的入参约束、输出不同。\n2.7 指标相关 2.7.1 关键资源指标 不涉及\n2.7.2 系统性指标 不涉及\n2.7.3 性能指标 不涉及\n2.8 测试建议 本需求的目标是：可解密由oracle加密的数据，加密新数据时与oracle加密结果一致。因此，需对比oracle一起测试。\ntapd上，本需求的测试用例可供参考： https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007197\n2.8 其他说明 无\n遗留问题 前向兼容：通过插件版本实现兼容（暂无问题） 加密插件：将dbms_obfuscation_toolkit包放在pgcrypto插件中 兼容范围： ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/1-requirement-oracle-crypto-func/","summary":"\u003ch1 id=\"1-简介\"\u003e1 简介\u003c/h1\u003e\n\u003ch2 id=\"11-目的\"\u003e1.1 目的\u003c/h2\u003e\n\u003cp\u003e早期版本的oracle提供一个包含多个加密函数的包，用户可通过SQL语法调用加密函数，实现数据加密功能。本文主要介绍以下几点：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eoracle加密包的功能与使用方法\u003c/li\u003e\n\u003cli\u003evastbase实现oracle加密包\u003c/li\u003e\n\u003cli\u003evastbase加密包的功能与使用方法\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e本文档可指导开发者、测试者熟悉vastbase加密包特性的功能场景。\u003c/p\u003e\n\u003cp\u003e本文档的内容已被上传至tapd，tapd上，排版更好看，测试用例更方便复制。建议直接从tapd上查看本文档原文： \u003ca href=\"https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007194\"\u003ehttps://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007194\u003c/a\u003e\u003c/p\u003e\n\u003ch2 id=\"12-适用范围\"\u003e1.2 适用范围\u003c/h2\u003e\n\u003cp\u003evastbase 3.0.8及之后版本。\u003c/p\u003e\n\u003ch2 id=\"13-术语定义首字母缩写词和缩略语\"\u003e1.3 术语定义、首字母缩写词和缩略语\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eDES：Data Encryption Standard，数据加密标准，一种早期通用的加密算法\u003c/li\u003e\n\u003cli\u003e3DES：Triple DES，基于DES演进的一种早期通用的加密算法\u003c/li\u003e\n\u003cli\u003eMD5：Message-Digest Algorithm，一种早期通用的数据摘要算法\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"13-参考资料\"\u003e1.3 参考资料\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eoracle dbms_obfuscation_toolkit 函数介绍：\u003ca href=\"https://docs.oracle.com/cd/A97630_01/appdev.920/a96590/adgsec04.htm\"\u003ehttps://docs.oracle.com/cd/A97630_01/appdev.920/a96590/adgsec04.htm\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eoracle dbms_obfuscation_toolkit 函数参数：\u003ca href=\"https://docs.oracle.com/cd/B10500_01/appdev.920/a96612/d_obtoo2.htm\"\u003ehttps://docs.oracle.com/cd/B10500_01/appdev.920/a96612/d_obtoo2.htm\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003etapd上，本需求文档： \u003ca href=\"https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007194\"\u003ehttps://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007194\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003etapd上，本需求的测试用例： \u003ca href=\"https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007197\"\u003ehttps://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007197\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-支持oracle加密插件dbms_obfuscation_toolkit\"\u003e2 支持oracle加密插件dbms_obfuscation_toolkit\u003c/h1\u003e\n\u003ch2 id=\"21-功能简述\"\u003e2.1 功能简述\u003c/h2\u003e\n\u003cp\u003e早期版本oracle提供7个内置加密函数。早在4年或更早之前的旧版本vastbase中，也提供7个与oracle一致的加密函数，这7个函数，函数名、函数入参与oracle一致，但是，6个函数输出、15个函数参数约束与oracle不一致，本特性将重构这些加密函数，确保函数的输出、约束等与oracle一致。\u003c/p\u003e\n\u003ch3 id=\"一基础知识\"\u003e一、基础知识\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e加密的原理\u003cbr\u003e\n加密算法有很多种，不同场景中，适合的加密算法类型不同。对存储数据加密，通常采用对称密码算法，此处主要介绍对称密码算法：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e加密原理：输入1个明文，输入1个密钥，对明文和密钥进行一些可逆的运算（比如异或，代换），可得到1个密文。密钥通常是随机生成的\u003c/li\u003e\n\u003cli\u003e加密算法：DES算法，发布于1977年，已确定为不安全加密算法。3DES算法，调用3次DES算法，生成3个密钥，安全性与DES差别不大，也属于不安全的加密算法。AES算法，发布于2001年，通用的国际标准，替代不安全的DES算法\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e数据库加密函数\u003cbr\u003e\n几乎所有数据库，都提供内置加密函数，让用户通过SQL语句调用。最典型的场景如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 假设，数据库提供函数encrypt(明文，密钥，加密算法)，输出为密文\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 用户想表\u0026#39;t1\u0026#39;中存储数据\u0026#39;shenkun\u0026#39;，则存储的语法如下：（用户自己保管密钥）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;shenkun\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;一串随机的密钥\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aes\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"二oracle加密包\"\u003e二、Oracle加密包\u003c/h3\u003e\n\u003cp\u003e早期版本的oracle中，包含1个名为dbms_obfuscation_toolkit的包，提供7个函数，主要实现加密、解密等功能：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e版本信息：oracle 8i版本开始提供，oracle 10g版本开始不被推荐使用，由dbms_crypto代替，oracle 21c版本正式移除\u003c/li\u003e\n\u003cli\u003e函数列表：\n\u003cul\u003e\n\u003cli\u003e生成随机数：desgetkey(seed) -\u0026gt; key\u003c/li\u003e\n\u003cli\u003e加密：desencrypt(input, key) -\u0026gt; encrypted_data\u003c/li\u003e\n\u003cli\u003e解密：descdecrypt(input, key) -\u0026gt; decrypted_data\u003c/li\u003e\n\u003cli\u003e生成随机数：des3getkey(which=\u0026gt;0, seed) -\u0026gt; key\u003c/li\u003e\n\u003cli\u003e加密：des3encrypt(input, key, which=\u0026gt;0, iv=\u0026gt;012345678abcdef) -\u0026gt; encrypted_data\u003c/li\u003e\n\u003cli\u003e解密：des3decrypt(input, key, which=\u0026gt;0, iv=\u0026gt;012345678abcdef) -\u0026gt; decrypted_data\u003c/li\u003e\n\u003cli\u003e哈希：md5(input) -\u0026gt; checksum\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e函数参数：函数参数有2种数据类型：varchar2, raw。与raw类型相比，如果是varchar2类型，参数名需加上_string后缀。比如，raw类型的入参名为input，则varcha2类型入参名为input_string\u003c/li\u003e\n\u003cli\u003e函数限制：\n\u003cul\u003e\n\u003cli\u003edesgetkey：seed长度最短为80字节\u003c/li\u003e\n\u003cli\u003edesencrypt：input长度是8字节的整数倍；key最短为8字节，超过8字节的部分被丢弃\u003c/li\u003e\n\u003cli\u003edescdecrypt：input长度是8字节的整数倍；key最短为8字节，超过8字节的部分被丢弃\u003c/li\u003e\n\u003cli\u003edes3getkey: seed长度最短为80字节\u003c/li\u003e\n\u003cli\u003edes3encrypt：input长度是8字节的整数倍；which为0时，key最短为16字节，超过16字节的部分被丢弃；which为1时，key最短为24字节，超过24字节的部分被丢弃\u003c/li\u003e\n\u003cli\u003edes3dencrypt：input长度是8字节的整数倍；which为0时，key最短为16字节，超过16字节的部分被丢弃；which为1时，key最短为24字节，超过24字节的部分被丢弃\u003c/li\u003e\n\u003cli\u003emd5：无\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e参考文档\n\u003cul\u003e\n\u003cli\u003e函数介绍：函数背景、注意事项等：\u003ca href=\"https://docs.oracle.com/cd/A97630_01/appdev.920/a96590/adgsec04.htm\"\u003ehttps://docs.oracle.com/cd/A97630_01/appdev.920/a96590/adgsec04.htm\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e函数参数：参数类型、调用示例等：\u003ca href=\"https://docs.oracle.com/cd/B10500_01/appdev.920/a96612/d_obtoo2.htm\"\u003ehttps://docs.oracle.com/cd/B10500_01/appdev.920/a96612/d_obtoo2.htm\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e以下是上述函数的调用示例：\u003c/p\u003e","title":"海量 1 需求 oracle加密函数"},{"content":" 1 概述 1.1 数据结构 数组 链表 二叉树 树 栈 队列 图 1.2 算法 问题 1.2 解法 2 数组 2.1 所有0移动到数组的末尾 2.2 移除数组指定元素 2.3 移除数组重复元素 2.4 移除数组数量大于2的元素 2.5 数组重复元素排序 2.6 第K个最大数 2.7 最大的K个数 2.8 两数之和 参考 1 概述 1.1 数据结构 数组 排序 滑动窗口 去重 碰撞指针：回文串 链表 反转链表 二叉树 递归 树 b树：一个节点存多个值 降低树高度，结和IO机制，降低IO次数 b+树：只有叶子节点存数据 高效：中间节点不存数据，可存更多节点 稳定：查找次数一致 有序：叶子节点组成链表，方便批量查询 b-link树：节点指向右兄弟；每个节点存储High-key 并发：根据High-key，并发场景下，可判断节点是否发生分裂，无需加锁 栈 队列 图 1.2 算法 动态规划\n功能：用表记录所有结果，避免重复计算（斐波那契、最长公共子序列） 问题 回溯：枚举 + 剪枝\n分治\n贪心\n1.2 解法 数组\n移动0：数组中，将0移到数组末尾\n冒泡排序：把0冒泡到末尾（不改变元素顺序）\nfor (i = 0; i \u0026lt; arrsz; i++) { if (arr[i] == 0) { ... } } 移除元素：数组中，将指定val移除，返回移除后的数组\n冒泡排序：把val冒泡到末尾\n首尾双指针：把val与末尾交换（可改变元素顺序）\nfor (i = 0; i \u0026lt; arrsz; i++) { if (arr[i] == val) { ... } } 删除重复元素：有序数组中，删除重复项\n双指针：start和end分别指向重复元素首末，然后start = end + 1\nwhile (start \u0026lt; arrsz \u0026amp;\u0026amp; end \u0026lt; arrsz) { while (end \u0026lt; arrsz \u0026amp;\u0026amp; arr[end] == arr[start]) { end++; } arr[newsz++] = arr[start]; start = end; } 颜色分类：数组中，仅包含0,1,2，排序\n冒泡排序：把大数冒泡到后面\nfor (i = 0; i \u0026lt; arrsz - 1; i++) { if (arr[i] \u0026gt; arr[i + 1]) { SWAP(arr, i, i + 1); } } bubble_sort(arr, arrsz - 1); 双指针p0,p1,pcur：覆盖 + 补偿 （仅扫描一次）：首先，p0与p1扩展空间，然后交换\n0 1 2 0 0 0 1 cur : p0++, p1++, swap(p0, p1), swap(pcur, p0) 0 (先扩展p0) 1 (再扩展p1，最后交换) 第K个最大数：数组中，第K个最大数\n快速排序 堆排序：建堆，删除k-1次堆顶 两数之和：有序数组中，查找和为target的2个数\n二分查找 首尾双指针 哈希表 回文字符串：字符串中，排除空格特殊字符和大小写，正读和反读一样\n首尾双指针 2 数组 2.1 所有0移动到数组的末尾 https://leetcode.cn/problems/move-zeroes/\nvoid move_zero(int *arr, int arrsz) // 冒泡排序 { int tmp; int i; if (arrsz \u0026lt;= 1) { return; } for (i = 0; i \u0026lt; arrsz - 1; i++) { if (arr[i] == 0) { tmp = arr[i]; arr[i] = arr[i + 1]; arr[i + 1] = tmp; } } arrsz--; move_zero(arr, arrsz); } 2.2 移除数组指定元素 int remove_num(int *arr, int arrsz, int num) // 双指针，冒泡排序 { int left; int right; int cnt = 0; if (arrsz \u0026lt; 1) { return 0; } for (left = 0, right = arrsz - 1; left \u0026lt;= right; left++) { if (arr[left] == num) { cnt++; for (; arr[right] == num \u0026amp;\u0026amp; right \u0026gt; left; cnt++, right--){} if (left \u0026lt; right) { SWAP(arr, left, right); right--; } } } return arrsz - cnt; } 2.3 移除数组重复元素 int remove_dumpicate(int *arr, int arrsz) // 双指针 { int start; int end; int newsz = 0; if (arrsz \u0026lt;= 1) { return arrsz; } start = 0; end = start; while (start \u0026lt; arrsz \u0026amp;\u0026amp; end \u0026lt; arrsz) { while (end \u0026lt; arrsz \u0026amp;\u0026amp; arr[end] == arr[start]) { end++; } arr[newsz++] = arr[start]; start = end; } return newsz; } 2.4 移除数组数量大于2的元素 int remove_dumpicate2(int *arr, int arrsz) // 双指针 { int start; int end; int newsz = 0; if (arrsz \u0026lt;= 1) { return arrsz; } start = 0; end = start; while (start \u0026lt; arrsz \u0026amp;\u0026amp; end \u0026lt; arrsz) { while (end \u0026lt; arrsz \u0026amp;\u0026amp; arr[end] == arr[start]) { end++; } arr[newsz++] = arr[start]; if (end - start \u0026gt;= 2) { arr[newsz++] = arr[start]; } start = end; } return newsz; } 2.5 数组重复元素排序 void bubble_sort(int *arr, int arrsz) // 冒泡排序 { if (arrsz \u0026lt;= 1) { return; } int i; for (i = 0; i \u0026lt; arrsz - 1; i++) { if (arr[i] \u0026gt; arr[i + 1]) { SWAP(arr, i, i + 1); } } bubble_sort(arr, arrsz - 1); } void bubble_sort1(int *arr, int arrsz) // 双指针，覆盖 + 补偿 { if (arrsz \u0026lt;= 1) { return; } int p0 = 0; int p1 = 0; int i; /* * 0 0 1 1 2 2 1 0 0 1 * - * + * ^ */ for (i = 0; i \u0026lt; arrsz - 1; i++) { if (arr[i] == 0) { } if (arr[i] \u0026gt; arr[i + 1]) { SWAP(arr, i, i + 1); } } bubble_sort(arr, arrsz - 1); } 2.6 第K个最大数 int max_k(int *arr, int arrsz, int k) // 第k个最大数：构造大顶堆，删除k-1次栈顶 { #define ROOT_NODE(child) (int)(((child) - 1) / 2) int *heap = arr; int heapsz; int father; int child; if (k \u0026gt; arrsz) { return -1; } for (heapsz = 1; heapsz \u0026lt;= arrsz; heapsz++) { // 自底向上，构造大顶堆 for (child = heapsz - 1, father = ROOT_NODE(child); child != 0; child = father, father = ROOT_NODE(child)) { if (heap[father] \u0026lt; heap[child]) { SWAP(heap, child, father); } } } heapsz--; #define LEFT_NODE(father) (2 * (father) + 1) #define RIGHT_NODE(father) (2 * (father) + 2) int left; int right; int max; int tarheapsz = arrsz - k + 1; while (heapsz \u0026gt; tarheapsz) { // 交换首尾，自顶向下，重构大顶堆 prt(heap, heapsz); SWAP(heap, 0, heapsz - 1); heapsz--; for (father = 0, left = LEFT_NODE(father), right = RIGHT_NODE(father); father \u0026lt; heapsz; left = LEFT_NODE(father), right = RIGHT_NODE(father)) { if (left \u0026gt;= heapsz) { break; } max = left \u0026lt; heapsz \u0026amp;\u0026amp; right \u0026lt; heapsz ? (heap[right] \u0026gt; heap[left] ? right : left) : left; if (heap[father] \u0026lt; heap[max]) { SWAP(heap, father, max); father = max; continue; } break; } } return heap[0]; } 2.7 最大的K个数 维护小顶堆 if num \u0026gt; heap[0] : heap[0] = num, shift(heap) 2.8 两数之和 参考 https://leetcode.cn/circle/article/QxxqIF/ ","permalink":"https://my-blog.j8465383071.workers.dev/posts/algorithm/1-summary/","summary":"\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-%E6%A6%82%E8%BF%B0\"\u003e1 概述\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-1-%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84\"\u003e1.1 数据结构\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E6%95%B0%E7%BB%84\"\u003e数组\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E9%93%BE%E8%A1%A8\"\u003e链表\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BA%8C%E5%8F%89%E6%A0%91\"\u003e二叉树\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E6%A0%91\"\u003e树\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E6%A0%88\"\u003e栈\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E9%98%9F%E5%88%97\"\u003e队列\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%9B%BE\"\u003e图\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-%E7%AE%97%E6%B3%95\"\u003e1.2 算法\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E9%97%AE%E9%A2%98\"\u003e问题\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-%E8%A7%A3%E6%B3%95\"\u003e1.2 解法\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-%E6%95%B0%E7%BB%84\"\u003e2 数组\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#2-1-%E6%89%80%E6%9C%890%E7%A7%BB%E5%8A%A8%E5%88%B0%E6%95%B0%E7%BB%84%E7%9A%84%E6%9C%AB%E5%B0%BE\"\u003e2.1 所有0移动到数组的末尾\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-2-%E7%A7%BB%E9%99%A4%E6%95%B0%E7%BB%84%E6%8C%87%E5%AE%9A%E5%85%83%E7%B4%A0\"\u003e2.2 移除数组指定元素\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-3-%E7%A7%BB%E9%99%A4%E6%95%B0%E7%BB%84%E9%87%8D%E5%A4%8D%E5%85%83%E7%B4%A0\"\u003e2.3 移除数组重复元素\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-4-%E7%A7%BB%E9%99%A4%E6%95%B0%E7%BB%84%E6%95%B0%E9%87%8F%E5%A4%A7%E4%BA%8E2%E7%9A%84%E5%85%83%E7%B4%A0\"\u003e2.4 移除数组数量大于2的元素\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-5-%E6%95%B0%E7%BB%84%E9%87%8D%E5%A4%8D%E5%85%83%E7%B4%A0%E6%8E%92%E5%BA%8F\"\u003e2.5 数组重复元素排序\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-6-%E7%AC%ACK%E4%B8%AA%E6%9C%80%E5%A4%A7%E6%95%B0\"\u003e2.6 第K个最大数\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-7-%E6%9C%80%E5%A4%A7%E7%9A%84K%E4%B8%AA%E6%95%B0\"\u003e2.7 最大的K个数\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-8-%E4%B8%A4%E6%95%B0%E4%B9%8B%E5%92%8C\"\u003e2.8 两数之和\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%8F%82%E8%80%83\"\u003e参考\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"1-概述\"\u003e1 概述\u003c/h1\u003e\n\u003ch2 id=\"11-数据结构\"\u003e1.1 数据结构\u003c/h2\u003e\n\u003ch3 id=\"数组\"\u003e数组\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e排序\u003c/li\u003e\n\u003cli\u003e滑动窗口\u003c/li\u003e\n\u003cli\u003e去重\u003c/li\u003e\n\u003cli\u003e碰撞指针：回文串\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"链表\"\u003e链表\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e反转链表\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"二叉树\"\u003e二叉树\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e递归\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"树\"\u003e树\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eb树：一个节点存多个值\n\u003cul\u003e\n\u003cli\u003e降低树高度，结和IO机制，降低IO次数\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eb+树：只有叶子节点存数据\n\u003cul\u003e\n\u003cli\u003e高效：中间节点不存数据，可存更多节点\u003c/li\u003e\n\u003cli\u003e稳定：查找次数一致\u003c/li\u003e\n\u003cli\u003e有序：叶子节点组成链表，方便批量查询\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eb-link树：节点指向右兄弟；每个节点存储High-key\n\u003cul\u003e\n\u003cli\u003e并发：根据High-key，并发场景下，可判断节点是否发生分裂，无需加锁\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"栈\"\u003e栈\u003c/h3\u003e\n\u003ch3 id=\"队列\"\u003e队列\u003c/h3\u003e\n\u003ch3 id=\"图\"\u003e图\u003c/h3\u003e\n\u003ch2 id=\"12-算法\"\u003e1.2 算法\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e动态规划\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e功能：用表记录所有结果，避免重复计算（斐波那契、最长公共子序列）\u003c/li\u003e\n\u003cli\u003e\n\u003ch2 id=\"问题\"\u003e问题\u003c/h2\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e回溯：枚举 + 剪枝\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e分治\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e贪心\u003c/p\u003e","title":"数据结构与算法 1 总结"},{"content":"摘要\n本文介绍介绍如何在2种个人PC中，使用源码安装PostgreSQL，包括：\n在Windows操作系统中，如何基于VwWare虚拟机，搭建Linux环境。并在Linux中，通过postgreSQL源码进行编译安装。 在MacOS操作系统中，如何使用云服务器中的Linux操作系统，搭建postgreSQL源码编译与学习环境。 目录\n1 在Windows中安装PostgreSQL 1.1 目的 1.2 准备 1.3 编译源码 1.4 配置快捷命令 2 在MacOS中安装PostgreSQL 2.1 问题 2.2 调研云服务商 2.3 选择云服务器 2.4 配置云服务器 2.5 下载postgreSQL源码 1 在Windows中安装PostgreSQL 1.1 目的 通过postgreSQL源码进行编译安装，主要目的是：\n方便通过源码调试跟踪 直接修改以增加调试信息或新功能 1.2 准备 首先，介绍如何准备centOS虚拟机，并安装git、VSCode、gdb等工具\n已有windows 10/11 x86物理机\nwindow 10中，安装vmware\nvmware中，安装centOS虚拟机\nhttp://mirrors.huaweicloud.com/centos/8.4.2105/isos/x86_64/\ncentOS中，安装git，以及中文输入法\ncentOS中，安装VSCode\nhttps://code.visualstudio.com/docs/setup/linux#_rhel-fedora-and-centos-based-distributions\ncentOS中，安装PostgresSQL依赖的第三方开源软件\nsudo yum install -y readline readline-devel openssl openssl-devel zlib zlib-devel # 但是，部分linux可能会裁剪应用，因此可能需要安装如下软件 sudo yum install -y bison bison-devel flex flex-devel #[参考](https://blog.csdn.net/Linjingke32/article/details/80393576) 安装调试工具\nsudo yum install gdb 1.3 编译源码 接下来，介绍如何在centOS中，下载、配置、编译、启动postgreSQL\n准备源码目录，配置环境变量\nmkdir ~/pg_9.2.4 cd ~/pg_9.2.4 下载PostgresSQL 9.2.4源码，并解压\nwget https://ftp.postgresql.org/pub/source/v9.2.4/postgresql-9.2.4.tar.gz # 备用方法：https://www.postgresql.org/ftp/source/v9.2.4/ tar -zxvf postgresql-9.2.4.tar.gz # 备注：建议初始化为git仓库，并上传到云端备份，以防因误改代码至代码无法编译 准备环境变量\necho \u0026#39;export BUILD_ROOT=`pwd`\u0026#39; \u0026gt; pgenv echo \u0026#39;export PG_HOME=$BUILD_ROOT/install\u0026#39; \u0026gt;\u0026gt; pgenv echo \u0026#39;export PATH=\u0026#34;$PG_HOME/bin:$PATH\u0026#34;\u0026#39; \u0026gt;\u0026gt; pgenv source pgenv 编译源码\ncd postgresql-9.2.4 ./configure --prefix=$PG_HOME --enable-debug make install -sj # debian ./configure --prefix=$PG_HOME --enable-debug --without-readline --without-zlib 生成日志文件并启动数据库服务器\nmkdir $PG_HOME/log \u0026amp;\u0026amp; touch $PG_HOME/log/server.log initdb -D $PG_HOME/data pg_ctl -D $PG_HOME/data/ -l $PG_HOME/log/server.log start ps ux | grep bin/postgres 连接数据库\npsql -h localhost -p 5432 -d postgres windows cmd 查找局域网ip for /L %i IN (1,1,254) DO ping -w 2 -n 1 192.168.137.%i shell pageup补齐 https://blog.csdn.net/enzesheng/article/details/42319117 vim 右键粘贴 https://www.shuzhiduo.com/A/o75NZEl95W/ 安装旧版本软件 apt search xxx 示例： apt install flex-old # pg 各版本源码 https://www.postgresql.org/ftp/source/ # vscode 插件 https://marketplace.visualstudio.com/VSCode apt install libreadline-dev\n1.4 配置快捷命令 alias pmake=\u0026#39;make -sj 16 \u0026amp;\u0026amp; make install -sj\u0026#39; alias pinit=\u0026#39;rm -rf $PG_HOME/data \u0026amp;\u0026amp; initdb -D $PG_HOME/data\u0026#39; alias pstart=\u0026#39;pg_ctl start -D $PG_HOME/data -l logfile\u0026#39; alias pstop=\u0026#39;pg_ctl stop -D $PG_HOME/data -l logfile\u0026#39; 2 在MacOS中安装PostgreSQL 2.1 问题 在macOS中，下载并配置postgreSQL依赖的开源组件时，频繁碰壁。遂决定租一台云服务主机，编译并运行postgreSQL。\n2.2 调研云服务商 国内运服务商众多，优惠条件各不相同。在简单调查后，选择价格较低者。\n云服务商 0元试用 条件 最低配置价格 阿里云 有 仅新用户有一次机会 1core 2g 24/3mon 华为云 有 每日9.30开抢 腾讯云 有 仅新用户有一次机会 2core 2g 6.6/mon 天翼云 无 低价秒杀 1core 2g 33/year 1core 2g 122/year 金山云 无 无 2core 4g 576/year 移动云 有 仅新用户有一次机会 2core 4g 28/mon 百度云 无 无 1core 1g 34/mon 浪潮云 无 无 垃圾 2.3 选择云服务器 选择购买低价阿里云云服务器\n在安装操作系统时，选择centOS 7.6\n更改或设置root密码，用于ssh登录\n在个人电脑上，使用命令行连接远程主机\nssh root@ip 2.4 配置云服务器 安装git\nyum install git 创建新用户\nuseradd lorand passwd lorand 在个人电脑上，进行测试：\nssh lorand@{IP} 安装code-server\n忽略两次失败尝试：\n# fail https://cloud.tencent.com/developer/article/1655175 # fail git clone https://gitee.com/mirrors/code-server.git https://gitee.com/mirrors/code-server?_from=gitee_search curl -fsSL https://code-server.dev/install.sh | sh 接下来，是成功尝试\n参考：https://zhuanlan.zhihu.com/p/493434939\n首先，将安装包下载到个人电脑\nhttps://link.zhihu.com/?target=https%3A//github.com/coder/code-server/releases/download/v4.2.0/code-server_4.2.0_amd64.deb\n然后，将安装包上传到云服务器：\nhttps://github.com/coder/code-server/releases scp ./code-server_4.2.0_amd64.deb lorand@182.92.66.91:~ 最后，在云服务器上，使用root角色进行安装\nsu yum install dpkg dpkg -i code-server_4.2.0_amd64.deb exit 运行code-server\n配置端口号\nvi ~/.config/code-server/config.yaml # bind-addr: 0.0.0.0:3000 运行\ncode-server --port 3000 --host 0.0.0.0 --auth password code-server 或 nohup code-server \u0026amp; 在个人电脑上，使用浏览器，连接code-server\n182.92.66.91：3000 但是，由于云服务器有防火墙，到这步应该连接失败。还需要最后一步。\n配置云服务防火墙\n在阿里云控制台，”网络与安全“-\u0026gt;”安全组”中，新增防火墙规则：目的端口：3000，允许连接\n最终效果：\n2.5 下载postgreSQL源码 参考另一篇编译安装postgreSQL的博客，本部分不再赘述。\nsu yum install -y readline readline-devel openssl openssl-devel zlib zlib-devel bison bison-devel flex flex-devel exit git clone https://gitee.com/lorand/postgresql_9.2.4.git echo \u0026#39;export BUILD_ROOT=`pwd`\u0026#39; \u0026gt; pgenv echo \u0026#39;export PG_HOME=$BUILD_ROOT/install\u0026#39; \u0026gt;\u0026gt; pgenv echo \u0026#39;export PATH=\u0026#34;$PG_HOME/bin:$PATH\u0026#34;\u0026#39; \u0026gt;\u0026gt; pgenv source pgenv cd postgresql_9.2.4 ./configure --prefix=$PG_HOME --enable-debug make install -sj mkdir $PG_HOME/log \u0026amp;\u0026amp; touch $PG_HOME/log/server.log initdb -D $PG_HOME/data pg_ctl -D $PG_HOME/data/ -l $PG_HOME/log/server.log start ps ux | grep bin/postgres psql -d postgres # CREATE USER pglorand WITH PASSWORD \u0026#39;gauss@123\u0026#39;; # 在阿里云控制台，新增安全组：目的端口：5432 vi pg_hba.conf # host all all 0.0.0.0/0 trust vi postgres.conf # listen_addresses = ’*‘ psql -d postgres -U pglorand 另外，还可在个人电脑上，连接远程postgreSQL服务器，效果：\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/1-1-install-postgresql/","summary":"\u003cp\u003e\u003cstrong\u003e摘要\u003c/strong\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e本文介绍介绍如何在2种个人PC中，使用源码安装PostgreSQL，包括：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e在Windows操作系统中，如何基于VwWare虚拟机，搭建Linux环境。并在Linux中，通过postgreSQL源码进行编译安装。\u003c/li\u003e\n\u003cli\u003e在MacOS操作系统中，如何使用云服务器中的Linux操作系统，搭建postgreSQL源码编译与学习环境。\u003c/li\u003e\n\u003c/ul\u003e\u003c/blockquote\u003e\n\u003cp\u003e\u003cstrong\u003e目录\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-%E5%9C%A8Windows%E4%B8%AD%E5%AE%89%E8%A3%85PostgreSQL\"\u003e1 在Windows中安装PostgreSQL\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-1-%E7%9B%AE%E7%9A%84\"\u003e1.1 目的\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-%E5%87%86%E5%A4%87\"\u003e1.2 准备\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-3-%E7%BC%96%E8%AF%91%E6%BA%90%E7%A0%81\"\u003e1.3 编译源码\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-4-%E9%85%8D%E7%BD%AE%E5%BF%AB%E6%8D%B7%E5%91%BD%E4%BB%A4\"\u003e1.4 配置快捷命令\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-%E5%9C%A8MacOS%E4%B8%AD%E5%AE%89%E8%A3%85PostgreSQL\"\u003e2 在MacOS中安装PostgreSQL\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#2-1-%E9%97%AE%E9%A2%98\"\u003e2.1 问题\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-2-%E8%B0%83%E7%A0%94%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%95%86\"\u003e2.2 调研云服务商\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-3-%E9%80%89%E6%8B%A9%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8\"\u003e2.3 选择云服务器\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-4-%E9%85%8D%E7%BD%AE%E4%BA%91%E6%9C%8D%E5%8A%A1%E5%99%A8\"\u003e2.4 配置云服务器\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-5-%E4%B8%8B%E8%BD%BDpostgreSQL%E6%BA%90%E7%A0%81\"\u003e2.5 下载postgreSQL源码\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"1-在windows中安装postgresql\"\u003e1 在Windows中安装PostgreSQL\u003c/h1\u003e\n\u003ch2 id=\"11-目的\"\u003e1.1 目的\u003c/h2\u003e\n\u003cp\u003e通过postgreSQL源码进行编译安装，主要目的是：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e方便通过源码调试跟踪\u003c/li\u003e\n\u003cli\u003e直接修改以增加调试信息或新功能\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"12-准备\"\u003e1.2 准备\u003c/h2\u003e\n\u003cp\u003e首先，介绍如何准备centOS虚拟机，并安装git、VSCode、gdb等工具\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e已有windows 10/11 x86物理机\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ewindow 10中，安装vmware\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003evmware中，安装centOS虚拟机\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003ca href=\"http://mirrors.huaweicloud.com/centos/8.4.2105/isos/x86_64/\"\u003ehttp://mirrors.huaweicloud.com/centos/8.4.2105/isos/x86_64/\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ecentOS中，安装git，以及中文输入法\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ecentOS中，安装VSCode\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003ca href=\"https://code.visualstudio.com/docs/setup/linux#_rhel-fedora-and-centos-based-distributions\"\u003ehttps://code.visualstudio.com/docs/setup/linux#_rhel-fedora-and-centos-based-distributions\u003c/a\u003e\u003c/p\u003e\u003c/blockquote\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ecentOS中，安装PostgresSQL依赖的第三方开源软件\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo yum install -y readline readline-devel openssl openssl-devel zlib zlib-devel\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 但是，部分linux可能会裁剪应用，因此可能需要安装如下软件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo yum install -y bison bison-devel flex flex-devel\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#[参考](https://blog.csdn.net/Linjingke32/article/details/80393576)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e安装调试工具\u003c/p\u003e","title":"PostgreSQL 1-1 源码安装 (linux / macos)"},{"content":"1 密码学综述 本文主要总结常见的密码算法与协议，并不详细介绍原理\n密码算法 对称密码算法 非对称密码算法 哈希算法 完整性校验算法 其他算法 随机数生成算法 密钥派生算法 2 密码算法 2.1 对称加密算法 对称加密算法的基本原理是，输入明文、密钥，对明文进行分组，对每组明文进行多轮线性、非线性运算，比如异或、代换等，得到密文。\n常见的对称加密算法如下：\n算法 发布时间 分组长度 密钥长度 算法 DES 1977 64 64 16 x 置换（E扩展、异或、代换、P置换） 3DES - - - - IDEA 1990 - - - AES 2001 128 128/192/256 10/12/14 x 矩阵运算(字节代换、行移位、列混合、异或) SM4 2012 128 128 32 x 分组运算（异或、代换、移位） SM1 - 128 128 未公开 SM7 - 128 128 未公开 在实现加密的过程中，还有几个基础知识：\n密钥扩展：加密时，会迭代很多轮，每一轮都用1个轮密钥。1个原始密钥，扩展为多个的轮密钥。 加密模式：一个原始明文，分为多个明文组，组与组之间的组合方式如下： 模式 中文 描述 ECB 电子密码本 不同的明文块，用相同的密钥 CBC 密码分组链接 上1密文块，与下一明文块异或 CTR 计数器模式 密钥加密计数器生成密钥流，密文块与密钥流异或 CFB 密码反馈模式 - OFB 输出反馈模式 与CFB类似 常见算法的具体实现原理如下：\n一、DES\n密钥扩展：16轮 * 48 bit密钥 （每轮生成1个轮密钥） 转换：64 -\u0026gt; 56 bit，忽略校验位 移位 合并：28 bit 与 28 bit合并 代换： 加密：16轮 置换：前面的bit后后面的bit置换 异或 代换 二、AES\n密钥扩展：128 / 192 / 256 bit 分别对应 10 / 12 / 14 轮 * 32 bit 密钥（每轮生成1个轮密钥） 移位：左移 代换：S盒代换 异或：与固定基数异或 加密：10 / 12 / 14 轮 （与密钥长度有关） 构造1个矩阵：4 x 4 字节 = 4 * 4 * 8 bit = 128 bit 代换：字节代换 移位：行移位 混合：列混合 （各分组拼成矩阵，矩阵相乘） 异或：轮密钥加 解密：轮密钥加、逆列混合、逆行移位、逆字节代换 三、SM4\n密钥扩展：32轮 * 32 bit 密钥 （每轮生成1个轮密钥） 分组：分为4组 * 32bit 异或：与固定基数异或 代换：S盒代换 移位：移位并与其他分组异或 明文：128 bit，分为4组 * 32bit 加密：32轮 -\u0026gt; 分为4组 * 32bit 异或：轮密钥异或 代换：S盒代换 移位：行移位并与自己异或 解密： 2.2 非对称密码算法 原理：基于数学问题的难解性，给定输入，计算输出容易；给定输出，计算输入困难。 4个常见算法 算法 安全密钥长度 数论基础 安全性基础 RSA 2048 bit 欧拉定理 整数分解问题的难解性 ElGamal 1024 bit 离散对数 有限域上，离散对数问题的难解性 ECC 160 bit 离散对数 椭圆曲线上，离散对数问题的难解性 SM2 256 bit 离散对数 椭圆曲线上，离散对数问题的难解性 加密算法： RSA ElGamal ECC SM2 2.3 哈希算法 2.4 完整性校验算法 认证模式 算法 密钥长度 HMAC HMAC-MD5 128 bit HMAC HMAC-SHA1 160 HMAC HMAC-SHA256 256 HMAC SM3 256 DES CBC-MAC 64 AES CBC-MAC 128 2.5 随机数生成算法 2.6 密钥派生算法 3 密码协议 5 软件实现 5.1 openssl实现加密 一、对称加密 准备编译环境 准备开发环境：centos 7, x86\n下载openssl源码\ncentos已安装openssl，但可能是1.0或1.1版本，我想使用3.0版本，所以选择源码编译安装openssl。另外，如果更改系统原openssl版本，可能导致系统崩溃\nmkdir crypto cd crypto wget https://www.openssl.org/source/openssl-3.0.5.tar.gz 安装perl\n配置openssl的编译参数时，即下述步骤4中的./config ..命令中，需要依赖perl。（我没用过perl，直接跟着教程安装的）\nyum install -y perl-CPAN # 继续安全必须模块 perl -MCPAN -e shell # 中途有个地方，输入：local::lib # 当出现 cpan[1]\u0026gt; ，时，输入一下命令 install IPC::Cmd # 退出 exit 编译openssl源码\ntaz -zxvf openssl-3.0.5.tar.gz mkdir openssl # 存放编译出的libssl.so cd openssl-3.0.5 # 安装目录设置为当前目录的 output文件夹 ./config --prefix=`pwd`/output --openssldir=`pwd`/output shared make -sj make install -sj mv ./output ../libssl 创建源码目录\ncd .. mkdir code # 确保目录结构为： |-- crypto |-- libssl # 存放openssl的lib与include文件 |-- openssl-3.0.5 # openssl源码，用不上了 |-- code cd code touch enc.c 在enc.c中，开始写加解密代码demo\n加解密demo 加解密源码：\n#include \u0026lt;stdio.h\u0026gt; #include \u0026lt;string.h\u0026gt; /* openssl头文件 */ #include \u0026lt;openssl/evp.h\u0026gt; #include \u0026lt;openssl/rand.h\u0026gt; #include \u0026lt;openssl/err.h\u0026gt; typedef unsigned char uchar; #define ASSERT(condition) if (!(condition)) {printf(\u0026#34;error: code line: %d\\n\u0026#34;, __LINE__); exit(0);} /* 加密函数 （为考虑博客排版紧凑，不考虑代码风格） */ void encrypt(uchar *plain, int plainlen, uchar *key, uchar *iv, uchar *cipher, int *cipherlen) { int ret; /* 1 初始化内存上下文 */ EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); ASSERT(ctx != NULL); /* 2 选择加密算法，建议当函数入参传进来 */ const EVP_CIPHER *algorithm = EVP_aes_256_cbc(); /* 3 扩展密钥 */ ret = EVP_EncryptInit_ex(ctx, algorithm, NULL, key, iv); ASSERT(ret == 1); /* 4 加密明文 */ ret = EVP_EncryptUpdate(ctx, cipher, cipherlen, plain, plainlen); ASSERT(ret == 1); /* 5 填充密文，让密文长度变成分组长度的整数倍 */ int padlen; ret = EVP_EncryptFinal_ex(ctx, cipher + *cipherlen, \u0026amp;padlen); ASSERT(ret == 1); *cipherlen += padlen; /* 输出长度：密文实际长度 + 填充长度 */ EVP_CIPHER_CTX_free(ctx); } /* 解密函数 */ void decrypt(uchar *cipher, int cipherlen, uchar *key, uchar *iv, uchar *plain, int *plainlen) { int ret; /* 1 初始化内存上下文 */ EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); ASSERT(ctx != NULL); /* 2 选择加密算法 */ const EVP_CIPHER *algorithm = EVP_aes_256_cbc(); /* 3 扩展密钥 */ ret = EVP_DecryptInit_ex(ctx, algorithm, NULL, key, iv); ASSERT(ret == 1); /* 4 解密密文 */ ret = EVP_DecryptUpdate(ctx, plain, plainlen, cipher, cipherlen); ASSERT(ret == 1); /* 5 计算填充长度并清理填充 */ int padlen; ret = EVP_DecryptFinal_ex(ctx, plain + *plainlen, \u0026amp;padlen); ASSERT(ret == 1); *plainlen += padlen; /* 输出长度：解密长度 - 填充长度，此处padlen实际是个负数 */ EVP_CIPHER_CTX_free(ctx); } void print_uchar(uchar *data, int len) { printf(\u0026#34;len:%-6d data:\u0026#34;); int i; for (i = 0; i \u0026lt; len; i++) { printf(\u0026#34;%x\u0026#34;, data[i]); } printf(\u0026#34;\\n\u0026#34;); } int main() { uchar plain[37] = {0}; /* 随便设置的长度 */ uchar key[32] = {0}; uchar iv[16] = {0}; uchar cipher[64] = {0}; int cipherlen = 0; int ret; /* 随机生成 明文、密钥、IV */ ret = RAND_bytes(plain, 37); ASSERT(ret == 1); ret = RAND_bytes(key, 32); ASSERT(ret == 1); ret = RAND_bytes(iv, 16); ASSERT(ret == 1); printf(\u0026#34;-- plain, key, iv:\\n\u0026#34;); print_uchar(plain, 37); print_uchar(key, 32); print_uchar(iv, 16); /* 加密 */ encrypt(plain, 37, key, iv, cipher, \u0026amp;cipherlen); printf(\u0026#34;\\n-- output cipher:\\n\u0026#34;); print_uchar(cipher, cipherlen); /* 解密 */ uchar _plain[64] = {0}; int _plainlen = 0; decrypt(cipher, cipherlen, key, iv, _plain, \u0026amp;_plainlen); printf(\u0026#34;\\n-- output plain:\\n\u0026#34;); print_uchar(_plain, _plainlen); return 0; } 编译代码\ngcc enc.c -I../libssl/include -L../libssl/lib64 -lssl -lcrypto -o enc 运行代码\nexport LD_LIBRARY_PATH=`pwd`/../libssl/lib64:$LD_LIBRARY_PATH ./enc 以下是示例输出：\n-- plain, key, iv: len:37 data:1b172e617193d5bef358a28504f86b2ce9f820a8599982d6e7edda2b3c69b98b2e1b9d9 len:32 data:7bf1cc71b9262c0c0621956e9d4528841da3b47a48f0a0a8d63b1997586d28 len:16 data:9cc1f5648c6988d33e7b24f46223b648 -- output cipher: len:48 data:1e6fde979bf3b76e889f588a3943a9bf74eaed127e0a0ba1f27f97558b0c93f9f5d2d89202d59444f6ce6bc7d596114 -- output plain: len:37 data:1b172e617193d5bef358a28504f86b2ce9f820a8599982d6e7edda2b3c69b98b2e1b9d9 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/1-1-cryptography/","summary":"\u003ch1 id=\"1-密码学综述\"\u003e1 密码学综述\u003c/h1\u003e\n\u003cp\u003e本文主要总结常见的密码算法与协议，并不详细介绍原理\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e密码算法\n\u003cul\u003e\n\u003cli\u003e对称密码算法\u003c/li\u003e\n\u003cli\u003e非对称密码算法\u003c/li\u003e\n\u003cli\u003e哈希算法\u003c/li\u003e\n\u003cli\u003e完整性校验算法\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e其他算法\n\u003cul\u003e\n\u003cli\u003e随机数生成算法\u003c/li\u003e\n\u003cli\u003e密钥派生算法\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-密码算法\"\u003e2 密码算法\u003c/h1\u003e\n\u003ch2 id=\"21-对称加密算法\"\u003e2.1 对称加密算法\u003c/h2\u003e\n\u003cp\u003e对称加密算法的基本原理是，输入明文、密钥，对明文进行分组，对每组明文进行多轮线性、非线性运算，比如异或、代换等，得到密文。\u003cbr\u003e\n常见的对称加密算法如下：\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e算法\u003c/th\u003e\n          \u003cth\u003e发布时间\u003c/th\u003e\n          \u003cth\u003e分组长度\u003c/th\u003e\n          \u003cth\u003e密钥长度\u003c/th\u003e\n          \u003cth\u003e算法\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eDES\u003c/td\u003e\n          \u003ctd\u003e1977\u003c/td\u003e\n          \u003ctd\u003e64\u003c/td\u003e\n          \u003ctd\u003e64\u003c/td\u003e\n          \u003ctd\u003e16 x 置换（E扩展、异或、代换、P置换）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e3DES\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eIDEA\u003c/td\u003e\n          \u003ctd\u003e1990\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eAES\u003c/td\u003e\n          \u003ctd\u003e2001\u003c/td\u003e\n          \u003ctd\u003e128\u003c/td\u003e\n          \u003ctd\u003e128/192/256\u003c/td\u003e\n          \u003ctd\u003e10/12/14 x 矩阵运算(字节代换、行移位、列混合、异或)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eSM4\u003c/td\u003e\n          \u003ctd\u003e2012\u003c/td\u003e\n          \u003ctd\u003e128\u003c/td\u003e\n          \u003ctd\u003e128\u003c/td\u003e\n          \u003ctd\u003e32 x 分组运算（异或、代换、移位）\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eSM1\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e128\u003c/td\u003e\n          \u003ctd\u003e128\u003c/td\u003e\n          \u003ctd\u003e未公开\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eSM7\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e128\u003c/td\u003e\n          \u003ctd\u003e128\u003c/td\u003e\n          \u003ctd\u003e未公开\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e在实现加密的过程中，还有几个基础知识：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e密钥扩展：加密时，会迭代很多轮，每一轮都用1个轮密钥。1个原始密钥，扩展为多个的轮密钥。\u003c/li\u003e\n\u003cli\u003e加密模式：一个原始明文，分为多个明文组，组与组之间的组合方式如下：\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e模式\u003c/th\u003e\n          \u003cth\u003e中文\u003c/th\u003e\n          \u003cth\u003e描述\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eECB\u003c/td\u003e\n          \u003ctd\u003e电子密码本\u003c/td\u003e\n          \u003ctd\u003e不同的明文块，用相同的密钥\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCBC\u003c/td\u003e\n          \u003ctd\u003e密码分组链接\u003c/td\u003e\n          \u003ctd\u003e上1密文块，与下一明文块异或\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCTR\u003c/td\u003e\n          \u003ctd\u003e计数器模式\u003c/td\u003e\n          \u003ctd\u003e密钥加密计数器生成密钥流，密文块与密钥流异或\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCFB\u003c/td\u003e\n          \u003ctd\u003e密码反馈模式\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eOFB\u003c/td\u003e\n          \u003ctd\u003e输出反馈模式\u003c/td\u003e\n          \u003ctd\u003e与CFB类似\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e常见算法的具体实现原理如下：\u003c/p\u003e","title":"传统安全 1 密码学"},{"content":" 1 进程架构 1.1 进程架构 1.2 进程启动 1.3 进程通信 2 进程功能 2.1 postgres线程 1.2.1 postmaster进程 1.2.2 postgres进程 1.2.3 wal writer进程 1.2.4 background writer进程 1.2.5 checkpointer进程 1.2.6 autovacuum进程 1.2.7 statistics collector进程 1.2.8 archiver进程 1.2.9 logging collertor进程 1.3 进程通信 3 进程控制 1 进程架构 1.1 进程架构 postgresql 采用1+n+7的进程架构，包括：\n1个postmaster进程 n个postgres进程 7个辅助进程：包括： bg writer进程： checkpointer进程： walwriter进程： autovacuum进程： archiver进程： statistics collector进程： log collectoer进程： 进程架构图如下图所示：\n1.2 进程启动 先启动postmaster进程，再由poastermaster启动n+7进程。\n在postmaster主函数中，进程启动顺序如下：\nmain() # [主进程] 启动postmaster进程 PostmasterMain() pqsignal(SIGUSR1, sigusr1_handler); # 注册信号 SysLogger_Start() # [进程7] 启动log collector进程 StartupDataBase() -\u0026gt; StartupProcessMain() # 进行故障恢复 ServerLoop() BackendStartup() SysLogger_Start() # [进程n] 启动posters进程 StartCheckpointer() -\u0026gt; CheckpointerMain() # [进程2] 启动heckpointer进程 StartBackgroundWriter() -\u0026gt; BackgroundWriterMain() # [进程1] 启动bg writer进程 StartWalWriter() -\u0026gt; InitXLOGAccess() WalWriterMain() # [进程3] 启动walwriter进程 StartAutoVacLauncher() # [进程4] 启动autovacuum进程 pgstat_start() # [进程6] 启动 statistics collector进程 pgarch_start() # [进程5] 启动归档进程 maybe_start_bgworker() 1.3 进程通信 2 进程功能 本章介绍各进程的主要功能。\n2.1 postgres线程 1.2.1 postmaster进程 // 部分辅助进程启动方法 #define StartupDataBase()\tStartChildProcess(StartupProcess) #define StartBackgroundWriter() StartChildProcess(BgWriterProcess) #define StartCheckpointer()\tStartChildProcess(CheckpointerProcess) #define StartWalWriter()\tStartChildProcess(WalWriterProcess) #define StartWalReceiver()\tStartChildProcess(WalReceiverProcess) StartChildProcess() AuxiliaryProcessMain() WalWriterMain() ... // 总入口 main() // [进程1] PostmasterMain() // 主要功能：进入loop，启动辅助线程，监听应用连接 pqsignal(SIGUSR1, sigusr1_handler); // 注册wal接受进程信号量 SysLogger_Start() StartupDataBase() -\u0026gt; StartupProcessMain() // 启动进程：故障恢复 ServerLoop() BackendStartup() SysLogger_Start() StartCheckpointer() -\u0026gt; CheckpointerMain() // [进程5] 检查点进程 StartBackgroundWriter() -\u0026gt; BackgroundWriterMain() // [进程4] 数据写进程 StartWalWriter() -\u0026gt; InitXLOGAccess() WalWriterMain() // [进程3] wal写进程 StartAutoVacLauncher() // [进程6] 清理进程 pgstat_start() // [进程7] 统计信息进程 pgarch_start() // [进程8] 归档进程 maybe_start_bgworker() // 其中， sigusr1_handler(PMSIGNAL_START_WALRECEIVER) StartWalReceiver() WaitForWALToBecomeAvailable() RequestXLogStreaming() SendPostmasterSignal(PMSIGNAL_START_WALRECEIVER) 从control中，找到checkpoint位置，开始重放xlog\nStartupProcessMain() StartupXLOG() ReadControlFile() read(ControlFile) readRecoveryCommandFile() // 读取恢复控制文件recovery.conf if { } else {// 根据control中的checkpoint开始恢复 ReadCheckpointRecord(ControlFile-\u0026gt;checkPoint) RelationCacheInitFileRemove() unlink_initfile(\u0026#34;pg_internal.init\u0026#34;) MultiXactSetNextMXact() SetTransactionIdLimit() SetMultiXactIdLimit() SetCommitTsLimit() StartupReplicationSlots() StartupReorderBuffer() StartupMultiXact() StartupCommitTs() StartupReplicationOrigin() InRecovery = true } UpdateControlFile() pgstat_reset_all() CheckRequiredParameterValues() ResetUnloggedRelations() DeleteAllExportedSnapshotFiles() ProcArrayInitRecovery() StartupCLOG() StartupSUBTRANS() for (rmid \u0026lt;= RM_MAX_ID): // 启动资源管理器 RmgrTable[rmid].rm_startup() PublishStartupProcessInformation() SendPostmasterSignal(PMSIGNAL_RECOVERY_STARTED) CheckRecoveryConsistency() record = ReadRecord(checkPoint.redo) // 从检查点找到第一条xlog记录 do { /* 资源管理器redo xlog记录 */ RmgrTable[record-\u0026gt;xl_rmid].rm_redo(xlogreader) record = ReadRecord(InvalidXLogRecPtr) } while (record != NULL) for (): RmgrTable[rmid].rm_cleanup(); ShutdownWalRcv() ... TrimCLOG() TrimMultiXact() LocalSetXLogInsertAllowed() XLogReportParameters() CompleteCommitTsInitialization() WalSndWakeup() typedef struct { ... DBState state; pg_time_t time; // 上次更新control文件的时间 XLogRecPtr checkPoint; // 上次更新时的checkpoint点 XLogRecPtr prevCheckPoint; XLogRecPtr\tminRecoveryPoint; TimeLineID\tminRecoveryPointTLI; XLogRecPtr\tbackupStartPoint; XLogRecPtr\tbackupEndPoint; ... } ControlFileData; // 全部资源管理器 RmgrData RmgrTable[#include \u0026#34;access/rmgrlist.h\u0026#34;] // 9.5共20种 // 资源管理器功能 typedef RmgrData { const char *rm_name; void (*rm_redo) (XLogReaderState *record); void (*rm_desc) (StringInfo buf, XLogReaderState *record); const char *(*rm_identify) (uint8 info); void (*rm_startup) (void); void (*rm_cleanup) (void); } RmgrData; // 资源管理器类型 RM_XLOG_ID xlog_redo RM_XACT_ID xact_redo RM_SMGR_ID smgr_redo // CREATE/TRUNCATE TABLE RM_CLOG_ID clog_redo RM_DBASE_ID dbase_redo RM_TBLSPC_ID tblspc_redo RM_MULTIXACT_ID multixact_redo RM_HEAP2_ID heap2_redo // REWRITE/VACUUM/FREEZE_PAGE/VISIBLE/MULTI_INSERT/LOCK_UPDATE/NEW_CID RM_HEAP_ID heap_redo // INSERT/DELETE/UPDATE/TRUNCATE/HOT_UPDATE/CONFIRM/LOCK/INPLACE/INIT_PAGE RM_BTREE_ID btree_redo RM_HASH_ID hash_redo RM_GIN_ID gin_redo RM_GIST_ID gist_redo RM_SEQ_ID seq_redo ... // xlog插入方法 XLogBeginInsert() /* 检查受否在故障恢复 */ XLogRegisterData(data, datasz) /* */ XLogRecPtr XLogInsert(RmgrId rmid, uint8 info) XLogFlush(XLogRecPtr record) // xlog插入时机 XLogInsert(RM_HEAP_ID |- heap_insert() |- heap_delete() |- heap_update() |- heap_lock_tuple() |- heap_finish_speculative() |- heap_abort_speculative() |- heap_inplace_update() |- log_heap_update() XLogInsert(RM_HEAP_ID) ... // xlog重放时机 PostmasterMain() StartupProcessMain() StartupXLOG() // xlog重放操作 heap_redo() switch(info): XLOG_HEAP_INSERT: heap_xlog_insert() if XLOG_HEAP_INIT_PAGE: XLogInitBufferForRedo() PageInit() else: XLogReadBufferForRedo() XLogReadBufferForRedoExtended() // 从磁盘读page XLogReadBufferExtended() MarkBufferDirty() XLOG_HEAP_DELETE() heap_xlog_delete() ... 1.2.2 postgres进程 进程启动：\nServerLoop() BackendStartup() BackendRun() PostgresMain() InitPostgres() exec_simple_query() exec_simple_query() PortalRun() PortalRunMulti() ProcessQuery() ExecutorRun() standard_ExecutorRun() ExecutePlan() ExecProcNode() ExecModifyTable() /* INSERT/UPDATE/DELETE */ ExecInsert() heap_insert() 1.2.3 wal writer进程 main() PostmasterMain() ServerLoop() StartWalWriter() // 主要功能：进入loop，睡眠，满足时被唤醒，将wal写入磁盘 InitXLOGAccess() GetRedoRecPtr() RedoRecPtr = XLogCtl-\u0026gt;RedoRecPtr InitXLogInsert() // 初始化内存 WalWriterMain() for (;;) XLogBackgroundFlush() LWLockAcquire(WALWriteLock) XLogWrite() curridx = XLogRecPtrToBufIdx(LogwrtResult.Write) // 找到上一次xlog点 while (LogwrtResult.Write \u0026lt; WriteRqst.Write) // 计算长度，计算完成后才开始写入 XLogRecPtr EndPtr = XLogCtl-\u0026gt;xlblocks[curridx]; LogwrtResult.Write = EndPtr; // 实时更新落盘位置 startidx = curridx; npage++; from = XLogCtl-\u0026gt;pages + startidx * (Size) XLOG_BLCKSZ; // 计算落盘长度，BLKCZ可配置，1k到6m if WriteRqst.Write \u0026lt;= LogwrtResult.Write: write(from, npages * (Size) XLOG_BLCKSZ) WalSndWakeupRequest() XLogArchiveNotifySeg() if (XLogCheckpointNeeded): RequestCheckpoint(CHECKPOINT_CAUSE_XLOG) curridx = NextBufIdx(curridx) WalSndWakeupProcessRequests() WalSndWakeup() AdvanceXLInsertBuffer() // 扩张wal WaitLatch(WalWriterDelay) WaitLatchOrSocket() select() /* sleep */ 1.2.4 background writer进程 main() PostmasterMain() ServerLoop() StartBackgroundWriter() -\u0026gt; BackgroundWriterMain() for (;;) { ResetLatch() BgBufferSync() StrategySyncStart() while () { SyncOneBuffer() } pgstat_send_bgwriter() WaitLatch() } bgwritere与checkpoint的区别：\n目的不同，执行频率不同\ncheckpoint定期执行，除共享缓冲区中的数据页外，还会落盘事务日志等信息，并向xlog日志checkpoint检查点 bgwriter定期执行，刷写部分脏页，同时执行缓存替换算法，保证缓冲区管理器页面充足，降低postgres进程等待缓冲区空闲的概率 bgwriter设置参数：\nbgwriter_delay：定期执行刷盘操作 bgwriter_lru_multiplier (M)：两次bgwriter刷盘之间申请的page页数为N，系统最多写出M x N个脏页 bgwriter_lru_maxpages：写出脏页最大数 postgres会做时钟扫描算法，bgwriter要跟上时钟扫描算法\n启动流程：\nServerLoop() StartBackgroundWriter() StartChildProcess() AuxiliaryProcessMain() BackgroundWriterMain() 整体步骤：\n初始化内存上下文 +------+ | 1 | | 2 | \u0026lt;- 上次bgwriter位置 | 3 | | 4 | \u0026lt;- 时钟扫描位置 | 5 | | 6 | \u0026lt;- 申请的buffer | ... | | 1024 | +------+ BackgroundWriterMain() /* 内存上下文 */ AllocSetContextCreate(TopMemoryContext) /* 循环 */ for (;;) { ResetLatch() /* 1. 遍历所有脏页，写入磁盘，记录统计信息 */ BgBufferSync() /* 找到时钟扫描受害者位置，计算上次时钟扫描到目前申请的buffer */ StrategySyncStart() while (num_to_scan \u0026gt; 0 \u0026amp;\u0026amp; reusable_buffers \u0026lt; upcoming_alloc_est) SyncOneBuffer() FlushBuffer(bufHdr, NULL); /* 2. 将统计信息发送给pgstat进程 */ pgstat_send_bgwriter() WaitLatch() WaitLatchOrSocket() select() } 1.2.5 checkpointer进程 // checkpoint时机 #define CHECKPOINT_IS_SHUTDOWN\t0x0001\t/* Checkpoint is for shutdown */ #define CHECKPOINT_END_OF_RECOVERY\t0x0002 /* end of wal end recovery */ #define CHECKPOINT_IMMEDIATE\t0x0004\t/* Do it without delays */ #define CHECKPOINT_FORCE\t0x0008\t/* Force even if no activity */ #define CHECKPOINT_FLUSH_ALL\t0x0010\t/* Flush all pages, including those belonging to unlogged tables */ /* These are important to RequestCheckpoint */ #define CHECKPOINT_WAIT\t0x0020\t/* Wait for completion */ /* These indicate the cause of a checkpoint request */ #define CHECKPOINT_CAUSE_XLOG\t0x0040\t/* XLOG consumption */ #define CHECKPOINT_CAUSE_TIME\t0x0080\t/* Elapsed time */ // checkpoint时机 #define CHECKPOINT_IS_SHUTDOWN\t0x0001\t/* Checkpoint is for shutdown */ #define CHECKPOINT_END_OF_RECOVERY\t0x0002 /* end of wal end recovery */ #define CHECKPOINT_IMMEDIATE\t0x0004\t/* Do it without delays */ #define CHECKPOINT_FORCE\t0x0008\t/* Force even if no activity */ #define CHECKPOINT_FLUSH_ALL\t0x0010\t/* Flush all pages, including those belonging to unlogged tables */ /* These are important to RequestCheckpoint */ #define CHECKPOINT_WAIT\t0x0020\t/* Wait for completion */ /* These indicate the cause of a checkpoint request */ #define CHECKPOINT_CAUSE_XLOG\t0x0040\t/* XLOG consumption */ #define CHECKPOINT_CAUSE_TIME\t0x0080\t/* Elapsed time */ // checkpont实现 CheckpointerMain() for (;;) { ResetLatch() GetInsertRecPtr() CreateCheckPoint() InitXLogInsert() smgrpreckpt() GetOldestActiveTransactionId() WALInsertLockAcquireExclusive() WALInsertLockRelease() MultiXactGetCheckptMulti() // 先落盘 CheckPointGuts() CheckPointCLOG() CheckPointCommitTs() CheckPointSUBTRANS() CheckPointMultiXact() CheckPointPredicate() CheckPointRelationMap() CheckPointReplicationSlots() CheckPointSnapBuild() CheckPointLogicalRewriteHeap() CheckPointBuffers() BufferSync() while() { SyncOneBuffer() FlushBuffer() XLogFlush() smgrwrite() } smgrsync() CheckPointReplicationOrigin() CheckPointTwoPhase() // 再写xlog记录 XLogBeginInsert() XLogRegisterData() XLogInsert(RM_XLOG_ID) XLogFlush() // 最后更新控制文件 UpdateControlFile() smgrpostckpt() smgrcloseall() CheckArchiveTimeout() pgstat_send_bgwriter() WaitLatch() } // BufferSync main() PostmasterMain() ServerLoop() StartCheckpointer() -\u0026gt; CheckpointerMain() // 主要功能：进入loop，睡眠，满足条件时被唤醒，将各资源管理器中的内容写入磁盘 for (;;) { ResetLatch() GetInsertRecPtr() CreateCheckPoint() InitXLogInsert() smgrpreckpt() GetOldestActiveTransactionId() WALInsertLockAcquireExclusive() WALInsertLockRelease() MultiXactGetCheckptMulti() // 先落盘 CheckPointGuts() CheckPointCLOG() CheckPointCommitTs() CheckPointSUBTRANS() CheckPointMultiXact() CheckPointPredicate() CheckPointRelationMap() CheckPointReplicationSlots() CheckPointSnapBuild() CheckPointLogicalRewriteHeap() CheckPointBuffers() BufferSync() while() { SyncOneBuffer() FlushBuffer() XLogFlush() smgrwrite() } smgrsync() CheckPointReplicationOrigin() CheckPointTwoPhase() // 再写xlog记录 XLogBeginInsert() XLogRegisterData() XLogInsert(RM_XLOG_ID) XLogFlush() // 最后更新控制文件 UpdateControlFile() smgrpostckpt() smgrcloseall() CheckArchiveTimeout() pgstat_send_bgwriter() WaitLatch() } 1.2.6 autovacuum进程 1.2.7 statistics collector进程 1.2.8 archiver进程 1.2.9 logging collertor进程 1.3 进程通信 typedef struct { sig_atomic_t is_set; bool is_shared; int owner_pid; } Latch; WaitLatch(Latch *latch, int wakeEvents, long timeout) WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock, long timeout) https://cloud.tencent.com/developer/article/2000758 3 进程控制 pg-internal.vonng.com\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/1-2-postgresql-struct/","summary":"\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-%E8%BF%9B%E7%A8%8B%E6%9E%B6%E6%9E%84\"\u003e1 进程架构\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-1-%E8%BF%9B%E7%A8%8B%E6%9E%B6%E6%9E%84\"\u003e1.1 进程架构\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-%E8%BF%9B%E7%A8%8B%E5%90%AF%E5%8A%A8\"\u003e1.2 进程启动\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-3-%E8%BF%9B%E7%A8%8B%E9%80%9A%E4%BF%A1\"\u003e1.3 进程通信\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-%E8%BF%9B%E7%A8%8B%E5%8A%9F%E8%83%BD\"\u003e2 进程功能\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#2-1-postgres%E7%BA%BF%E7%A8%8B\"\u003e2.1 postgres线程\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-2-1-postmaster%E8%BF%9B%E7%A8%8B\"\u003e1.2.1 postmaster进程\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-2-postgres%E8%BF%9B%E7%A8%8B\"\u003e1.2.2 postgres进程\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-3-wal-writer%E8%BF%9B%E7%A8%8B\"\u003e1.2.3 wal writer进程\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-4-background-writer%E8%BF%9B%E7%A8%8B\"\u003e1.2.4 background writer进程\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-5-checkpointer%E8%BF%9B%E7%A8%8B\"\u003e1.2.5 checkpointer进程\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-6-autovacuum%E8%BF%9B%E7%A8%8B\"\u003e1.2.6 autovacuum进程\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-7-statistics-collector%E8%BF%9B%E7%A8%8B\"\u003e1.2.7 statistics collector进程\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-8-archiver%E8%BF%9B%E7%A8%8B\"\u003e1.2.8 archiver进程\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-9-logging-collertor%E8%BF%9B%E7%A8%8B\"\u003e1.2.9 logging collertor进程\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-3-%E8%BF%9B%E7%A8%8B%E9%80%9A%E4%BF%A1-1\"\u003e1.3 进程通信\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-%E8%BF%9B%E7%A8%8B%E6%8E%A7%E5%88%B6\"\u003e3 进程控制\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"1-进程架构\"\u003e1 进程架构\u003c/h1\u003e\n\u003ch2 id=\"11-进程架构\"\u003e1.1 进程架构\u003c/h2\u003e\n\u003cp\u003epostgresql 采用1+n+7的进程架构，包括：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e1个postmaster进程\u003c/li\u003e\n\u003cli\u003en个postgres进程\u003c/li\u003e\n\u003cli\u003e7个辅助进程：包括：\n\u003col\u003e\n\u003cli\u003ebg writer进程：\u003c/li\u003e\n\u003cli\u003echeckpointer进程：\u003c/li\u003e\n\u003cli\u003ewalwriter进程：\u003c/li\u003e\n\u003cli\u003eautovacuum进程：\u003c/li\u003e\n\u003cli\u003earchiver进程：\u003c/li\u003e\n\u003cli\u003estatistics collector进程：\u003c/li\u003e\n\u003cli\u003elog collectoer进程：\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e进程架构图如下图所示：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"pg-all-process\" loading=\"lazy\" src=\"/images/PostgreSQL/1-2-postgresql-struct/pg-all-process.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"12-进程启动\"\u003e1.2 进程启动\u003c/h2\u003e\n\u003cp\u003e先启动postmaster进程，再由poastermaster启动n+7进程。\u003cbr\u003e\n在postmaster主函数中，进程启动顺序如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"c1\"\u003e# [主进程] 启动postmaster进程\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ePostmasterMain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003epqsignal\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSIGUSR1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003esigusr1_handler\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 注册信号\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eSysLogger_Start\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e   \u003cspan class=\"c1\"\u003e# [进程7] 启动log collector进程\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eStartupDataBase\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eStartupProcessMain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 进行故障恢复\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eServerLoop\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eBackendStartup\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eSysLogger_Start\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"c1\"\u003e# [进程n] 启动posters进程\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eStartCheckpointer\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eCheckpointerMain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"c1\"\u003e# [进程2] 启动heckpointer进程\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eStartBackgroundWriter\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eBackgroundWriterMain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"c1\"\u003e# [进程1] 启动bg writer进程\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eStartWalWriter\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eInitXLOGAccess\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"n\"\u003eWalWriterMain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"c1\"\u003e# [进程3] 启动walwriter进程\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eStartAutoVacLauncher\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"c1\"\u003e# [进程4] 启动autovacuum进程\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003epgstat_start\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"c1\"\u003e# [进程6] 启动 statistics collector进程\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003epgarch_start\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"c1\"\u003e# [进程5] 启动归档进程\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003emaybe_start_bgworker\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"13-进程通信\"\u003e1.3 进程通信\u003c/h2\u003e\n\u003ch1 id=\"2-进程功能\"\u003e2 进程功能\u003c/h1\u003e\n\u003cp\u003e本章介绍各进程的主要功能。\u003c/p\u003e","title":"PostgreSQL 1-2 进程架构"},{"content":"1 整体流程 1.1 执行流程 应用-\u0026gt;驱动：通过驱动的api建立连接，并执行SQL语句 驱动-\u0026gt;服务端：通过libpq协议封装SQL语句，发送至服务端 服务端 postgres线程：接收SQL语句，调用exec_siple_query()开始处理SQL语句 SQL引擎 解析器：通过flex进行词法解析，通过yacc进行语法分析，生成解析树 分析器：对解析树进行语义分析：包括检查表是否存在等，生成查询树 重写器： 计划期：根据查询树生成执行计划 执行器：自顶向下执行各个算子，执行过程中会调用存储引擎统一接口 INSERT / UPDATE / DELETE\nExecModifyTable 算子：EexecInsert / ExecUpdate / ExecDelete EexecInsert ExecMaterializeSlot ExecBRInsertTriggers /* ROW INSERT 触发器 */ ExecWithCheckOptions /* 检查约束 */ heap_insert /* 存储引擎统一接口 */ ExecInsertIndexTuples ExecARInsertTriggers /* AFTER ROW 触发器 */ ExecProcessReturning SELECT\nExecIndexScan IndexNext() index_getnext() tid = index_getnext_tid(scan) index_fetch_heap(scan) heap_hot_search_buffer() PageGetItem() ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/1-3-execute/","summary":"\u003ch1 id=\"1-整体流程\"\u003e1 整体流程\u003c/h1\u003e\n\u003ch2 id=\"11-执行流程\"\u003e1.1 执行流程\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e应用-\u0026gt;驱动：通过驱动的api建立连接，并执行SQL语句\u003c/li\u003e\n\u003cli\u003e驱动-\u0026gt;服务端：通过libpq协议封装SQL语句，发送至服务端\u003c/li\u003e\n\u003cli\u003e服务端 postgres线程：接收SQL语句，调用exec_siple_query()开始处理SQL语句\u003c/li\u003e\n\u003c/ol\u003e\n\u003cul\u003e\n\u003cli\u003eSQL引擎\u003c/li\u003e\n\u003c/ul\u003e\n\u003col start=\"2\"\u003e\n\u003cli\u003e解析器：通过flex进行词法解析，通过yacc进行语法分析，生成解析树\u003c/li\u003e\n\u003cli\u003e分析器：对解析树进行语义分析：包括检查表是否存在等，生成查询树\u003c/li\u003e\n\u003cli\u003e重写器：\u003c/li\u003e\n\u003cli\u003e计划期：根据查询树生成执行计划\u003c/li\u003e\n\u003cli\u003e执行器：自顶向下执行各个算子，执行过程中会调用存储引擎统一接口\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eINSERT / UPDATE / DELETE\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eExecModifyTable\u003c/span\u003e \u003cspan class=\"err\"\u003e算子：\u003c/span\u003e\u003cspan class=\"n\"\u003eEexecInsert\u003c/span\u003e \u003cspan class=\"o\"\u003e/\u003c/span\u003e \u003cspan class=\"n\"\u003eExecUpdate\u003c/span\u003e \u003cspan class=\"o\"\u003e/\u003c/span\u003e \u003cspan class=\"n\"\u003eExecDelete\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eEexecInsert\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eExecMaterializeSlot\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eExecBRInsertTriggers\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* ROW INSERT 触发器 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eExecWithCheckOptions\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 检查约束 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eheap_insert\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 存储引擎统一接口 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eExecInsertIndexTuples\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eExecARInsertTriggers\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* AFTER ROW 触发器 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eExecProcessReturning\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eSELECT\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eExecIndexScan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eIndexNext\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003eindex_getnext\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003etid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eindex_getnext_tid\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003escan\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nf\"\u003eindex_fetch_heap\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003escan\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nf\"\u003eheap_hot_search_buffer\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003ePageGetItem\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ol\u003e","title":"PostgreSQL 1-3 执行模块"},{"content":"网络欺骗 - 50% 概述：局域网内，结合数据传播特点，伪造数据，欺骗机器网卡\n模型：\n主机：维护ARP缓存，内容为 [IP:MAC]\n协议：ARP：Address Resolution Protol：根据IP获取MAC\n主机网卡：\n网卡工作模式： 混杂：接收所有数据 广播：接收dest_addr为广播地址的数据 多播：接收dest_addr为多播地址的数据 单播：接收dest_addr为本机地址的数据 链路层：需要MAC地址 交换机\n分类：二层、三层、四层交换机 二层交换机：根据MAC，找到端口，发送数据，维护MAC缓存，内容为 [MAC:端口] 示意图\n帧[mac][ip] 帧[mac][ip] [主机1] -----------\u0026gt; [交换机] -------------\u0026gt; [主机2] | IP | MAC | | 端口 | MAC | | IP | MAC | | 端口 | MAC | 攻击方式：\n1 攻击机：发送大量 虚假MAC 的帧，占满交换机缓存，让交换机广播数据 2 攻击机：发送虚假的ARP：欺骗局域网内的主机 3 受害机：把数据发到错误的地方，比如攻击机 解决：\n预防：主机静态ARP表、进制ARP 检测：看某台主机的ARP缓存，判断是否有主机发送大量ARP包 检测：看无通信主机的ARP缓存，检测是否缓存了ARP包 信息收集 - ok 概述：在进行攻击之前，收集受害者的信息 攻击方式： 主机状态 ICMP Echo攻击：发送ICMP Echo包，如果回复，则主机开启 Non-Echo ICMP：发送其他类型的ICMP包，如果回复，则主机开启 IP异常包头：发送异常IP包（无效字段、错误分片、静止分片），判断主机返回信息 TCP扫描 UDP扫描 操作系统版本 被动栈指纹识别：嗅探，收集网络中数据包，判断IP的TTL、TOS、DF和TCP 的Windows-size等特征 主动栈指纹识别：TCP三次握手，ACK序号相等还是加一 TCP ISN取样：向目标主机多次握手，多次取样返回的ISN ICMP包错误信息发送速率：向目标主机连续发送大量icmp错误包 ICP消息引用：向目标主机发送ICMP错误包，判断返回的错误引用长度 端口 TCP 连接（开放）：tcp三次握手后，tcp反向ident协议可查看：对方进程pid和角色 TCP SYN（半开放）：发送tcp syn包，端口关闭：返回rst，开启：返回syn+ack TCP FIN（隐蔽）：发送fin包，关闭：返回rst，开启：无返回 TCP Xmax（隐蔽）：发送fin、urg、push标记的包，关闭：返回rst，开启：返回 TCP NULL （隐蔽）：发送关闭无标记包 FTP PROXY （隐藏）：请求ftp服务向目标主机建立连接 UDP：发送UDP包，关闭：ICMP port unreachable，开启：无返回 软件版本 漏洞 操作系统漏洞：基于漏洞库，扫描CGI漏洞、POP3漏洞、FTP漏洞、SSH漏洞等 拒绝服务 - ok 概述：合法用户无法访问服务\n模型：\n[主机1] ----\u0026gt; [主机2] 攻击方式：\n基于系统漏洞 ping of death：构造超长ICMP包，受害系统无法识别此类异常，未分配足够内存 tear drop：构造重复的IP分片包，受害系统合并分片时，导致越界 基于软件漏洞 基于协议漏洞 基于有限资源 smurf：构造ICMP ECHO请求，src_addr设置为受害机地址，在目标网络广播，每台主机都会向受害机回复ICMP REPLAY tcp syn flood：构造TCP SYN请求，使受害机保留大量半开TCP连接 tcp syn land：构造TCP SYN请求，src_addr和dst_addr都是受害机，受害机自己与自己建立半开连接 http flood：构造大量HTTP GET请求 攻击检测\n基于误用的DDOS检测 提取攻击特征：进行特征匹配，模型推理，状态转换和专家系统 基于异常的DDOS检测 建立模型：统计检测、模式检测、人工智能检测、机器学习检测 安全协议 - 50% 概述\n网络层：IPSEC （https://zhuanlan.zhihu.com/p/603923686） 传输层：SSL 客户端 --+--------------------------- |1. SSL版本、加密套件、随机数 --\u0026gt; | | \u0026lt;-- 2. 选择的加密套件、随机数 | | \u0026lt;-- 3. 证书 | | \u0026lt;-- 4. 密钥交换参数 | | \u0026lt;-- 5. 请求客户端证书 | | \u0026lt;-- 6. 结束 | | 7. 证书 --\u0026gt; | | 8. 密钥交换参数：使用对方证书，加密1个随机数 --\u0026gt; | （一共3个随机数，关键在这第3个） | 9. 证书验证：对随机数进行签名 --\u0026gt; | (使用7的证书，可验证本步的签名) | 10. 编码改变通知：后续都加密传输 --\u0026gt; | | 11. 握手结束：已发送消息的hash --\u0026gt; | | \u0026lt;-- 12. 编码改变通知：后续都加密传输 | | \u0026lt;-- 13. 握手结束：加密消息，发送给客户端，验证密钥成功 | 应用层：HTTPS 防火墙 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/1-3-network-attack/","summary":"\u003ch4 id=\"网络欺骗---50\"\u003e网络欺骗 - 50%\u003c/h4\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e概述：局域网内，结合数据传播特点，伪造数据，欺骗机器网卡\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e模型：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e主机：维护ARP缓存，内容为 [IP:MAC]\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e协议：ARP：Address Resolution Protol：根据IP获取MAC\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e主机网卡：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e网卡工作模式：\n\u003cul\u003e\n\u003cli\u003e混杂：接收所有数据\u003c/li\u003e\n\u003cli\u003e广播：接收dest_addr为广播地址的数据\u003c/li\u003e\n\u003cli\u003e多播：接收dest_addr为多播地址的数据\u003c/li\u003e\n\u003cli\u003e单播：接收dest_addr为本机地址的数据\u003c/li\u003e\n\u003cli\u003e链路层：需要MAC地址\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e交换机\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e分类：二层、三层、四层交换机\u003c/li\u003e\n\u003cli\u003e二层交换机：根据MAC，找到端口，发送数据，维护MAC缓存，内容为 [MAC:端口]\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e示意图\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            帧\u003cspan class=\"o\"\u003e[\u003c/span\u003emac\u003cspan class=\"o\"\u003e][\u003c/span\u003eip\u003cspan class=\"o\"\u003e]\u003c/span\u003e           帧\u003cspan class=\"o\"\u003e[\u003c/span\u003emac\u003cspan class=\"o\"\u003e][\u003c/span\u003eip\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"o\"\u003e[\u003c/span\u003e主机1\u003cspan class=\"o\"\u003e]\u003c/span\u003e -----------\u0026gt; \u003cspan class=\"o\"\u003e[\u003c/span\u003e交换机\u003cspan class=\"o\"\u003e]\u003c/span\u003e -------------\u0026gt; \u003cspan class=\"o\"\u003e[\u003c/span\u003e主机2\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e IP \u003cspan class=\"p\"\u003e|\u003c/span\u003e MAC \u003cspan class=\"p\"\u003e|\u003c/span\u003e          \u003cspan class=\"p\"\u003e|\u003c/span\u003e 端口 \u003cspan class=\"p\"\u003e|\u003c/span\u003e MAC \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e IP \u003cspan class=\"p\"\u003e|\u003c/span\u003e MAC \u003cspan class=\"p\"\u003e|\u003c/span\u003e          \u003cspan class=\"p\"\u003e|\u003c/span\u003e 端口 \u003cspan class=\"p\"\u003e|\u003c/span\u003e MAC \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e攻击方式：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e1 攻击机：发送大量 虚假MAC 的帧，占满交换机缓存，让交换机广播数据\u003c/li\u003e\n\u003cli\u003e2 攻击机：发送虚假的ARP：欺骗局域网内的主机\u003c/li\u003e\n\u003cli\u003e3 受害机：把数据发到错误的地方，比如攻击机\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e解决：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e预防：主机静态ARP表、进制ARP\u003c/li\u003e\n\u003cli\u003e检测：看某台主机的ARP缓存，判断是否有主机发送大量ARP包\u003c/li\u003e\n\u003cli\u003e检测：看无通信主机的ARP缓存，检测是否缓存了ARP包\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch4 id=\"信息收集---ok\"\u003e信息收集 - ok\u003c/h4\u003e\n\u003cul\u003e\n\u003cli\u003e概述：在进行攻击之前，收集受害者的信息\u003c/li\u003e\n\u003cli\u003e攻击方式：\n\u003cul\u003e\n\u003cli\u003e主机状态\n\u003col\u003e\n\u003cli\u003eICMP Echo攻击：发送ICMP Echo包，如果回复，则主机开启\u003c/li\u003e\n\u003cli\u003eNon-Echo ICMP：发送其他类型的ICMP包，如果回复，则主机开启\u003c/li\u003e\n\u003cli\u003eIP异常包头：发送异常IP包（无效字段、错误分片、静止分片），判断主机返回信息\u003c/li\u003e\n\u003cli\u003eTCP扫描\u003c/li\u003e\n\u003cli\u003eUDP扫描\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e操作系统版本\n\u003col\u003e\n\u003cli\u003e被动栈指纹识别：嗅探，收集网络中数据包，判断IP的TTL、TOS、DF和TCP 的Windows-size等特征\u003c/li\u003e\n\u003cli\u003e主动栈指纹识别：TCP三次握手，ACK序号相等还是加一\u003c/li\u003e\n\u003cli\u003eTCP ISN取样：向目标主机多次握手，多次取样返回的ISN\u003c/li\u003e\n\u003cli\u003eICMP包错误信息发送速率：向目标主机连续发送大量icmp错误包\u003c/li\u003e\n\u003cli\u003eICP消息引用：向目标主机发送ICMP错误包，判断返回的错误引用长度\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e端口\n\u003col\u003e\n\u003cli\u003eTCP 连接（开放）：tcp三次握手后，tcp反向ident协议可查看：对方进程pid和角色\u003c/li\u003e\n\u003cli\u003eTCP SYN（半开放）：发送tcp syn包，端口关闭：返回rst，开启：返回syn+ack\u003c/li\u003e\n\u003cli\u003eTCP FIN（隐蔽）：发送fin包，关闭：返回rst，开启：无返回\u003c/li\u003e\n\u003cli\u003eTCP Xmax（隐蔽）：发送fin、urg、push标记的包，关闭：返回rst，开启：返回\u003c/li\u003e\n\u003cli\u003eTCP NULL （隐蔽）：发送关闭无标记包\u003c/li\u003e\n\u003cli\u003eFTP PROXY （隐藏）：请求ftp服务向目标主机建立连接\u003c/li\u003e\n\u003cli\u003eUDP：发送UDP包，关闭：ICMP port unreachable，开启：无返回\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e软件版本\u003c/li\u003e\n\u003cli\u003e漏洞\n\u003col\u003e\n\u003cli\u003e操作系统漏洞：基于漏洞库，扫描CGI漏洞、POP3漏洞、FTP漏洞、SSH漏洞等\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch4 id=\"拒绝服务---ok\"\u003e拒绝服务 - ok\u003c/h4\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e概述：合法用户无法访问服务\u003c/p\u003e","title":"传统安全 3 网络安全"},{"content":"摘要 本博客以循序渐进的方式，依次简要介绍PostgreSQL存储模块的各个子模块的基础功能，提及内容适合数据库内核初学者。本博客旨在介绍核心原理，以便于理解为首，部分内容可能不会100%准确与具体，针对每个提及的子模块，之后会分别单独写博客详细介绍\n目录 摘要 目录 1 概述 1.1 PostgreSQL的使用流程 1.2 PostgreSQL的基础架构 1.3 PostgreSQL的功能场景 1.4 PostgreSQL存储模块的介绍流程 2 执行模块 3 存储模块 3.1 存储结构 (1) data_directory (2) oid (3) data-file (4) page (5) tuple 3.2 关键机制 (1) mvcc (2) delete 3.3 执行流程 (1) input (2) heapam (3) trancation (4) fsm (5) buffer (6) smgr (7) vfd (8) vm (9) wal (10) wal-buffer 3.4 关键进程 (1) bgwriter (2) walwriter (3) checkpointer (5) walsender (6) autovacuum 3.5 关键流程 (1) heap_insert (2) heap_delete (3) heap_update (4) heap_scan 3.6 辅助机制 (1) index (2) recovery (3) backup (4) toast (5) logical 1 概述 1.1 PostgreSQL的使用流程 本博客仅讨论存储模块的关键原理。简而言之，PostgreSQL将数据合理地组织并存储在磁盘上，并向用户提供SQL接口，让其读写磁盘上的指定数据。以下是PostgreSQL简单工作流程：\n安装PostgreSQL\n安装前，用户需指定一个空文件夹作为PostgreSQL的数据目录。\ninitdb -D 数据目录 ... 安装后，PostgreSQL会在数据目录下生成很多子目录以及文件\n启动PostgreSQL\n等待用户向PostgreSQL建立连接并发送请求\npg_ctl -D 数据目录 ... start 连接PostgreSQL\n用户连接PostgreSQL后，可向其发送SQL语句，让其执行\npsql -h 数据库所在机器的ip -p 数据库进程监听的端口 ... 执行SQL语句\n以常见的SQL语句为例PostgreSQL的执行原理如下：\n创建表：PostgreSQL接收以下SQL后，在数据目录下生成1个用于存储表t1数据的数据文件\nCREATE TABLE t1 (c1 INT, c2 TEXT); 写数据：PostgreSQL接收以下SQL后，将SQL语句中的数据(1, ‘data1’)写入上一步创建的t1数据文件\nINSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;); 读数据：PostgreSQL接收以下SQL后，从t1的数据文件中，读取数据，并发送给用户\nSELECT * FROM t1; 1.2 PostgreSQL的基础架构 1.3 PostgreSQL的功能场景 用户使用数据时，有很多复杂的场景，因此，在解决组织与存储数据的问题时，数据库还需考虑：\n多数据：一些场景中，1个数据库集群，可能存储上万张表，部分表中可能存储上百亿条数据，1个表的总数据大小可能为几T 多操作：1个表上，可能会执行INSERT、DELETE、UPDATE、SELECT等操作，在组织数据时，还需考虑数据的变化问题，比如，利用被删除数据原先所占的存储空间 高并发：一些场景中，用户可能有上百个事务，同时操作1个表，在表上并发进行INSERT、DELETE、UPDATE、SELECT等操作，需要考虑各种操作的并行与互斥 高性能：用户读写数据时，最终目的是读写磁盘上的表文件，高并发场景，磁盘IO频率等关键因素，对性能影响较大 高可靠： 高可用： 1.4 PostgreSQL存储模块的介绍流程 2 执行模块 占个位先，以后介绍执行模块\n3 存储模块 3.1 存储结构 (1) data_directory 安装数据库时，要求指定数据目录$data_directory\nexport data_directory=随便设置个目录 initdb -D $data_directory 执行initdb后，$data_directory目录下会生成很多文件\nll $data_directory $data_directory # 暂时忽略每个文件夹或文件的代表什么，只需知道文件夹和文件很多即可 |-- base |-- global |-- pg_wal |-- pg_xact |-- PostgreSQL.conf 对于已安装的数据库，在psql中，通过如下命令，可查看$data_directory\nshow data_directory; data_directory --------------------------------------- /path/to/data_directory/ (2) oid PostgreSQL会为每个对象分配一个唯一的id，即oid。每个Database、Table等很多对象都有一个唯一的oid。oid的用途很大，后面会提到。\n举例：\nCREATE DATABASE db1; CREATE TABLE t1 (c1 INT); CREATE TABLE t2 (c1 INT); -- db1, t1, t2都有一个唯一的oid，比如，分别是16386, 16387, 16389 通过以下语法，可从系统表中找到表对应的oid\nSELECT relname,oid FROM pg_class WHERE relname = \u0026#39;t1\u0026#39;; relname | oid ---------+------- t1 | 16387 (3) data-file 用户创建的表时，PostgreSQL会在数据目录下，生成1个对应的data-file文件，用于存储表中数据\n举例：\nCREATE TABLE t1 (c1 INT); -- 假设t1的oid为16387，t1属于名为db1的database，db1的oid为16386 刚创建表时，由于表中暂时无数据，因此文件也暂时是空的。文件名默认为表的oid，在数据目录下，可找到对应的文件。\n$data_directory |-- base |-- 16386 # 文件夹为database的oid |-- 16387 # 文件名为table的oid 通过以下语法，可从系统表中，看表对应的data-file的绝对路径：\nSELECT setting || \u0026#39;/\u0026#39; || pg_relation_filepath(\u0026#39;t1\u0026#39;) FROM pg_settings WHERE name = \u0026#39;data_directory\u0026#39;; ?column? ------------------------------------------------------- /path/to/data_directory/base/16386/16387 (1 row) 一些特殊情况，例如vacuum full语法，会重建表对应的data-file文件，此时，data-file文件的名称可能会与表的oid不一致，但是，无需担心，数据库会记录表oid和文件名的对应关系。\n特殊情况（暂不考虑）:\nToast表：如果1条数据的长度超过2k，且是Text等类型，超长数据可能存储在不同文件中，详见Toast机制 大数据量：如果向1个表写入狠多数据，该表对应的数据文件大小达到1G时，该表会生成第2个数据文件来存数据。依次类推，表中数据量较大时，1个表可能有很多个数据文件。1个表最多可拥有32T的数据文件 分区表：如果创建分区表，每个分区的数据文件都是独立的。本博客不关心分区表 段页式表：如果1个表对应1个或多个文件，当表的数量过多时，文件的数量也很多，Oracle支持将多个表的数据存储在同1个文件中，以缩减文件数量。本博客不关心Oracle (4) page 当执行以下语法，向表中插入数据时，(1, 'data1')是表中1行数据，这个行数据将被写入表对应的data-file中。\nINSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;); 1个data-file，由1个或多个数据页(page)组成：\npage大小：所有Page大小一致，均为8192字节，即8k。因此，1个data-file的大小，始终是8k的整数倍 page组成：1个page，由3个部分组成： PageHeader：通常为几十字节，存储page的空闲空间等很多信息 DataZone：存储行数据，即page的关键区域 PageTail：通常为0/几十/一两百字节，大部分data-file无PageTail，暂时忽略，后文介绍 page规律：最开始时，1个data-file有1个page，可存储多行数据。1个page存满后，会生成新的page存数据，以此类推，数据越多，page越多 操作系统从文件读取数据时，每次固定读取4k，即1个file-block，请仔细了解该机制的目的\nPostgreSQL每次从磁盘读取文件时，每次读取1个page，page大小默认为8k，还可配置为4k, 16k\n(5) tuple 1个page中，DataZone由多个tuple组成：\ntuple大小：1个tuple，用于存储1行数据，行数据越长，tuple越长。（如果行数据超过2k，可能触发toast机制，后文才介绍该机制） tuple组成：1个tuple，有2个部分组成： TupleHeader：通常为几十字节，存储行数据的状态等信息 Data：即行数据本身 tuple规律：用户每插入1条行数据，生成1个tuple，Tuple存放在page的DataZone区。1个page存满，会生成新的page，新tuple也将存放在新的page，以此类推 在page中，tuple是从后往前排列的，即从PageTaile方向逐渐往PageHeader方向排列。上文提到，大部分data-file的page中，无PageTail，因此，下图中暂时省去PageTail\n3.2 关键机制 (1) mvcc PostgreSQL的高并发场景\n实际应用场景中，1个数据库，可能需要同时处理成百上千个事务，这些事务，可能会访问同一个表，产生很多访问冲突的问题。以下是一个简单的示例：\n-- 用户1，执行事务1，事务尚未提交 BEGIN; INSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;); -- 用户2，执行事务2 BEGIN; SELECT * FROM t1 WHERE c1 = 1; -- 此时，同一时间，有2个执行中的事务，同时访问 t1表 PostgreSQL事务的特点\n上述示例中，事务2会和事务1发生访问冲突，数据库有不同的事务隔离级别（其他文章会详细介绍），以默认的隔离级别为例，事务2应该有以下2个特点：\n即使事务1没有提交事务，事务2也可以访问t1表，无需等待 事务1的数据(1, 'data')还未提交，事务2应无法访问(1, 'data')，即该条数据对事务2不可见 PostgreSQL事务的原理\n为了解决并发访问问题，PostgreSQL使用MVCC机制，该机制的基本实现原理如下：\n标识事务顺序：PostgreSQL维护一个递增的数字，即事务id，每个要写数据的事务，都会申请1个事务id。先开始的事务，id小，后开始的事务，id大 维护事务状态：PostgreSQL会维护所有正在进行中的事务的状态 记录数据版本：事务写入数据时，即将行数据封装到tuple时，会在tuple的头部记录事务id，即每行数据都携带了事务id 检查数据版本：每当PostgreSQL访问行数据时，会先从tuple的头部获取事务id，再检查全局事务状态，判断该条行数据是否可访问 (2) delete 上文提到，PostgreSQL经常需要处理高并发场景，比如，一个事务删除数据时，另一个事务读取数据，以下是一个简单的示例：\n-- 用户1，执行事务1，删除数据，事务尚未提交 BEGIN; DELETE FROM t1 WHERE c1 = 1; -- 用户2，执行事务2 BEGIN; SELECT * FROM t1 WHERE c1 = 1; -- 此时，同一时间，有2个执行中的事务，同时访问 t1表，1个事务删除数据，1个事务读取数据 PostgreSQL删除数据的流程\n在示例中，显然，当事务1执行DELETE操作时，由于事务未提交，显然不能直接从Page中删除数据。PostgreSQL采用标记删除的方法，标记删除的基本原理如下： 记录数据状态：删除数据时，先将数据标记为删除状态，并在tuple的头部记录删除tuple的id 检查数据版本：当其他事务访问到含删除标记的tuple时，从tuple的头部获取事务id，检查事务id对应的事务是否已提交，如果对应的事务未提交，该条tuple仍然可见或者暂时无法操作 清理无效数据：执行删除操作的事务提交后，代表含删除标记的tuple真正变成无效数据，但是，考虑到性能等因素，PostgreSQL不着急立即清理无效的tuple，而是提供一些异步清理的机制，后文会介绍 3.3 执行流程 (1) input 首先，此处以一个简单的例子，介绍在处理SQL语法的整个流程中，存储模块主要完成哪些工作：\n用户：执行以下SQL\nINSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;); 执行模块：直接包括语法解析、语义分析等流程后，最终，获取3个最关键的的信息：(1) 执行INSERT操作，(2) 表名为 t1，(3) 行数据为 (1, ‘data1’)，然后，调用存储模块的接口，将表的信息，行数据本身传递给存储模块\n存储模块：存储模块将行数据(1, ‘data1’)封装到tuple中，然后从t1对应的data-file中，找到合适的page，将tuple存入page。在完成这些功能的同时，考虑高并发、高性能、高可靠等因素\n用户执行INSERT、UPDATE、DELETE、SELECT等很多操作时，都需要调用存储模块的接口，不同操作的接口不同，本章主要以INSERT语法为例，简单存储模块处理INSERT语法时，会涉及哪些子模块，以及模块的基本功能。存储模块处理其他语法时，基本流程、涉及的子模块、子模块的功能等都大同小异，便不一一介绍。\n在PostgreSQL的代码中，1个relation结构体，存储1个表的基本信息。例如，用户执行以下语法：\nINSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;); 上述INSERT语法中，执行模块识别到表名为t1时，会生成1个relation结构体，然后将表的众多关键元信息暂存在relation结构体中，比如表oid、表的列数、表的列数据类型等，这些元信息大部分来自系统表，例如，上文提到的pg_class等系统表。当然，ralation也会暂存一些其他临时数据，比如，表上的锁等。\n在代码中，无论是执行模块，还是存储模块，都会经常用到relation结构体中的信息。执行模块调用存储模块的接口时，也会直接将relation结构体传到存储模块。\n(2) heapam heapam是存储模块对上层提供的数据读写接口的模块，通常由执行模块调用。这些接口通常是操作1个relation中的1个或多个tuple。即操作1个表中的1行或多行数据。可以理解为，heapam是存储模块的入口。\n本文介绍heapam模块最常见的4个接口，用户执行INSERT、DELETE、UPDATE、SELECT等语法，操作表时，执行模块通常调用以下4个接口：\n/* * 功能：向relatiion中写入1条tuple * 示例：用户执行 INSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;); * relation中存储 t1 的原信息，比如oid等 * tup中存储1行数据 (1, \u0026#39;data1\u0026#39;)，此时的HeapTuple，主要包含数据，tuple的头部中还没有事务id等信息 */ heap_insert(Relation relation, HeapTuple tup, ...) /* * 从relation中删除1条tuple * tid存储要删除数据的位置，tid中的关键信息为：哪个data-file, data-file中第几个page, page中第几个tuple * 执行模块会调用其他存储接口，找到要删除tuple的位置，此处暂不介绍 * * 示例：用户执行 DELETE FROM t1 WHERE c1 = 1; * tid为符合条件c1=1的行数据的位置，如果有多条符合条件的行数据，存储模块会调用多次heap_delete，每次调用仅删除1个tuple */ heap_delete(Relation relation, ItemPointer tid, ...) /* * 在relation中，将旧tuple标记删除，并写入1个新tuple。后文会介绍此处的标记删除机制 */ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, ...) /* * 从relation中读取数据，每次读取1条数据 */ HeapScanDesc heap_beginscan(Relation relation, ...) HeapTuple heap_getnext(HeapScanDesc scan) (3) trancation 上文提到，为解决高并发等问题，PostgreSQL在tuple中存储行数据时，会同时存储事务id。执行模块调用heap_insert时，只传递了行数据，因为，在heap_insert函数内部，会首先执行以下2个操作：\n申请1个事务id，代表此次执行INSERT操作的事务 生成1个tuple，在tuple的头部记录事务id，在tuple中存储行数据 至此，已准备好1个完整的tuple\n(4) fsm 生成tuple后，需要找到1个合适的page，将tuple存放到page中\n寻找合适的page时，考虑：\ntuple长短不一：1个表有多个page，1个page可存储多个tuple，1个tuple存储1行数据，数据来自INSERT .. ('data')等语法，语法中的数据长短不一，有的数据长度可能为0.1k，有的数据长度可能为1k page空闲不一：如果执行DELETE等操作，某些page中的某些tuple可能跟被删除，数据的异步清理机制可能会清理page中的tuple，导致page中空闲空间变大 page数量很多：一些场景中，1个表可能存储几T的数据，即data-file中的page数非常多 fsm模块的功能是记录每个page的空闲空间大小，并根据tuple的长度，提供快速查1个具有合适空闲空间的page的功能\nfsm文件：为了记录page的空闲空间，1个表，除了拥有1个data-file存储数据外（暂不考虑数据量超大场景），还拥有1个对应的fsm-file。fsm-file存储data-file中每个page的空闲空间大小，假设data-file的名称为17000，则对应fsm-file的名称为17000_fsm fsm内容：对于data-file中的所有page，即第1，2， 3， …个page，fsm-file中只会分别记录1个整数，表示对应page中空闲空间大小 fsm查找：fsm-file的大小远远小于data-file的大小。向data-file写入tuple之前，先快速从fsm中查找具有合适空闲空间的page，然后直接获取该page fsm组织：1个fsm节点记录1个page的空闲空间，所有fsm按照空闲空间大小的顺序，组成棵个b+树，提高查找效率 (5) buffer 选择page后，从磁盘读取page时，io开销很高，为了提高性能，存储模块会在内存中缓存一些经常访问的page，降低io次数\n缓存page时，需考虑：\npage数量很多：上文提到，1个数据库有很多表，1个表有很多page，磁盘上page的总大小，可能是T级别的，而内存大小，一般是G级别，因此，只能缓存少部分page 快速查找page：fsm每次选择page后，首先需判断page是否存在于缓存中，要遍历缓存中的page，显然查找速度很慢，因此，需提高page查找速度 page访问随机：内存只能缓存少部分page，而用户执行SQL时，短时间内访问的page数绝对大于内存中缓存的page数，因此，需制定缓存page淘汰机制 page并发访问：在缓存中的page，可能被多个事务访问，因此，需对缓存中的page加锁访问 buffer模块的功能是缓存page，并解决快速查找、并发访问等问题，无论是读还是写page，都优先从buffer中查找page：\nbuffer容量：根据每台机器内存大小、数据库配置参数等不同，buffer模块可缓存的page数也不同，一般是几千个page buffer查找：buff中，所有page存在1个hash表中，每次查找page时，根据2个关键信息，[data-file对应的id, data-file中第几个page]，作为key值，可找到唯一的page buffer插入：每次读或写page时，先在buffer中查找page，如果指定page不在buffer中，则从磁盘读取指定page，然后将page插入buffer中 buffer淘汰：随着page不断插入buffer，当buffer缓存快慢时，buffer会依据最近每个page的访问次数的依据，淘汰一些page buffer落盘：当事务向buffer中的page写数据时，此时buffer中的page与磁盘上对应的page内容已不一致，即buffer中的page时脏页，为了提供读写效率，事务并不会立即将脏页落盘，后文会介绍buffer中脏页异步落盘的机制 buffer并发：buffer中的每个page，都有对应的读写锁，控制多事务对同一page的并发访问 (6) smgr 从磁盘读取page时，1次读写1个page，本质是调用操作系统的文件读写接口read(), write()，设置读写偏移为8k的倍数、读写长度为8k\nsmgr模块简单封装了操作系统的read/write接口，上层只需传入page的编号，即可直接读写指定page，smgr的接口定义如下：\n/* 1 创建或打开1个文件, rnode和文件路径和文件名有关，以后介绍 */ .. smgropen(RelFileNode rnode); /* 2 向文件中写入1个Page。其中，blocknum即Page编号，从1开始的整数；buffer即长度为8k的Page数据 */ smgrwrite(.., BlockNumber blocknum, char *buffer, ..); /* 3 从文件中读取1个Page。其中，blocknum即Page编号；buffer即用于存放Page的长度为8k的缓存区 */ smgrread(.., BlockNumb blocknum, char *buffer); /* 4 其他之后介绍 */ 另外，针对不同操作系统场景，smgr模块也可以封装不同操作系统的不同文件读写提供，对上层提供统一的接口。\n(7) vfd 从磁盘读取page时，需确保文件已打开，即获取文件句柄\n获取文件句柄时，需考虑：\n句柄数量多：在linux中，1个进程，一般最多可同时打开几千个文件，但PostgreSQL是频繁读写文件的进程，1个数据库中，可能拥有上万个文件，因此，需解决数据库文件数大于单进程文件句柄数的限制 句柄访问随机：与buffer模块的原理类似，当句柄较多时，还需考虑句柄淘汰的问题 vfd模块的功能是缓存最近常用的句柄，当句柄数达到操作系统限制时，淘汰暂未被使用的句柄，确保打开新文件时，不会因达到操作系统句柄数限制而失败\n(8) vm 向page写入tuple后，写入tuple的事务仍未提交，写入事务可能回滚，导致tuple失效，而且，写入事务未提交前，对于其他事务而言，该tuple并未生效。从page中删除tuple时，tuple也会失效。PostgreSQL需异步清理page中的失效tuple。\n清理各page中未生效的tuple时，需考虑：\npage数量很多：上文提到，1个data-file中的page数可能非常多，清理 page无无效tuple：1个page中，可能所有tulpe都是有效的，即无事务删除任何tuple、且所有插入tuple的事务也提交了等，此时，无需清理page vm模块的功能是记录每个page是否含未生效的tuple，并提供快速判断指定page是否含未生效的功能\nvm文件：为了记录所有page是否含未生效的tuple，1个表，除了拥有1个data-file文件，1个fsm-file外，还拥有1个对应的vm-file。vm-file存储data-file中每个page中是否含未生效tuple。假设data-file的名称为17000，则对应vm-file的名称为17000_vm vm文件内容：对于data-file中的所有page，即第1，2， 3， …个page，vm中只会分别记录1个bool值，表示对应page中是否含未生效tuple vm文件查找：fsm-file的大小远远小于data-file的大小，在异步清理无效tuple时，先快速从vm中判断指定page是否含含未生效tuple，便无需读取所有page，降低IO次数。另外，后文会提到，vm模块对索引模块也很重要 vm文件组织：vm文件本质是一个数组，数组的下标表表示对应page的编号 (9) wal 将tuple插入page后，page暂时在buffer中。存储模块需要在确保高可靠和高性能的前提下，将tuple落盘\n将tuple落盘时，需要考虑以下问题：\n高可靠：数据库是对可靠性要求极高的软件，当插入tuple的事务提交时，如果tuple未落盘，当发生断电等突发事件，内存即buffer中的tuple将会丢失，重启后，将出现事务提交，但是事务插入的tuple丢失，数据不一致 高性能：1个事务，可能将多个tuple，插入多个page。在事务提交前，如果依次将每个page都落盘，由于IO开销较高，将导致单个事务的处理时间变长，整体性能较低 高可用：数据库对可用性要求也极高，大部分场景，都需同时部署主、备数据库，当主数据库发生故障时，备数据库需升为主数据库，保证服务不中断，此时，要求主机源源不断往备机发送数据，并且保证，事务提交时，备机已成功接收与落盘数据。如果主机往备机发送SQL语句，备机接受和执行SQL语句，显然效率很低 wal模块的功能是收集所有文件写操作、写操作的信息、写操作涉及的数据，1写操作记录到1条wal-record中，当事务提交时，确保事务所有写操作生成的所有wal-record都落盘。示例：\n用户执行事务\nBEGIN; INSERT INTO t1 VALUES (1, ‘data1’); INSERT INTO t2 VALUES (2, ‘data2’); INSERT INTO t3 VALUES (3, ‘data3’); 存储模块执行写操作\n执行3次heap_insert，分别生成3条tuple，将3条tuple存入3个page，3个page暂存在buffer中 假设生成tuple-1, tuple-2, tuple-3，分别被写入data-file-1, data-file-2, data-file-3的page-1, page-2, page-3 用户提交事务\nCOMMIT; 存储模块执行事务提交\n假如无wal模块：存储模块先将page-1, page-2, page-3落盘，再向用户返回事务提交成功 假如有wal模块： 生成wal-record：将3条tuple存储3个page的同时，生成3条wal-record，3条wal-record记录的关键信息分别为[insert, data-file-1, page-1, tupl-1, tuple-offset], [insert, data-file-2, page-2, tupl-2, tuple-offset]， [insert, data-file-3, page-3, tupl-3, tuple-offset] 落盘wal-record：3条wal-record可组合在一起，落盘1次即可 发送wal-record：由于wal-record记录了所有关键信息，备机接受wal-record后，直接根据元信息重现主机的写操作即可，无需重复分析处理SQL，甚至，备机确保接收的wal-record落盘即可，无需在事务提交时立即重现写操作（实际上，执行1次事务，写文件的次数，文件的类型等，远超此处的示例） 最后，返回事务提交成功 wal模块的上述机制，对关系数据库非常重要，几乎存在于所有关系数据库中\n(10) wal-buffer 生成wal-record后，需要将wal-record写入磁盘。\n3.4 关键进程 (1) bgwriter (2) walwriter (3) checkpointer (5) walsender (6) autovacuum 3.5 关键流程 (1) heap_insert (2) heap_delete (3) heap_update (4) heap_scan 3.6 辅助机制 (1) index (2) recovery (3) backup (4) toast (5) logical ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/1-4-storage/","summary":"\u003ch1 id=\"摘要\"\u003e摘要\u003c/h1\u003e\n\u003cblockquote\u003e\n\u003cp\u003e本博客以循序渐进的方式，依次简要介绍PostgreSQL存储模块的各个子模块的基础功能，提及内容适合数据库内核初学者。本博客旨在介绍核心原理，以便于理解为首，部分内容可能不会100%准确与具体，针对每个提及的子模块，之后会分别单独写博客详细介绍\u003c/p\u003e\u003c/blockquote\u003e\n\u003ch1 id=\"目录\"\u003e目录\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E6%91%98%E8%A6%81\"\u003e摘要\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E7%9B%AE%E5%BD%95\"\u003e目录\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-%E6%A6%82%E8%BF%B0\"\u003e1 概述\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-1-PostgreSQL%E7%9A%84%E4%BD%BF%E7%94%A8%E6%B5%81%E7%A8%8B\"\u003e1.1 PostgreSQL的使用流程\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-PostgreSQL%E7%9A%84%E5%9F%BA%E7%A1%80%E6%9E%B6%E6%9E%84\"\u003e1.2 PostgreSQL的基础架构\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-3-PostgreSQL%E7%9A%84%E5%8A%9F%E8%83%BD%E5%9C%BA%E6%99%AF\"\u003e1.3 PostgreSQL的功能场景\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-4-PostgreSQL%E5%AD%98%E5%82%A8%E6%A8%A1%E5%9D%97%E7%9A%84%E4%BB%8B%E7%BB%8D%E6%B5%81%E7%A8%8B\"\u003e1.4 PostgreSQL存储模块的介绍流程\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-%E6%89%A7%E8%A1%8C%E6%A8%A1%E5%9D%97\"\u003e2 执行模块\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-%E5%AD%98%E5%82%A8%E6%A8%A1%E5%9D%97\"\u003e3 存储模块\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#3-1-%E5%AD%98%E5%82%A8%E7%BB%93%E6%9E%84\"\u003e3.1 存储结构\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-data-directory\"\u003e(1) data_directory\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-oid\"\u003e(2) oid\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-data-file\"\u003e(3) data-file\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-page\"\u003e(4) page\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#5-tuple\"\u003e(5) tuple\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-2-%E5%85%B3%E9%94%AE%E6%9C%BA%E5%88%B6\"\u003e3.2 关键机制\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-mvcc\"\u003e(1) mvcc\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-delete\"\u003e(2) delete\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-3-%E6%89%A7%E8%A1%8C%E6%B5%81%E7%A8%8B\"\u003e3.3 执行流程\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-input\"\u003e(1) input\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-heapam\"\u003e(2) heapam\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-trancation\"\u003e(3) trancation\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-fsm\"\u003e(4) fsm\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#5-buffer\"\u003e(5) buffer\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#6-smgr\"\u003e(6) smgr\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#7-vfd\"\u003e(7) vfd\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#8-vm\"\u003e(8) vm\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#9-wal\"\u003e(9) wal\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#10-wal-buffer\"\u003e(10) wal-buffer\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-4-%E5%85%B3%E9%94%AE%E8%BF%9B%E7%A8%8B\"\u003e3.4 关键进程\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-bgwriter\"\u003e(1) bgwriter\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-walwriter\"\u003e(2) walwriter\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-checkpointer\"\u003e(3) checkpointer\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#5-walsender\"\u003e(5) walsender\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#6-autovacuum\"\u003e(6) autovacuum\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-5-%E5%85%B3%E9%94%AE%E6%B5%81%E7%A8%8B\"\u003e3.5 关键流程\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-heap-insert\"\u003e(1) heap_insert\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-heap-delete\"\u003e(2) heap_delete\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-heap-update\"\u003e(3) heap_update\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-heap-scan\"\u003e(4) heap_scan\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-6-%E8%BE%85%E5%8A%A9%E6%9C%BA%E5%88%B6\"\u003e3.6 辅助机制\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-index\"\u003e(1) index\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-recovery\"\u003e(2) recovery\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-backup\"\u003e(3) backup\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-toast\"\u003e(4) toast\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#5-logical\"\u003e(5) logical\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"1-概述\"\u003e1 概述\u003c/h1\u003e\n\u003ch2 id=\"11-postgresql的使用流程\"\u003e1.1 PostgreSQL的使用流程\u003c/h2\u003e\n\u003cp\u003e本博客仅讨论存储模块的关键原理。简而言之，PostgreSQL将数据合理地组织并存储在磁盘上，并向用户提供SQL接口，让其读写磁盘上的指定数据。以下是PostgreSQL简单工作流程：\u003c/p\u003e","title":"PostgreSQL 1-4 存储模块"},{"content":"1 netfilter 1.1 netfilter 架构 1.2 netfilter 编程 struct nf_hook_state { unsigned int hook; int thresh; u_int8_t pf; struct net_device *in; struct net_device *out; struct sock *sk; struct net *net; struct list_head *hook_list; int (*okfn)(struct net *, struct sock *, struct sk_buff *); }; /* 回调函数 */ typedef unsigned int nf_hookfn( void *priv, struct sk_buff *skb, const struct nf_hook_state *state); /* 回调函数返回值 */ #define NF_DROP 0 #define NF_ACCEPT 1 #define NF_STOLEN 2 #define NF_QUEUE 3 #define NF_REPEAT 4 #define NF_STOP 5 /* 向内核注册回调函数 */ struct nf_hook_ops { struct list_head list; /* 链表成员 */ nf_hookfn *hook; /* 回调函数 */ struct module *owner; int pf; /* 协议簇 */ int hooknum; /* NF_ARP_IN, NF_ARP_OUT */ int priority; /* 优先级 */ } ; /* 协议簇 */ #define AF_UNSPEC 0 #define AF_UNIX 1 #define AF_LOCAL 1 #define AF_INET 2 /* IP */ #define AF_INET6 10 /* IPV6 */ #define AF_LLC 26 /* 注册 */ void nf_register_hooks(struct nf_hook_ops *ops_arr, int arr_len); module_init(arp_hook_init) 参考：netfilter结构体：https://www.cnblogs.com/ink-white/p/16818769.html 参考：netfilter构造报文：https://www.cnblogs.com/ink-white/p/16816464.html 参考：netfilter捕获arp：https://blog.csdn.net/fuyuande/article/details/79772134 2 iptables 2.1 iptables 命令 # 1 查看所有规则 iptables --list -n iptables --list -t [filter/mangle/nat/raw] # 2 规则管理 iptables [操作] [链名] [动作] [过滤条件] # 操作 -A : 新增规则，添加至末尾 -I : 新增规则，添加到指定位置 -D : 删除规则 -R : 替换规则 # 链名 PREROUTING INPUT OUTPT FORWARD # 动作 -j ACCEPT -j DROP -j REJECT -j SNAT # 过滤条件 -s 0.0.0.0 : 源IP -sport 100 : 源端口 -d 1.1.1.1 : 目标IP -dport 100 : 目标端口 -p icmp/tcp/udp : 协议类型 -p icmp --icmp-type 8 : ping -i etho : 数据接收网口 -o eth1 : 数据发送网口 -m 其他参数 -m mac --mac-source 00:00:00:00:01 -m owner --uid-owner 100 -m owner --pid-owner 100 -m state --state [NEW, RELATED, ESTABLISHED, INVALID] # 3 启动与停止 [ location: /etc/init.d/iptables ] iptables start iptables stop iptables restart # 4 批量操作 iptables -F # 清空规则 iptables -X # 清空用户规则 iptables -Z # 清空计数 # 5 保存规则 [ storage: /etc/sysconfig/iptables ] iptables save 3 kkwall 3.1 命令 # 1 过滤 # 1.1 过滤ip kkwall filter -sip 10.10.10.10 kkwall accept -dip 10.10.10.10 # 1.2 过滤端口 kkwall filter -sport 100 kkwall accept -dport 100 kkwall filter -dport all # 1.2 过滤协议 kkwal filter -protol tcp/icmp/udp/igmp # 3 入侵检测 # 3.1 防 arp 欺骗 # 网关固定mac kkwal set mac 0.0.0.0/00:00:00:00:01 # 短时间内，大量arp报文 # 3.2 端口扫描 # 设置端口白名单，如果报文目标端口在白名单外的端口，为异常报文 kkwal set ports 22,80 # 检测所有tcp状态，识别所有syn和fin扫描 # 3.3 拒绝服务 # 系统漏洞： # ping of death: 超长icmp包 63336， 分片发送 -\u0026gt; 丢弃 # tear drop: 重复的IP分片 -\u0026gt; 丢弃 # 有限资源 # smurf: 短时间接收到大量icmp echo包 -\u0026gt; 全丢弃 # tcp syn flood: 短时间，大量半开请求 # tcp syn land: tcp src_addr和dst_addr都是自己 # http flood: http请求 typedef struct { ; } ArpHdr; typedef struct { ; } IpHdr; typedef struct { ; } TcpHdr; typedef struct { int type; IpHdr *iphdr; TcpHdr *tcphdr; } Fragment; /* */ void detecte_trick(ArpHdr *arp) { ArpItem staticarp = arp_list_find(arp-\u0026gt;mac); if (arp-\u0026gt;dst_ip != staticarp) { printf(\u0026#34;arp trick\u0026#34;); } } 参考：iptables常用命令 https://blog.csdn.net/shiner_chen/article/details/132104300 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/1-4-firewall/","summary":"\u003ch1 id=\"1-netfilter\"\u003e1 netfilter\u003c/h1\u003e\n\u003ch2 id=\"11-netfilter-架构\"\u003e1.1 netfilter 架构\u003c/h2\u003e\n\u003ch2 id=\"12-netfilter-编程\"\u003e1.2 netfilter 编程\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003enf_hook_state\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"kt\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ehook\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ethresh\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eu_int8_t\u003c/span\u003e \u003cspan class=\"n\"\u003epf\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003enet_device\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ein\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003enet_device\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eout\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003esock\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003esk\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003enet\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003enet\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003elist_head\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ehook_list\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eokfn\u003c/span\u003e\u003cspan class=\"p\"\u003e)(\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003enet\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003esock\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003esk_buff\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 回调函数 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003etypedef\u003c/span\u003e \u003cspan class=\"kt\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003enf_hookfn\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epriv\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003esk_buff\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eskb\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003econst\u003c/span\u003e \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003enf_hook_state\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 回调函数返回值 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define NF_DROP 0\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define NF_ACCEPT 1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define NF_STOLEN 2\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define NF_QUEUE 3\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define NF_REPEAT 4\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define NF_STOP 5\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 向内核注册回调函数 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003enf_hook_ops\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003elist_head\u003c/span\u003e    \u003cspan class=\"n\"\u003elist\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e   \u003cspan class=\"cm\"\u003e/* 链表成员 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003enf_hookfn\u003c/span\u003e           \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ehook\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e  \u003cspan class=\"cm\"\u003e/* 回调函数 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003emodule\u003c/span\u003e      \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eowner\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e                 \u003cspan class=\"n\"\u003epf\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e     \u003cspan class=\"cm\"\u003e/* 协议簇 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e                 \u003cspan class=\"n\"\u003ehooknum\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* NF_ARP_IN, NF_ARP_OUT */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e                 \u003cspan class=\"n\"\u003epriority\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 优先级 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 协议簇 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define AF_UNSPEC       0\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define AF_UNIX         1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define AF_LOCAL        1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define AF_INET         2   \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* IP */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define AF_INET6        10  \u003c/span\u003e\u003cspan class=\"cm\"\u003e/* IPV6 */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define AF_LLC          26\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 注册 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003enf_register_hooks\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"nc\"\u003enf_hook_ops\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eops_arr\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003earr_len\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003emodule_init\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003earp_hook_init\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e参考：netfilter结构体：\u003ca href=\"https://www.cnblogs.com/ink-white/p/16818769.html\"\u003ehttps://www.cnblogs.com/ink-white/p/16818769.html\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e参考：netfilter构造报文：\u003ca href=\"https://www.cnblogs.com/ink-white/p/16816464.html\"\u003ehttps://www.cnblogs.com/ink-white/p/16816464.html\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e参考：netfilter捕获arp：\u003ca href=\"https://blog.csdn.net/fuyuande/article/details/79772134\"\u003ehttps://blog.csdn.net/fuyuande/article/details/79772134\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-iptables\"\u003e2 iptables\u003c/h1\u003e\n\u003ch2 id=\"21-iptables-命令\"\u003e2.1 iptables 命令\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 1 查看所有规则\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eiptables --list -n\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eiptables --list -t \u003cspan class=\"o\"\u003e[\u003c/span\u003efilter/mangle/nat/raw\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 2 规则管理\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eiptables \u003cspan class=\"o\"\u003e[\u003c/span\u003e操作\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e链名\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e动作\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e过滤条件\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 操作\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        -A : 新增规则，添加至末尾\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        -I : 新增规则，添加到指定位置\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        -D : 删除规则\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        -R : 替换规则\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 链名\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        PREROUTING\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        INPUT\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        OUTPT\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        FORWARD\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 动作\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        -j ACCEPT\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        -j DROP\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        -j REJECT\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        -j SNAT\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 过滤条件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        -s 0.0.0.0 : 源IP\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        -sport \u003cspan class=\"m\"\u003e100\u003c/span\u003e : 源端口\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        -d 1.1.1.1 : 目标IP\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        -dport \u003cspan class=\"m\"\u003e100\u003c/span\u003e : 目标端口\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        -p icmp/tcp/udp : 协议类型\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            -p icmp --icmp-type \u003cspan class=\"m\"\u003e8\u003c/span\u003e : ping\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        -i etho    : 数据接收网口\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        -o eth1    : 数据发送网口\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        -m 其他参数\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            -m mac --mac-source 00:00:00:00:01\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            -m owner --uid-owner \u003cspan class=\"m\"\u003e100\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            -m owner --pid-owner \u003cspan class=\"m\"\u003e100\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            -m state --state \u003cspan class=\"o\"\u003e[\u003c/span\u003eNEW, RELATED, ESTABLISHED, INVALID\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 3 启动与停止 [ location: /etc/init.d/iptables ]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eiptables start\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eiptables stop\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eiptables restart\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 4 批量操作\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eiptables -F     \u003cspan class=\"c1\"\u003e# 清空规则\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eiptables -X     \u003cspan class=\"c1\"\u003e# 清空用户规则\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eiptables -Z     \u003cspan class=\"c1\"\u003e# 清空计数\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 5 保存规则  [ storage: /etc/sysconfig/iptables ]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eiptables save\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"3-kkwall\"\u003e3 kkwall\u003c/h1\u003e\n\u003ch2 id=\"31-命令\"\u003e3.1 命令\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 1 过滤\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 1.1 过滤ip\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ekkwall filter -sip 10.10.10.10\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ekkwall accept -dip 10.10.10.10\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 1.2 过滤端口\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ekkwall filter -sport \u003cspan class=\"m\"\u003e100\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ekkwall accept -dport \u003cspan class=\"m\"\u003e100\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ekkwall filter -dport all\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 1.2 过滤协议\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ekkwal filter -protol tcp/icmp/udp/igmp\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 3 入侵检测\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 3.1 防 arp 欺骗\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 网关固定mac\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ekkwal \u003cspan class=\"nb\"\u003eset\u003c/span\u003e mac 0.0.0.0/00:00:00:00:01\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 短时间内，大量arp报文\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 3.2 端口扫描\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 设置端口白名单，如果报文目标端口在白名单外的端口，为异常报文\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ekkwal \u003cspan class=\"nb\"\u003eset\u003c/span\u003e ports 22,80\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 检测所有tcp状态，识别所有syn和fin扫描\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 3.3 拒绝服务\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 系统漏洞：\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# ping of death: 超长icmp包 63336， 分片发送 -\u0026gt; 丢弃\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# tear drop: 重复的IP分片  -\u0026gt; 丢弃\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 有限资源\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# smurf: 短时间接收到大量icmp echo包 -\u0026gt; 全丢弃\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# tcp syn flood: 短时间，大量半开请求\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# tcp syn land: tcp src_addr和dst_addr都是自己\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# http flood: http请求\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003etypedef\u003c/span\u003e \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"n\"\u003eArpHdr\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003etypedef\u003c/span\u003e \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"n\"\u003eIpHdr\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003etypedef\u003c/span\u003e \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"n\"\u003eTcpHdr\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003etypedef\u003c/span\u003e \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003etype\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eIpHdr\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eiphdr\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eTcpHdr\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003etcphdr\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"n\"\u003eFragment\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/*  */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003edetecte_trick\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eArpHdr\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003earp\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eArpItem\u003c/span\u003e \u003cspan class=\"n\"\u003estaticarp\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003earp_list_find\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003earp\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003emac\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003earp\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003edst_ip\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"n\"\u003estaticarp\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003eprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;arp trick\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e参考：iptables常用命令 \u003ca href=\"https://blog.csdn.net/shiner_chen/article/details/132104300\"\u003ehttps://blog.csdn.net/shiner_chen/article/details/132104300\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e","title":"传统安全 4 防火墙"},{"content":"initdb 流程 opengauss\nmain # initdb.cpp canonicalize_path # PGDATA find_other_exec # 在gs_initdb bin目录下，查找gaussdb bin # 在$GAUSSHOME/share/postgrsql目录下，检查以下文件是否存在 check_input(\u0026#39;postgres.bki, postgres.description, pg_hba.conf.sample, postgresql.conf.sample, ..., system_views.sql, ...\u0026#39;) check_locale_encoding init_log gs_getenv_r(\u0026#39;GAUSSLOG\u0026#39;) write_version_file canonicalize_path(\u0026#39;$PGDATA/PG_VERSION\u0026#39;) fprintf(PG_MAJORVERSION = \u0026#39;9.2\u0026#39;) setup_config readfile(\u0026#39;$GAUSSHOME/share/postgrsql/postgresql.conf.sample\u0026#39;) sprintf_s(\u0026#39;$PGDATA/postgresql.conf\u0026#39;) writefile(\u0026#39;$PGDATA/postgresql.conf\u0026#39;) InitUndoSubsystemMeta bootstrap_template1 write_version_file setup_auth get_set_pwd setup_depend load_plpgsql setup_sysviews setup_description ... setup_privileges setup_schema setup_update vacuum_db make_template0 make_postgres ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/1-5-initdb/","summary":"\u003ch1 id=\"initdb-流程\"\u003einitdb 流程\u003c/h1\u003e\n\u003cp\u003eopengauss\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e \u003cspan class=\"c1\"\u003e# initdb.cpp\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ecanonicalize_path\u003c/span\u003e \u003cspan class=\"c1\"\u003e# PGDATA\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003efind_other_exec\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 在gs_initdb bin目录下，查找gaussdb bin\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 在$GAUSSHOME/share/postgrsql目录下，检查以下文件是否存在\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003echeck_input\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;postgres.bki, postgres.description, pg_hba.conf.sample, postgresql.conf.sample, ..., system_views.sql, ...\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003echeck_locale_encoding\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003einit_log\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003egs_getenv_r\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;GAUSSLOG\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ewrite_version_file\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ecanonicalize_path\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;$PGDATA/PG_VERSION\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003efprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ePG_MAJORVERSION\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;9.2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003esetup_config\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ereadfile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;$GAUSSHOME/share/postgrsql/postgresql.conf.sample\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003esprintf_s\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;$PGDATA/postgresql.conf\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ewritefile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;$PGDATA/postgresql.conf\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eInitUndoSubsystemMeta\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ebootstrap_template1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ewrite_version_file\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003esetup_auth\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eget_set_pwd\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003esetup_depend\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eload_plpgsql\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003esetup_sysviews\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003esetup_description\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"o\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003esetup_privileges\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003esetup_schema\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003esetup_update\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003evacuum_db\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003emake_template0\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003emake_postgres\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"PostgreSQL 1-5 initdb"},{"content":"1 数据库加密的背景 1.1 数据库安全机制 应用将数据发送给数据库后，数据库组织数据，将数据存储在文件中，并提供一系列安全机制，保护数据安全。比如：\n安全传输：基于TLS等安全协议，保证数据在应用与数据库之间传输的机密性、完整性等，避免攻击者对传输中的数据进行窃听、伪造、篡改等 身份认证：基于IP、口令、证书等鉴别用户身份，避免攻击者非法访问数据库 访问控制：通过多种访问控制机制，限制攻击者对数据库对象的的访问范围 安全审计：记录攻击者在数据库中执行的各项操作 数据脱敏：对隐私数据库进行脱敏处理，避免攻击者查看数据库中的隐私数据 数据防篡改：基于区块链等技术，记录数据变化情况，识别攻击者非法篡改磁盘上的数据库文件 1.2 数据泄露问题 在很多针对数据库的攻击行为中，攻击者可绕过上述数据库安全机制，直接从磁盘窃取数据，造成数据泄露问题。\n为了规避此类问题，有效的方案是对数据进行加密，使攻击者仅能从磁盘获取数据密文，无法解密数据，从而解决数据泄露问题。\n1.3 数据库加密方案分类 数据库加密方案较多，本博客仅介绍一些常见的，且适用于大部分场景的加密方案。\n一、按加密位置分类 首先，按加密位置分类，可分为以下6种：\n各方案的基本原理如下：\n应用加密：应用先将数据加密，再使用SQL语句，将数据密文存储至数据库 全密态加密：数据库驱动识别并加密SQL语法中的数据，同时自动解密SQL查询结果。部分数据库产品提供此功能 网关或代理加密：在应用与数据库之间的中继节点中，比如代理或网关中，通过解析网络流量，自动识别与加解密流量中的数据，包括SQL语法中的数据与SQL查询结果。很多云服务、安全厂商提供此服务 加密函数：数据库内置加密函数或存储过程，应用可通过SQL语法主动调用加密函数。大部分数据库产品提供此功能 透明加密：数据库将数据存储至磁盘前，自动加密数据，数据库从磁盘读取数据时，自动解密数据。大部分数据库产品提供此功能 磁盘加密：操作系统处理磁盘读写请求时，自动加密与解密读写到的数据。部分操作系统或云存储服务提供此功能 二、按加密定义方式分类 上述加密方案中，按应用是否主动感知加密过程，可将其分为非自动加密与自动加密。\n非自动加密\n以应用加密为例，用户加密数据的流程如下：\n-- 1 首先，定义表 CREATE TABLE t1 (c1 TEXT, c2 TEXT); -- 2 假设需向t1中存储数据 (1, \u0026#39;data1\u0026#39;)，应用需要先将数据加密，在通过SQL语法将加密后的数据存储至数据库 -- 3 存储数据 INSERT INTO t1 VALUES (\u0026#39;encrypted[1]\u0026#39;, \u0026#39;encrypted[data1]\u0026#39;); -- 4 查询数据时，查询结果为数据密文，数据无法直接使用 SELECT * FROM t1; -- 查询结果为：(\u0026#39;encrypted[1]\u0026#39;, \u0026#39;encrypted[data1]\u0026#39;) -- 5 应用需自行解密查询结果，最终解密后得到原始数据 (1, \u0026#39;data1\u0026#39;) 此类加密方案中，每次涉及数据读写操作时，都需要主动进行加密与解密，操作复杂。\n自动加密\n以透明加密为例，用户在创建数据对象时，比如创建表时，可为表设置加密数据：\nCREATE TABLE t1 (c1 INT, c2 TEXT) WITH (encrypt=on); 然后，向数据库中存储时，数据自动加密存储t1表中的数据，从数据库查询t1表数据时，数据库自动解密数据，查询结果为明文。\nINSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;); SELECT * FROM t1; -- 查询结果：(1, \u0026#39;data1\u0026#39;) 此类加密方案中，用户无需关注加密与解密的过程，仅需为某些数据库对象设置加密属性。常见的自动加密方案中，可为以下几类数据库设置加密熟悉：\n自动加密的对象\n某个数据库，示例：CREATE DATABASE db1 .. WITH (encrypt=on) 某个命名空间，示例：CREATE SCHEMA sch1 .. WITH (encrypt=on) 某个表空间，示例：CREATE TABLESPACE spc1 .. WITH (encrypt=on) 某个表，示例：CREATE TABLE t1 (c1 INT, c2 TEXT) .. WITH (encrypt=on) 某个列，示例：CREATE TABLE t1 (c1 INT encrypt, c2 TEXT) 1.4 数据泄露范围 应用向数据库存储与查询数据时，为解决数据可靠存储、高效查找等问题，数据库可能将数据存放在多个地方。\n1.5 数据库加密方案衡量标准 一、安全性 上一节中提到，在很多介质中均可找到数据，本文衡量数据库加密方案的安全性时，将加密范围作为首要参考。\n介质 对象 应用加密 全密态加密 网关加密 内置函数加密 透明加密 磁盘加密 1 SQL语句 1 1 - - - - 2 数据库内存 1 1 1 - - - 3 表文件 1 1 1 1 1 1 4 索引文件 1 1 1 1 1 1 5 表物化视图文件 1 1 1 1 - 1 6 防篡改系统表文件 1 1 1 - - 1 7 优化系统表文件 1 1 1 1 - 1 8 审计日志文件 1 1 1 - - 1 9 运行日志文件 1 1 1 - - 1 10 预写日志文件 1 1 1 1 1 1 11 回滚日志文件 1 1 1 1 1 1 12 物化节点文件 1 1 1 1 - 1 13 SQL查询结果 1 1 - - - - 14 内存置换文件 1 1 1 - - 1 15 进程崩溃文件 1 1 1 - - 1 16 主备复制流 1 1 1 1 1 - 17 分布式计划流 1 1 1 - - - 18 逻辑复制流 1 1 1 1 - - 19 容灾复制流 1 1 1 1 1 - 20 逻辑备份文件 1 1 1 - - - 21 物理备份文件 1 1 1 1 1 - 二、可用性 加密范围过大，可能会导致数据库功能的可用性变低。例如，应用将数据加密，再将数据库密文存储在数据库中，当用户查询数据密文时，无法在数据密文上进行各类运算，比如：范围查询、模糊查询、排序等。\n加密位置是否在执行模块之前，是影响数据可用性的主要因素。\n在执行模块之前：执行模块将数据密文存至磁盘，并从磁盘读取数据密文，无法在数据密文上运算 在执行模块之后：执行模块处理的数据都是数据明文，执行模块可正常进行计算 三、高性能 四、易用性 五、低膨胀 1.5 各种数据库加密方案的对比 加密方案 安全性 可用性 高性能 易用性 低膨胀 应用加密 全密态加密 网关加密 内置函数加密 透明加密 磁盘加密 1.2 加密方案 序号 加密方案 加密位置 加密原理 优点 缺点 示例 1 代理加密网关 应用客户端 - 应用服务端 数据丰富、改动量小 扩展性低、实现困难 CASB代理网关 2 应用服务端加密 应用服务端 调用加密API 方案灵活 维护复杂 加密模块 3 加密中间件 应用服务端 - 数据库驱动 - - - - 4 数据库加密网关 数据驱动 - 数据库服务端 - - - - 5 数据库加密函数 数据库服务端 - - - - 6 数据库外挂加密 数据库服务端 触发器、视图、外部程序 - - - 7 透明加密 数据库服务端 - 文件系统 - - - - 8 文件加密 文件系统 - - - - 9 磁盘加密 磁盘 - - - - 1.3 方案评估标准 安全性： 功能完整性： 性能： 易用性： 可扩展性： 技术成熟度： 1.6 业界数据库加密方案 2 数据库加密的实现 2.0 通过编程访问数据 #include \u0026lt;stdio.h\u0026gt; #include \u0026lt;stdlib.h\u0026gt; #include \u0026#34;libpq-fe.h\u0026#34; #define Assert(condition) {if (!(condition)) { printf(\u0026#34;ERROR: line %d\\n\u0026#34;, __LINE__); exit(0);} } void demo() { PGconn *conn = PQconnectdb(\u0026#34;host=localhost dbname=postgres\u0026#34;); Assert(conn == CONNECTION_OK); PGresult *res = PQexec(conn, \u0026#34;CREATE TABLE t1 (c1 INT, c2 TEXT);\u0026#34;); Assert(PQresultStatus(res) == PGRES_COMMAND_OK); res = Qexec(conn, \u0026#34;INSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;), (2, \u0026#39;data2\u0026#39;);\u0026#34;); Assert(PQresultStatus(res) == PGRES_COMMAND_OK); res = Qexec(conn, \u0026#34;SELECT * FROM t1;\u0026#34;); Assert(PQresultStatus(res) == PGRES_TUPLES_OK); int row; for (row = 0; row \u0026lt; PQntuples(res); row++) { printf(\u0026#34;row: %d, data: %s\\n\u0026#34;, row, PQgetvalue(res, i, 1)); } PGresult *res = PQexec(conn, \u0026#34;DROP TABLE t1;\u0026#34;); Assert(PQresultStatus(res) == PGRES_COMMAND_OK); PQclear(res); PQfinish(conn); } int main() { demo(); } 2.1 方案一：应用内加密 2.2 方案二：全密态加密 2.3 方案三：网关加密 2.4 方案四：数据库加密函数 2.5 方案五：透明加密 2.6 方案六：磁盘加密 参考 一文读懂十大数据存储加密技术.https://www.secrss.com/articles/30324 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/1-5-database-encryption/","summary":"\u003ch1 id=\"1-数据库加密的背景\"\u003e1 数据库加密的背景\u003c/h1\u003e\n\u003ch2 id=\"11-数据库安全机制\"\u003e1.1 数据库安全机制\u003c/h2\u003e\n\u003cp\u003e应用将数据发送给数据库后，数据库组织数据，将数据存储在文件中，并提供一系列安全机制，保护数据安全。比如：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"dbsec\" loading=\"lazy\" src=\"/images/Security/1-5-database-encryption/dbsec.png\"\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e安全传输：基于TLS等安全协议，保证数据在应用与数据库之间传输的机密性、完整性等，避免攻击者对传输中的数据进行窃听、伪造、篡改等\u003c/li\u003e\n\u003cli\u003e身份认证：基于IP、口令、证书等鉴别用户身份，避免攻击者非法访问数据库\u003c/li\u003e\n\u003cli\u003e访问控制：通过多种访问控制机制，限制攻击者对数据库对象的的访问范围\u003c/li\u003e\n\u003cli\u003e安全审计：记录攻击者在数据库中执行的各项操作\u003c/li\u003e\n\u003cli\u003e数据脱敏：对隐私数据库进行脱敏处理，避免攻击者查看数据库中的隐私数据\u003c/li\u003e\n\u003cli\u003e数据防篡改：基于区块链等技术，记录数据变化情况，识别攻击者非法篡改磁盘上的数据库文件\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"12-数据泄露问题\"\u003e1.2 数据泄露问题\u003c/h2\u003e\n\u003cp\u003e在很多针对数据库的攻击行为中，攻击者可绕过上述数据库安全机制，直接从磁盘窃取数据，造成数据泄露问题。\u003cbr\u003e\n为了规避此类问题，有效的方案是对数据进行加密，使攻击者仅能从磁盘获取数据密文，无法解密数据，从而解决数据泄露问题。\u003c/p\u003e\n\u003ch2 id=\"13-数据库加密方案分类\"\u003e1.3 数据库加密方案分类\u003c/h2\u003e\n\u003cp\u003e数据库加密方案较多，本博客仅介绍一些常见的，且适用于大部分场景的加密方案。\u003c/p\u003e\n\u003ch3 id=\"一按加密位置分类\"\u003e一、按加密位置分类\u003c/h3\u003e\n\u003cp\u003e首先，按加密位置分类，可分为以下6种：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"dbenc\" loading=\"lazy\" src=\"/images/Security/1-5-database-encryption/dbenc.png\"\u003e\u003c/p\u003e\n\u003cp\u003e各方案的基本原理如下：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e应用加密：应用先将数据加密，再使用SQL语句，将数据密文存储至数据库\u003c/li\u003e\n\u003cli\u003e全密态加密：数据库驱动识别并加密SQL语法中的数据，同时自动解密SQL查询结果。部分数据库产品提供此功能\u003c/li\u003e\n\u003cli\u003e网关或代理加密：在应用与数据库之间的中继节点中，比如代理或网关中，通过解析网络流量，自动识别与加解密流量中的数据，包括SQL语法中的数据与SQL查询结果。很多云服务、安全厂商提供此服务\u003c/li\u003e\n\u003cli\u003e加密函数：数据库内置加密函数或存储过程，应用可通过SQL语法主动调用加密函数。大部分数据库产品提供此功能\u003c/li\u003e\n\u003cli\u003e透明加密：数据库将数据存储至磁盘前，自动加密数据，数据库从磁盘读取数据时，自动解密数据。大部分数据库产品提供此功能\u003c/li\u003e\n\u003cli\u003e磁盘加密：操作系统处理磁盘读写请求时，自动加密与解密读写到的数据。部分操作系统或云存储服务提供此功能\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch3 id=\"二按加密定义方式分类\"\u003e二、按加密定义方式分类\u003c/h3\u003e\n\u003cp\u003e上述加密方案中，按应用是否主动感知加密过程，可将其分为非自动加密与自动加密。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e非自动加密\u003cbr\u003e\n以应用加密为例，用户加密数据的流程如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 1 首先，定义表\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2 假设需向t1中存储数据 (1, \u0026#39;data1\u0026#39;)，应用需要先将数据加密，在通过SQL语法将加密后的数据存储至数据库\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 3 存储数据\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;encrypted[1]\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;encrypted[data1]\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 4 查询数据时，查询结果为数据密文，数据无法直接使用\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 查询结果为：(\u0026#39;encrypted[1]\u0026#39;, \u0026#39;encrypted[data1]\u0026#39;)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 5 应用需自行解密查询结果，最终解密后得到原始数据 (1, \u0026#39;data1\u0026#39;)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e此类加密方案中，每次涉及数据读写操作时，都需要主动进行加密与解密，操作复杂。\u003c/p\u003e","title":"传统安全 5 数据库加密"},{"content":" 摘要：本文主要分为3个章节：\n介绍Vastbase基于密码的身份认证机制，介绍密码相关配置参数，指出当前控制参数的局限性，提出PROFILE功能支持细粒度设置密码相关配置参数。 介绍Vastbase的PROFILE功能如何使用，包括管理PROFILE功能、管理PROFILE参数、管理用户PROFILE 介绍Vastbase身份认证流程与原理，介绍PROFILE功能的实现原理 目录\n1 PROFILE 功能背景 1.1 身份认证机制 1.2 身份认证配置 1.3 身份认证优化 2 PROFILE 功能使用 2.1 PROFILE 简单示例 2.2 管理 PROFILE 功能 2.3 管理 PROFILE 参数 2.4 管理 用户 PROFILE 3 PROFILE 功能原理 3.1 身份认证元数据 3.2 身份认证流程 1 PROFILE 功能背景 1.1 身份认证机制 Vastbase身份认证模块，主要采用基于密码的认证机制，常用的密码操作包括：\n创建密码\n创建新用户时，需指定密码。语法示例如下：\nCREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; Vastbase接收密码后，计算密码的哈希值，并将密码哈希值、密码创建时间等存储至系统表中。\n使用密码\n用户连接Vastbase时，需提供密码，使用vsql连接的命令如下：\nvsql -h {host} -p {port} -U u1 -W \u0026#39;u1.password\u0026#39; -d vastbase -r Vastbase会与vsql进行身份认证交互，基于存储的密码哈希值，校验密码是否正确。同时，Vastbase还会进行其他检查，比如：密码是否过期、密码错误次数是否过多等。\n修改密码\n用户修改密码时，语法示例如下：\nALTER USER u1 PASSWORD \u0026#39;u1.newpass\u0026#39;; vastbsae出于安全考虑，会检查新密码是否已曾用过的旧密码相同。\n1.2 身份认证配置 Vastbase会校验、检查密码，包括密码过期、密码复用等场景。在校验前，用户可配置校验、检查参数。在3.0.8.1版本前的Vastbase中，相关参数由GUC控制。\n查询相关GUC的命令如下：\nSELECT name, setting, unit, short_desc, min_val, max_val, boot_val FROM pg_settings WHERE name in (\u0026#39;password_effect_time\u0026#39;, \u0026#39;failed_login_attempts\u0026#39;, \u0026#39;password_lock_time\u0026#39;, \u0026#39;password_reuse_time\u0026#39;, \u0026#39;password_reuse_max\u0026#39;); 相关GUC的功能与取值如下：\n编号 GUC参数 参数功能 取值范围 默认值 单位 1 password_effect_time 使用密码时，检查密码创建时间，控制密码有效期 [30, 36500] 36500 天 2 failed_login_attempts 使用密码时，控制密码错误次数阈值，如果次数达到阈值，则账号会被暂时锁定 [1,1000] 5 次 3 password_lock_time 使用密码时，如果密码错误次数达到阈值，控制账号锁定时间 [1, 525600] 1440 分钟 4 password_reuse_time 修改密码时，如果新密码与曾使用过的旧密码相同，控制不能与近期使用过的相同 [30, 90] 30 天 5 password_reuser_max 修改密码时，如果新密码与曾使用过的旧密码相同，控制不能与最近几次使用过的相同 [1, 100] 3 次 1.3 身份认证优化 身份认证问题：\n上述5个GUC参数，对所有用户生效，即所有用户使用相同的配置参数。但是，一个集群，存在多个用户，每个用户角色不同，有高权限的系统管理员，有低权限的普通用户，不同用户的密码有效期、密码错误阈值等，要求也应不同。通过GUC参数，控制粒度较粗，无法详细为不同用户设置不用的配置参数。\n身份认证优化：\n3.0.8.1版本Vastbase，在身份认证模块，主要针对配置方式进行了优化。PROFILE功能，解决相关配置参数控制粒度粗的问题。\nPROFILE功能，支持为不用的用户，设置不同的配置参数，以实现细粒度控制。包括密码有效期、密码错误次数阈值等在内的参数，默认情况下，不再由GUC参数password_effect_time、failed_login_attempts等控制，而是由同名或名称接近的PROFILE参数控制，不用用户可设置不用的PROFILE参数。\nOracle兼容性：\nOracle 8版本开始支持PROFILE特性，为保证兼容性，提高易用性，Vastbase的PROFILE特性，在参数名称、参数功能、参数取值范围、参数单位、参数配置范围等，将与Oracle一致。\nOracle 23版本支持18个PROFILE参数，分为密码管理、资源管理类。Vastbase支持7个PROFILE参数，主要是密码管理类。\n注意：在Oracle兼容性下，才可使用PROFILE功能。\n2 PROFILE 功能使用 2.1 PROFILE 简单示例 首先，以一个简单的例子，简单介绍PROFILE的使用方法。\n假设，需创建用户u1，该用户的密码有效期为10天，密码错误次数阈值为3次。\n创建PROFILE，可理解为创建配置组，创建时可同时设置参数值。\nCREATE PROFILE pro1 LIMIT password_effect_time 10 failed_login_attempts 3; 创建用户，并为用户设置PROFILE，即设置配置组。\nCREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39; PROFILE pro1; 用户u1的密码有效期、密码错误次数阈值等，将不再有GUC参数控制，而是由PROFILE参数控制，PROFILE参数存储于系统表中。\nVastbase PROFILE功能的使用方法，与Oracle基本一致。\n2.2 管理 PROFILE 功能 PROFILE功能是否开启，由GUC参数resource_limit控制。\nresource_limit取值为on，表示开启PROFILE功能，开启PROFILE功能后，以下5个GUC参数，将不再生效，而是由PROFILE参数代替，PROFILE参数存储于系统表中：\npassword_effect_time failed_login_attempts password_lock_time password_reuse_time password_reuse_max 另外，身份认证成功的用户，用户会话超时时间，也不再由GUC参数session_timeout控制，由PROFILE参数代替。\n对于新安装的3.0.8.1及之后版本的Vastbase集群，如果是Oracle兼容性，resource_limit默认值为on，即默认开启PROFILE功能，并替代6个GUC参数。\n对于已存在的3.0.8.1之前的Vastbase集群，升级至3.0.8.1时，resource_limit默认值为off，即升级场景不会修改数据库行为，不会导致6个GUC参数失效。\n用户可手动设置GUC参数resource_limit的值为on或off，以开启或关闭PRIFILE功能。resource_limit为Postmaster级别的GUC参数，设置后，需重启集群，才能生效。\n2.3 管理 PROFILE 参数 PROFILE功能新增3个语法，支持创建、修改、删除PROFILE，语法格式如下：\n-- 创建 CREATE PROFILE profile_name [ LIMIT {setting_name setting_value ...} ] -- 修改 ALTER PROFILE profile_name LIMIT {setting_name setting_value ...} -- 删除 DROP PROFILE [IF EXISTS] profile_name [, profile_name, ...] 其中，setting_name表示PROFILE配置参数，目前支持7个参数：\nPROFILE配置名 被替代的GUC配置名 功能 password_life_time password_effect_time 无变化 password_grace_time - 如果密码超过有效期，控制继续使用账号的宽容期 failed_login_attempts failed_login_attempts 无变化 password_lock_time password_lock_time 无变化 password_reuse_time password_reuse_time 无变化 password_reuse_max password_reuse_max 无变化 idle_time session_timeout 无变化 与原GUC相比，上述参数的取值范围、参数单位等存在差异。\n使用示例如下：\n创建PROFILE\n-- 创建PROFILE，参数均使用默认值 CREATE PROFILE pro1; -- 创建PROFILE，同时设置参数值，可设置1个或多个参数，参数之间使用空格分隔。在pro2中，为主动设置的其他5个参数，均使用默认值 CREATE PROFILE pro2 LIMIT password_life_time 30 failed_login_attempts 3; -- 参数取值可设置为 unlimited，即对相关功能不做限制。例如将password_life_time设置为unlimited，表示密码永远不会过期 CREATE PROFILE pro3 LIMIT password_life_time unlimited; 查询PROFILE\n-- 所有PROFILE均存储于系统表中 SELECT * FROM vb_profiles; 安装集群时，Vastbase内置1个名为default的PROFILE，该PROFILE中7个参数取值均为unlimited。查询vb_profiles的结果如下：\nprofile | setname | setval | valunit | valtype | valmin | valmax | valdefault | setkind -- unlimited含义 ---------+-----------------------+-----------+---------+--------------------+------------+------------+---------- default | failed_login_attempts | unlimited | times | int | 1 | 2147483646 | 10 | password -- 等价INT_MAX，允许无限次登录失败 default | password_lock_time | unlimited | days | double | 0.00001 | 24855 | 1 | password -- 等价0，账号永远不锁 default | password_life_time | unlimited | days | double | 0.00001 | 24855 | 180 | password -- 等价DBL_MAX，密码永远有效 default | password_grace_time | unlimited | days | double | 0.00001 | 24855 | 7 | password -- 等价DBL_MAX，密码过期也永远可用 default | password_reuse_time | unlimited | days | double | 0.00001 | 24855 | 1 | password -- 等价0，密码可无限复用 default | password_reuse_max | unlimited | times | int | 1 | 2147483646 | 1 | password -- 等价INT_MAX，密码可无限复用 default | idle_time | unlimited | minutes | double | 0.00001 | 2147483646 | 10 | kernel -- 等价INT_MAX，会话永远不过期 -- 提示：0.00001 days约为0.8 second，24855 days约为70 years 各列含义如下：\n列名 含义 profile PROFILE 名，可理解为配置组 setname PROFILE 配置参数名 setval 配置参数 实际值 valunit 参数值 单位 valtype 参数值 数据类型 valmin 参数值 最小值 valmax 参数值 最大值 valdefault 参数值 默认值，执行CREATE PROFILE语法时，未主动设置值的配置参数，默认使用该列中的值 settype 配置参数 分类 另外，查询视图DBA_PROFILES的结果，与查询系统表vb_profiles效果接近。\nSELECT * FROM DBA_PROFILES; 修改PROFILE\n-- 修改PROFILE，可修改1个或多个参数，参数之间使用空格分隔 ALTER PROFILE pro1 LIMIT password_life_time 100 password_reuse_max unlimited; 删除PROFILE\nDROP PROFILE pro1; -- 删除PROFILE，一次可删除多个 DROP PROFILE IF EXISTS pro1,pro2,pro3; -- 注意：Vastbase内置的名为default的PROFILE不能被删除 2.4 管理 用户 PROFILE PROFILE功能支持为不同用户设置、修改不同的PROFILE，即不同的配置组。设置语法如下：\n-- 创建用户时，为用户设置PROFILE CREATE USER user_name PASSWORD password [ PROFILE profile_name ] -- 对于已存在的用户，修改用户PROFILE ALTER USER user_name [ PROFILE profile_name ] 如果未主动为用户设置PROFILE，则用户默认使用名为default的PROFILE。\n使用示例如下：\n设置用户PROFILE\n-- 前提：请确保已通过 CREATE PROFILE 语法设置对应的PROFILE CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39; PROFILE pro1; 查询用户PROFILE\nSELECT * FROM vb_user_profiles WHERE rolname = \u0026#39;u1\u0026#39;; 查询结果示例如下：\nroloid | rolname | profile --------+---------+--------- 28214 | u1 | pro1 修改用户PROFILE\n-- 前提：请确保已通过 CREATE PROFILE 语法设置对应的PROFILE ALTER USER u1 PROFILE pro2; 3 PROFILE 功能原理 3.1 身份认证元数据 系统表pg_authid\n创建用户时，Vastbase会为用户分配唯一的用户id，并在系统表pg_authid中，记录用户名、用户id、密码哈希值等信息。\nCREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; SELECT rolname,oid,rolpassword FROM pg_authid WHERE rolname = \u0026#39;u1\u0026#39;; -- 示例输出： rolname | oid | rolpassword ---------+-------+---------------------------- u1 | 28214 | sha25684899a888d999b97... 系统表pg_user_status\n创建用户时，Vastbase会在系统表pg_user_status中，初始话密码失败次数、密码锁定状态、密码锁定时间等信息。\n登录用户时，如果密码错误，Vastbase会更新系统表中密码失败次数等信息，并校验是否达到锁定条件。\nSELECT roloid,failcount,rolstatus，locktime FROM pg_user_status WHERE roloid = 28214; -- 示例输出： roloid | failcount | rolstatus | locktime --------+-----------+-----------+-------------------------- 28214 | 0 | 0 | 2025-05-01 10:40:41.... 系统表pg_auth_history\n修改密码时，Vastbase会在系统表pg_auth_history中，记录所有曾用过的密码\nALTER USER u1 PASSWORD \u0026#39;u1.newpass\u0026#39;; SELECT roloid,passwordtime,rolpassword FROM pg_auth_history WHERE roloid = 28214; -- 示例输出： roloid | passwordtime | rolpassword --------+-------------------------+------------------------------ 28214 | 2025-05-01 10:40:41.... | sha25684899a888d999b97... 28214 | 2025-05-08 13:25:07.... | sha256b019838a88f989c8... 3.2 身份认证流程 未开启PROFILE功能的场景下，身份认证的简要流程如下图所示：（途中系统表1、2、3分别代表pg_authid、pg_user_status、pg_auth_history。）\n开启PROFILE功能的场景下，上述流程中，第8步将不再从GUC中获取密码相关参数，而是替换为以下2步：\n根据用户id，从系统表vb_user_profiles中，查找用户使用的PROFILE。 从系统表vb_profiles中，查找指定PROFILE的7个配置参数，并缓存 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/2-blog-profile/","summary":"\u003cblockquote\u003e\n\u003cp\u003e摘要：本文主要分为3个章节：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e介绍Vastbase基于密码的身份认证机制，介绍密码相关配置参数，指出当前控制参数的局限性，提出PROFILE功能支持细粒度设置密码相关配置参数。\u003c/li\u003e\n\u003cli\u003e介绍Vastbase的PROFILE功能如何使用，包括管理PROFILE功能、管理PROFILE参数、管理用户PROFILE\u003c/li\u003e\n\u003cli\u003e介绍Vastbase身份认证流程与原理，介绍PROFILE功能的实现原理\u003c/li\u003e\n\u003c/ol\u003e\u003c/blockquote\u003e\n\u003cp\u003e\u003cstrong\u003e目录\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-PROFILE-%E5%8A%9F%E8%83%BD%E8%83%8C%E6%99%AF\"\u003e1 PROFILE 功能背景\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-1-%E8%BA%AB%E4%BB%BD%E8%AE%A4%E8%AF%81%E6%9C%BA%E5%88%B6\"\u003e1.1 身份认证机制\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-%E8%BA%AB%E4%BB%BD%E8%AE%A4%E8%AF%81%E9%85%8D%E7%BD%AE\"\u003e1.2 身份认证配置\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-3-%E8%BA%AB%E4%BB%BD%E8%AE%A4%E8%AF%81%E4%BC%98%E5%8C%96\"\u003e1.3 身份认证优化\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-PROFILE-%E5%8A%9F%E8%83%BD%E4%BD%BF%E7%94%A8\"\u003e2 PROFILE 功能使用\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#2-1-PROFILE-%E7%AE%80%E5%8D%95%E7%A4%BA%E4%BE%8B\"\u003e2.1 PROFILE 简单示例\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-2-%E7%AE%A1%E7%90%86-PROFILE-%E5%8A%9F%E8%83%BD\"\u003e2.2 管理 PROFILE 功能\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-3-%E7%AE%A1%E7%90%86-PROFILE-%E5%8F%82%E6%95%B0\"\u003e2.3 管理 PROFILE 参数\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-4-%E7%AE%A1%E7%90%86-%E7%94%A8%E6%88%B7-PROFILE\"\u003e2.4 管理 用户 PROFILE\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-PROFILE-%E5%8A%9F%E8%83%BD%E5%8E%9F%E7%90%86\"\u003e3 PROFILE 功能原理\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#3-1-%E8%BA%AB%E4%BB%BD%E8%AE%A4%E8%AF%81%E5%85%83%E6%95%B0%E6%8D%AE\"\u003e3.1 身份认证元数据\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-2-%E8%BA%AB%E4%BB%BD%E8%AE%A4%E8%AF%81%E6%B5%81%E7%A8%8B\"\u003e3.2 身份认证流程\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"1-profile-功能背景\"\u003e1 PROFILE 功能背景\u003c/h1\u003e\n\u003ch2 id=\"11-身份认证机制\"\u003e1.1 身份认证机制\u003c/h2\u003e\n\u003cp\u003eVastbase身份认证模块，主要采用基于密码的认证机制，常用的密码操作包括：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e创建密码\u003cbr\u003e\n创建新用户时，需指定密码。语法示例如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eVastbase接收密码后，计算密码的哈希值，并将密码哈希值、密码创建时间等存储至系统表中。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e使用密码\u003cbr\u003e\n用户连接Vastbase时，需提供密码，使用vsql连接的命令如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eh\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e{\u003c/span\u003e\u003cspan class=\"k\"\u003ehost\u003c/span\u003e\u003cspan class=\"err\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e{\u003c/span\u003e\u003cspan class=\"n\"\u003eport\u003c/span\u003e\u003cspan class=\"err\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.password\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evastbase\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eVastbase会与vsql进行身份认证交互，基于存储的密码哈希值，校验密码是否正确。同时，Vastbase还会进行其他检查，比如：密码是否过期、密码错误次数是否过多等。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e修改密码\u003cbr\u003e\n用户修改密码时，语法示例如下：\u003c/p\u003e","title":"海量 2 博客 profile"},{"content":" 1 CREATE/ALTER/DROP PROFILE 2 CREATE/ALTER USER .. PROFILE 3 验证profile生效 验证 failed_login_attempts 与 password_lock_time 验证 password_life_time 与 password_grace_time 验证 password_reuse_time 和 password_reuse_max 验证 idle_time 3 view CREATE PROFILE pro1 limit password_reuse_time 0.00002 password_reuse_max 10; -- 1.72s CREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39; PROFILE pro1; ALTER USER u1 PASSWORD \u0026#39;u1.pass2\u0026#39;; ALTER USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; -- error, interval \u0026lt; password_reuse_time \\! sleep 2 ALTER USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; -- succeed, interval \u0026gt; password_reuse_time ALTER PROFILE pro1 LIMIT password_reuse_time 0.00005; -- 4.32s ALTER USER u1 PASSWORD \u0026#39;u1.pass3\u0026#39;; ALTER USER u1 PASSWORD \u0026#39;u1.pass4\u0026#39;; ALTER USER u1 PASSWORD \u0026#39;u1.pass3\u0026#39;; -- error, interval \u0026lt; password_reuse_time \\! sleep 5 ALTER USER u1 PASSWORD \u0026#39;u1.pass3\u0026#39;; -- succeed, interval \u0026gt; password_reuse_time 1 CREATE/ALTER/DROP PROFILE -- check profile feature SHOW resource_limit; -- ================================ part 1 ================================ -- create profile CREATE PROFILE pro1; -- succeed: can set setting CREATE PROFILE pro2 LIMIT failed_login_attempts 10; -- succeed: can set more settings CREATE PROFILE pro3 LIMIT failed_login_attempts 10 password_lock_time 20 password_life_time 30 password_grace_time 40 password_reuse_time 50 password_reuse_max 60 idle_time 80; -- succeed: repeated settings are allowed CREATE PROFILE pro4 LIMIT password_life_time 10 password_life_time 20.2; -- succeed: setting value could be \u0026#39;unlimited\u0026#39; CREATE PROFILE pro5 LIMIT failed_login_attempts unlimited password_lock_time 10 password_life_time unlimited; -- succeed: name max len is 64, name will be truncated CREATE PROFILE aaaaa111111111122222222223333333333444444444455555555556666666666; -- too long, max 64, wi -- truncated name: aaaaa1111111111222222222233333333334444444444555555555566666666 SELECT profile,count(*) FROM vb_profiles GROUP BY profile ORDER BY profile; SELECT * FROM vb_profiles WHERE profile = \u0026#39;pro5\u0026#39; ORDER BY setname; -- error: profile name is invalid CREATE PROFILE 1; -- int CREATE PROFILE 1.1; -- numeric -- error: profile already exists CREATE PROFILE default LIMIT failed_login_attempts 10; CREATE PROFILE pro1 LIMIT failed_login_attempts 10; /* error: setting is invalid, supported settings: unit type min max ------------------------+---------+----------+---------+------------+---- failed_login_attempts | times | int | 1 | 2147483646 | 10 password_lock_time | days | double | 0.00001 | 24855 | 1 password_life_time | days | double | 0.00001 | 24855 | 180 password_grace_time | days | double | 0.00001 | 24855 | 7 password_reuse_time | days | double | 0.00001 | 24855 | 1 password_reuse_max | times | int | 1 | 2147483646 | 1 idle_time | minutes | double | 0.00001 | 2147483646 | 10 */ CREATE PROFILE epro2 LIMIT data_directory anyvalue; CREATE PROFILE epro3 LIMIT password_effect_time 10; CREATE PROFILE epro4 LIMIT 10 failed_login_attempts; -- error: setting lose value CREATE PROFILE epro5 LIMIT failed_login_attempts; CREATE PROFILE epro6 LIMIT failed_login_attempts 10 password_lock_time; -- error: setting value type is invalud CREATE PROFILE epro7 LIMIT failed_login_attempts \u0026#39;iamstring\u0026#39;; CREATE PROFILE epro8 LIMIT failed_login_attempts 1.1; CREATE PROFILE epro9 LIMIT failed_login_attempts noint; CREATE PROFILE epro10 LIMIT failed_login_attempts default; -- error: setting value is out of limit CREATE PROFILE epro11 LIMIT failed_login_attempts 0; CREATE PROFILE epro12 LIMIT failed_login_attempts 1 password_lock_time 0; CREATE PROFILE epro13 LIMIT password_lock_time 24856; CREATE PROFILE epro14 LIMIT password_lock_time 0.000001; SELECT profile,count(*) FROM vb_profiles GROUP BY profile ORDER BY profile; DROP PROFILE pro1, pro2, pro3, pro4, pro5; DROP PROFILE aaaaa111111111122222222223333333333444444444455555555556666666666; -- ================================ part 2 ================================ -- alter profile CREATE PROFILE pro1; CREATE PROFILE pro2 LIMIT failed_login_attempts 100; CREATE PROFILE pro3 LIMIT password_lock_time 20; -- succeed: can set setting ALTER PROFILE pro1 LIMIT failed_login_attempts 1000; -- succeed: can set more settings ALTER PROFILE pro2 LIMIT failed_login_attempts 10 password_lock_time 20 password_life_time 30 password_grace_time 40 password_reuse_time 50 password_reuse_max 60 idle_time 80; -- succeed: setting value could be \u0026#39;unlimited\u0026#39; ALTER PROFILE pro3 LIMIT failed_login_attempts unlimited password_lock_time 10 password_life_time unlimited; -- succeed: can alter default profile ALTER PROFILE default LIMIT failed_login_attempts 80 password_reuse_time 70.3; SELECT * FROM vb_profiles ORDER BY profile,setname; -- error: profile name is invalid ALTER PROFILE 1 LIMIT failed_login_attempts 10; -- int ALTER PROFILE 1.1 LIMIT failed_login_attempts 10; -- numeric ALTER PROFILE aaaaa111111111122222222223333333333444444444455555555556666666666 LIMIT failed_login_attempts 10; -- too long, max 64 -- error: repeated settings are not allowed ALTER PROFILE pro3 LIMIT password_reuse_time 10 password_reuse_time 20.2; -- error: profile doesn\u0026#39;t exist ALTER PROFILE epro1 LIMIT failed_login_attempts 10; ALTER PROFILE epro2 LIMIT failed_login_attempts 10; /* error: setting is invalid */ ALTER PROFILE pro1 LIMIT data_directory anyvalue; ALTER PROFILE pro1 LIMIT password_effect_time 10; ALTER PROFILE pro1 LIMIT 10 failed_login_attempts; -- error: setting lose value ALTER PROFILE pro1 LIMIT failed_login_attempts; ALTER PROFILE pro1 LIMIT failed_login_attempts 10 password_lock_time; -- error: setting value type is invalud ALTER PROFILE pro1 LIMIT failed_login_attempts \u0026#39;iamstring\u0026#39;; ALTER PROFILE pro1 LIMIT failed_login_attempts 1.1; ALTER PROFILE pro1 LIMIT failed_login_attempts noint; ALTER PROFILE pro1 LIMIT failed_login_attempts default; -- error: setting value is out of limit ALTER PROFILE pro1 LIMIT failed_login_attempts 0; ALTER PROFILE pro1 LIMIT failed_login_attempts 1 password_lock_time 0; ALTER PROFILE pro1 LIMIT password_lock_time 24856; ALTER PROFILE pro1 LIMIT password_lock_time 0.000001; DROP PROFILE pro1, pro2, pro3; -- ================================ part 3 ================================ -- drop profile CREATE PROFILE pro1; CREATE PROFILE pro2 LIMIT failed_login_attempts 100; CREATE PROFILE pro3 LIMIT password_lock_time 20; CREATE PROFILE pro4; CREATE PROFILE pro5; -- succeed: drop profile DROP PROFILE pro1; DROP PROFILE IF EXISTS pro1; DROP PROFILE IF EXISTS pro1, pro2, pro3; SELECT profile,count(*) FROM vb_profiles GROUP BY profile; -- error: profile doesn\u0026#39;t exist DROP PROFILE pro0; DROP PROFILE pro1, pro4, pro5; -- error: default profile can\u0026#39;t be dropped DROP PROFILE default; DROP PROFILE pro4, default; DROP PROFILE IF EXISTS pro4, pro5; 2 CREATE/ALTER USER .. PROFILE -- ================================ part 4 ================================ -- set profile for user SELECT * FROM vb_user_profiles; CREATE PROFILE pro1; CREATE PROFILE pro2; -- succeed: set profile for user CREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39; PROFILE pro1; CREATE USER u2 PASSWORD \u0026#39;u2.pass1\u0026#39; PROFILE pro1; CREATE USER u3 PASSWORD \u0026#39;u3.pass1\u0026#39; PROFILE default; CREATE USER u4 PASSWORD \u0026#39;u4.pass1\u0026#39;; -- error: profile doesn\u0026#39;t exist CREATE USER eu1 PASSWORD \u0026#39;u4.pass1\u0026#39; PROFILE pro1000; -- error: profile name invalid CREATE USER eu2 PASSWORD \u0026#39;u4.pass1\u0026#39; PROFILE 1; CREATE USER eu3 PASSWORD \u0026#39;u4.pass1\u0026#39; PROFILE; SELECT * FROM vb_user_profiles; DROP USER IF EXISTS u1, u2, u3, u4; -- catalog also changed SELECT * FROM vb_user_profiles; DROP PROFILE IF EXISTS pro1, pro2; -- ================================ part 5 ================================ -- alter user profile CREATE PROFILE pro1; CREATE PROFILE pro2; CREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; CREATE USER u2 PASSWORD \u0026#39;u2.pass1\u0026#39; PROFILE pro2; CREATE USER u3 PASSWORD \u0026#39;u3.pass1\u0026#39; PROFILE default; -- succeed: alter user set profile ALTER USER u1 PROFILE pro1; ALTER USER u2 PROFILE default; ALTER USER u3 PROFILE pro1; -- error: profile doesn\u0026#39;t exist ALTER USER u1 PROFILE pro1000; -- error: profile name invalid ALTER USER u1 PROFILE 1; ALTER USER u1 PROFILE; SELECT * FROM vb_user_profiles ORDER BY roloid; DROP USER IF EXISTS u1, u2, u3; DROP PROFILE IF EXISTS pro1, pro2; -- ================================ part 6 ================================ -- drop user and profile CREATE PROFILE pro1; CREATE PROFILE pro2; CREATE PROFILE pro3; CREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39; PROFILE pro1; CREATE USER u2 PASSWORD \u0026#39;u2.pass1\u0026#39; PROFILE pro2; -- succeed: drop user SELECT * FROM vb_user_profiles WHERE rolname = \u0026#39;u1\u0026#39;; DROP USER u1; SELECT * FROM vb_user_profiles WHERE rolname = \u0026#39;u1\u0026#39;; -- error: can\u0026#39;t drop profile if any user are using it DROP PROFILE pro2; -- error: default profile can\u0026#39;t be dropped DROP PROFILE default; DROP PROFILE pro3, default; DROP PROFILE default, pro3; SELECT * FROM vb_user_profiles ORDER BY roloid; DROP USER IF EXISTS u1, u2; DROP PROFILE IF EXISTS pro1, pro2, pro3; 3 验证profile生效 验证 failed_login_attempts 与 password_lock_time CREATE PROFILE pro1 LIMIT failed_login_attempts 3 password_lock_time 0.0001; CREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39; PROFILE pro1; -- 运行登录失败3次，失败后锁定8秒 CREATE USER u2 PASSWORD \u0026#39;u2.pass1\u0026#39;; -- 允许登录失败无数次 vsql -p 5432 -d postgres -U u1 -W \u0026#34;u1.error1\u0026#34; -c \u0026#34;SELECT 1;\u0026#34; vsql -p 5432 -d postgres -U u1 -W \u0026#34;u1.error1\u0026#34; -c \u0026#34;SELECT 1;\u0026#34; vsql -p 5432 -d postgres -U u1 -W \u0026#34;u1.error1\u0026#34; -c \u0026#34;SELECT 1;\u0026#34; vsql -p 5432 -d postgres -U u1 -W \u0026#34;u1.pass1\u0026#34; -c \u0026#34;SELECT 1;\u0026#34; -- sleep 8s vsql -p 5432 -d postgres -U u1 -W \u0026#34;u1.pass1\u0026#34; -c \u0026#34;SELECT 1;\u0026#34; -- u2 vsql -p 5432 -d postgres -U u2 -W \u0026#34;u2.error1\u0026#34; -c \u0026#34;SELECT 1;\u0026#34; vsql -p 5432 -d postgres -U u2 -W \u0026#34;u2.error1\u0026#34; -c \u0026#34;SELECT 1;\u0026#34; vsql -p 5432 -d postgres -U u2 -W \u0026#34;u2.error1\u0026#34; -c \u0026#34;SELECT 1;\u0026#34; vsql -p 5432 -d postgres -U u2 -W \u0026#34;u2.pass1\u0026#34; -c \u0026#34;SELECT 1;\u0026#34; -- sleep 8s vsql -p 5432 -d postgres -U u2 -W \u0026#34;u2.pass1\u0026#34; -c \u0026#34;SELECT 1;\u0026#34; vsql -p 5432 -d postgres -c \u0026#34;DROP USER u1,u2\u0026#34; 验证 password_life_time 与 password_grace_time CREATE PROFILE pro2 LIMIT password_life_time 0.0001 -- 8s password_grace_time 0.0001; CREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39; PROFILE pro2; -- 密码有效期为8s，密码宽容期也为8s CREATE USER u2 PASSWORD \u0026#39;u2.pass1\u0026#39;; -- 密码有效期无限制 \\q vsql -p 5432 -d postgres -U u1 -W \u0026#34;u1.pass1\u0026#34; -c \u0026#34;SELECT 1;\u0026#34; -- sleep 8s vsql -p 5432 -d postgres -U u1 -W \u0026#34;u1.pass1\u0026#34; -c \u0026#34;SELECT 1;\u0026#34; -- sleep 8s vsql -p 5432 -d postgres -U u1 -W \u0026#34;u1.pass1\u0026#34; -c \u0026#34;SELECT 1;\u0026#34; vsql -p 5432 -d postgres -U u2 -W \u0026#34;u2.pass1\u0026#34; -c \u0026#34;SELECT 1;\u0026#34; -- sleep 8s vsql -p 5432 -d postgres -U u2 -W \u0026#34;u2.pass1\u0026#34; -c \u0026#34;SELECT 1;\u0026#34; -- sleep 8s vsql -p 5432 -d postgres -U u2 -W \u0026#34;u2.pass1\u0026#34; -c \u0026#34;SELECT 1;\u0026#34; 验证 password_reuse_time 和 password_reuse_max CREATE PROFILE pro3 LIMIT password_reuse_time 0.0001 -- 不能用过去8秒使用过的密码 password_reuse_max 100; -- 不能用过去100次使用过的 DROP USER IF EXISTS u1,u2; CREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39; PROFILE pro3; ALTER USER u1 PASSWORD \u0026#39;u1.pass2\u0026#39;; ALTER USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; SELECT pg_sleep(3); ALTER USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; SELECT pg_sleep(3); ALTER USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; SELECT pg_sleep(3); ALTER USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; CREATE USER u2 PASSWORD \u0026#39;u2.pass1\u0026#39;; ALTER USER u2 PASSWORD \u0026#39;u2.pass2\u0026#39;; ALTER USER u2 PASSWORD \u0026#39;u2.pass1\u0026#39;; ALTER USER u2 PASSWORD \u0026#39;u2.pass2\u0026#39;; ALTER USER u2 PASSWORD \u0026#39;u2.pass1\u0026#39;; -- ----------------------------- CREATE PROFILE pro4 LIMIT password_reuse_max 2 -- 不能用过去2次使用过的 password_reuse_time 20; DROP USER IF EXISTS u1,u2; CREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39; PROFILE pro4; ALTER USER u1 PASSWORD \u0026#39;u1.pass2\u0026#39;; ALTER USER u1 PASSWORD \u0026#39;u1.pass3\u0026#39;; ALTER USER u1 PASSWORD \u0026#39;u1.pass4\u0026#39;; ALTER USER u1 PASSWORD \u0026#39;u1.pass3\u0026#39;; -- error ALTER USER u1 PASSWORD \u0026#39;u1.pass2\u0026#39;; -- ok 验证 idle_time CREATE PROFILE pro5 LIMIT idle_time 0.1; -- 6s DROP USER IF EXISTS u1,u2; CREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39; PROFILE pro5; CREATE USER u2 PASSWORD \u0026#39;u2.pass1\u0026#39;; \\q vsql -p 5432 -d postgres -U u1 -W \u0026#34;u1.pass1\u0026#34; -r SELECT 1; -- 不用pg_sleep \\! sleep 7 SELECT 1; \\q vsql -p 5432 -d postgres -U u2 -W \u0026#34;u2.pass1\u0026#34; -r SELECT 1; -- 不用pg_sleep \\! sleep 7 SELECT 1; 3 view CREATE OR REPLACE VIEW SYS.DBA_PROFILES AS SELECT profile \u0026#34;PROFILE\u0026#34;, setname \u0026#34;RESOURCE_NAME\u0026#34;, setkind \u0026#34;RESOURCE_TYPE\u0026#34;, setval \u0026#34;LIMIT\u0026#34; FROM vb_profiles; 升级 审计 oid knl_u_misc_init AuthenticatedUserId = InvalidOid ResetStreamStatus AuthenticatedUserId = InvalidOid InitializeSessionUserId AuthenticatedUserId = SearchSysCache(rolname / useroid) InitializeSessionUserIdStandalone AuthenticatedUserId = BOOTSTRAP_SUPERUSERID SessionUserId CurrentUserId create_session_context # get_setting_from_guc_or_profile enable_session_sig_alarm # get_setting_from_guc_or_profile ReadCommand # get_setting_from_guc_or_profile enable_session_sig_alarm # get_setting_from_guc_or_profile disable_session_sig_alarm TpoolSchedulerMain CheckSessionTimeout # get_setting_from_guc_or_profile handle_sig_alarm CheckSessionTimeout # get_setting_from_guc_or_profile WaitMission # get_setting_from_guc_or_profile enable_session_sig_alarm ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/2-testcase-profile/","summary":"\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-CREATE-x2F-ALTER-x2F-DROP-PROFILE\"\u003e1 CREATE/ALTER/DROP PROFILE\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-CREATE-x2F-ALTER-USER-PROFILE\"\u003e2 CREATE/ALTER USER .. PROFILE\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-%E9%AA%8C%E8%AF%81profile%E7%94%9F%E6%95%88\"\u003e3 验证profile生效\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E9%AA%8C%E8%AF%81-failed-login-attempts-%E4%B8%8E-password-lock-time\"\u003e验证 failed_login_attempts 与 password_lock_time\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E9%AA%8C%E8%AF%81-password-life-time-%E4%B8%8E-password-grace-time\"\u003e验证 password_life_time 与 password_grace_time\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E9%AA%8C%E8%AF%81-password-reuse-time-%E5%92%8C-password-reuse-max\"\u003e验证 password_reuse_time 和 password_reuse_max\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E9%AA%8C%E8%AF%81-idle-time\"\u003e验证 idle_time\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-view\"\u003e3 view\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003elimit\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_reuse_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e00002\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_reuse_max\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 1.72s\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error, interval \u0026lt; password_reuse_time\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esleep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- succeed, interval \u0026gt; password_reuse_time\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_reuse_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e00005\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 4.32s\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass3\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass4\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass3\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error, interval \u0026lt; password_reuse_time\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esleep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass3\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- succeed, interval \u0026gt; password_reuse_time\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"1-createalterdrop-profile\"\u003e1 CREATE/ALTER/DROP PROFILE\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- check profile feature\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSHOW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eresource_limit\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- ================================ part 1 ================================\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e--                              create profile\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- succeed: can set setting\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- succeed: can set more settings\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_lock_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e20\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_life_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e30\u003c/span\u003e\u003cspan class=\"w\"\u003e   \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_grace_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e40\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_reuse_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e50\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_reuse_max\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e60\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eidle_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e80\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- succeed: repeated settings are allowed\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro4\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_life_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_life_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e20\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- succeed: setting value could be \u0026#39;unlimited\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro5\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eunlimited\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_lock_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_life_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eunlimited\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- succeed: name max len is 64, name will be truncated\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eaaaaa111111111122222222223333333333444444444455555555556666666666\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- too long, max 64, wi\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- truncated name: aaaaa1111111111222222222233333333334444444444555555555566666666\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprofile\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_profiles\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eGROUP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprofile\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprofile\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_profiles\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprofile\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pro5\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esetname\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: profile name is invalid\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- int\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- numeric\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: profile already exists\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/*\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003eerror: setting is invalid, supported settings:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e                              unit      type        min         max\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    ------------------------+---------+----------+---------+------------+----\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    failed_login_attempts   | times   | int      | 1       | 2147483646 | 10\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    password_lock_time      | days    | double   | 0.00001 | 24855      | 1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    password_life_time      | days    | double   | 0.00001 | 24855      | 180\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    password_grace_time     | days    | double   | 0.00001 | 24855      | 7\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    password_reuse_time     | days    | double   | 0.00001 | 24855      | 1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    password_reuse_max      | times   | int      | 1       | 2147483646 | 1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    idle_time               | minutes | double   | 0.00001 | 2147483646 | 10\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e*/\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eepro2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edata_directory\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eanyvalue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eepro3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_effect_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eepro4\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: setting lose value\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eepro5\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eepro6\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_lock_time\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: setting value type is invalud\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eepro7\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;iamstring\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eepro8\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eepro9\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003enoint\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eepro10\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: setting value is out of limit\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eepro11\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eepro12\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_lock_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eepro13\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_lock_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e24856\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eepro14\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_lock_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e000001\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprofile\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_profiles\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eGROUP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprofile\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprofile\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro5\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eaaaaa111111111122222222223333333333444444444455555555556666666666\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- ================================ part 2 ================================\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e--                              alter profile\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e100\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_lock_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e20\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- succeed: can set setting\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1000\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- succeed: can set more settings\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_lock_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e20\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_life_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e30\u003c/span\u003e\u003cspan class=\"w\"\u003e   \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_grace_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e40\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_reuse_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e50\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_reuse_max\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e60\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eidle_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e80\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- succeed: setting value could be \u0026#39;unlimited\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eunlimited\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_lock_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_life_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eunlimited\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- succeed: can alter default profile\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e80\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_reuse_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e70\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_profiles\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprofile\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003esetname\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: profile name is invalid\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- int\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- numeric\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eaaaaa111111111122222222223333333333444444444455555555556666666666\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- too long, max 64\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: repeated settings are not allowed\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_reuse_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_reuse_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e20\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: profile doesn\u0026#39;t exist\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eepro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eepro2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/*\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003eerror: setting is invalid\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e*/\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edata_directory\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eanyvalue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_effect_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: setting lose value\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_lock_time\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: setting value type is invalud\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;iamstring\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003enoint\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: setting value is out of limit\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_lock_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_lock_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e24856\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_lock_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e000001\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- ================================ part 3 ================================\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e--                              drop profile\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e100\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_lock_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e20\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro4\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro5\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- succeed: drop profile\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprofile\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_profiles\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eGROUP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprofile\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: profile doesn\u0026#39;t exist\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro5\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: default profile can\u0026#39;t be dropped\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro5\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"2-createalter-user--profile\"\u003e2 CREATE/ALTER USER .. PROFILE\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- ================================ part 4 ================================\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e--                             set profile for user\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_user_profiles\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- succeed: set profile for user\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u3.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu4\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u4.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: profile doesn\u0026#39;t exist\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eeu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u4.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1000\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: profile name invalid\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eeu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u4.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eeu3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u4.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_user_profiles\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu4\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- catalog also changed\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_user_profiles\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- ================================ part 5 ================================\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e--                              alter user profile\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u3.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- succeed: alter user set profile\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: profile doesn\u0026#39;t exist\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1000\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: profile name invalid\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_user_profiles\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eroloid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- ================================ part 6 ================================\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e--                         drop user and profile\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- succeed: drop user\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_user_profiles\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erolname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_user_profiles\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erolname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: can\u0026#39;t drop profile if any user are using it\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error: default profile can\u0026#39;t be dropped\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_user_profiles\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eroloid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"3-验证profile生效\"\u003e3 验证profile生效\u003c/h1\u003e\n\u003ch2 id=\"验证-failed_login_attempts-与-password_lock_time\"\u003e验证 failed_login_attempts 与 password_lock_time\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_lock_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e0001\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 运行登录失败3次，失败后锁定8秒\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 允许登录失败无数次\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u1.error1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT 1;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u1.error1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT 1;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u1.error1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT 1;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u1.pass1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT 1;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- sleep 8s\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u1.pass1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT 1;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- u2\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u2.error1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT 1;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u2.error1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT 1;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u2.error1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT 1;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u2.pass1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT 1;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- sleep 8s\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u2.pass1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT 1;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;DROP USER u1,u2\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"验证-password_life_time-与-password_grace_time\"\u003e验证 password_life_time 与 password_grace_time\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_life_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e0001\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 8s\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_grace_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e0001\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 密码有效期为8s，密码宽容期也为8s\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 密码有效期无限制\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"n\"\u003eq\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u1.pass1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT 1;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- sleep 8s\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u1.pass1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT 1;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- sleep 8s\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u1.pass1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT 1;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u2.pass1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT 1;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- sleep 8s\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u2.pass1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT 1;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- sleep 8s\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u2.pass1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT 1;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"验证-password_reuse_time-和-password_reuse_max\"\u003e验证 password_reuse_time 和 password_reuse_max\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_reuse_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e0001\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 不能用过去8秒使用过的密码\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_reuse_max\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e100\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 不能用过去100次使用过的\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_sleep\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_sleep\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_sleep\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2.pass2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2.pass2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- -----------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro4\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_reuse_max\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 不能用过去2次使用过的\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_reuse_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e20\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro4\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass3\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass4\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass3\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- error\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- ok\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"验证-idle_time\"\u003e验证 idle_time\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro5\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eidle_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 6s\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro5\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"n\"\u003eq\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u1.pass1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 不用pg_sleep\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esleep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e7\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"n\"\u003eq\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e5432\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u2.pass1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 不用pg_sleep\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esleep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e7\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"3-view\"\u003e3 view\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eREPLACE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVIEW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSYS\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eDBA_PROFILES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"n\"\u003eprofile\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;PROFILE\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"n\"\u003esetname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;RESOURCE_NAME\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"n\"\u003esetkind\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;RESOURCE_TYPE\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"n\"\u003esetval\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;LIMIT\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_profiles\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e升级\u003c/li\u003e\n\u003cli\u003e审计\u003c/li\u003e\n\u003cli\u003eoid\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eknl_u_misc_init\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eAuthenticatedUserId\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eInvalidOid\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eResetStreamStatus\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eAuthenticatedUserId\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eInvalidOid\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eInitializeSessionUserId\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eAuthenticatedUserId\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eSearchSysCache\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erolname\u003c/span\u003e \u003cspan class=\"o\"\u003e/\u003c/span\u003e \u003cspan class=\"n\"\u003euseroid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eInitializeSessionUserIdStandalone\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eAuthenticatedUserId\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eBOOTSTRAP_SUPERUSERID\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eSessionUserId\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eCurrentUserId\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ecreate_session_context\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# get_setting_from_guc_or_profile\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eenable_session_sig_alarm\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"c1\"\u003e# get_setting_from_guc_or_profile\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eReadCommand\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# get_setting_from_guc_or_profile\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eenable_session_sig_alarm\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"c1\"\u003e# get_setting_from_guc_or_profile\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003edisable_session_sig_alarm\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eTpoolSchedulerMain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eCheckSessionTimeout\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"c1\"\u003e# get_setting_from_guc_or_profile\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ehandle_sig_alarm\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eCheckSessionTimeout\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"c1\"\u003e# get_setting_from_guc_or_profile\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eWaitMission\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# get_setting_from_guc_or_profile\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eenable_session_sig_alarm\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"海量 2 用例 profile"},{"content":"1 Oracle兼容性-支持profile功能 1.1 功能简述 本特性实现与oracle profile相同的功能，支持为不同用户设置7个不同的配置参数：\nfailed_login_attempts password_lock_time password_life_time password_grace_time password_reuse_time password_reuse_max idle_time 简单使用示例如下：\nCREATE PROFILE pro1 LIMIT failed_login_attempts 10; CREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; ALTER USER u1 PROFILE u1; 1.2 实现方案 一、元数据 本特性的关键实现为：对用户提供DDL接口，在内核中存储配置数据。因此，在介绍代码流程前，先介绍接口与元数据。\n新增GUC参数resource_limit (与oracle参数名一致)\n控制是否启用oracle profile功能。\n如果该参数为on，以下5个guc参数则不再生效：[failed_login_attempts, password_lock_time, password_effect_time, password_reuse_time, password_reuse_max]。另外，对于已经过身份认证的连接，session_timeout也不再生效，相关功能均由profile中的用户级参数控制。\n对于新安装的集群、旧版本升级的集群，该参数的值存在差异：\n新安装：新安装的数据库，即3.0.8版本及之后，该guc参数值默认为on（初始值为off，由initdb自动设置为on）\n升级：从3.0.8之前版本，升级到3.0.8版本时，在升级的过程中，该参数的值仍然是off，即升级上来默认不可用profile功能\nSELECT * FROM pg_settings WHERE name = \u0026#39;resource_limit\u0026#39;; -[ RECORD 1 ]------------------------------------------- name | resource_limit setting | on -- 默认为on （由initdb设置为on，从旧版本升级到新版本时，升级脚本会将该参数设置为off） unit | category | Ungrouped short_desc | Used to enable profile feature extra_desc | default on context | postmaster -- 需重启生效 vartype | bool source | default min_val | max_val | enumvals | boot_val | off reset_val | off sourcefile | sourceline | 修改6个GUC参数的生效条件\n当GUC参数resource_limit取值为on时，以下6个GUC参数不再生效：[failed_login_attempts, password_lock_time, password_effect_time, password_reuse_time, password_reuse_max, session_timeout]\n新增3个PROFILE的SQL语法 (与oracle语法格式一致)\nCREATE PROFILE profilename LIMIT {setting_name {setting_value | UNLIMITED} ...} ALTER PROFILE profilename LIMIT {setting_name {setting_value | UNLIMITED} ...} DROP PROFILE [IF EXISTS] profilename [, profilename, ...] 扩展2个SQL语法（与oracle语法格式一致）\nCREATE USER ... [PROFILE profilename] ... ALTER USER ... [PROFILE profilename] ... 新增系统表 vb_user_profiles\n存储用户与profile的对应关系\n新增系统表索引 btree(roloid)\n-- 示例语法 ALTER USER user1 PROFILE profile1; roloid | rolname | profile -------+---------+--------- 16384 | user1 | profile1 -- 示例行 新增系统表 vb_profiles\n该系统表存储profile中各个配置项的值，以及值的约束。\n新增系统表索引 btree(profile, setname)。\n备注：oracle对应的系统表为dba_profiles，本需求还会新增一个名为dba_profiles的系统视图，本质就是查询该表中的4列\n-- 示例语法 CREATE PROFILE profile1 LIMIT failed_login_attempts 10; profile | setname | setval | valunit | valtype | valmin | valmax | valdefault | settype ------------+---------------------------+--------------------+---------+----------+---------+------------+------------+---------- profile1 | failed_login_attempts | 10 | times | int | 1 | 2147483646 | 10 | password -- 示例行 该系统表中，有7行初始数据，即7个profile配置项，以及默认参数，默认参数的取值与oracle一致，都为unlimited。\nprofile | setname | setval | valunit | valtype | valmin | valmax | valdefault | settype -- unlimit含义 ------------+---------------------------+--------------------+---------+--------------------+------------+------------+---------- default | failed_login_attempts | unlimited | times | int | 1 | 2147483646 | 10 | password -- 等价INT_MAX，允许无限次登录失败 default | password_lock_time | unlimited | days | double | 0.00001 | 24855 | 1 | password -- 等价0，账号永远不锁 default | password_life_time | unlimited | days | double | 0.00001 | 24855 | 180 | password -- 等价DBL_MAX，密码永远有效 default | password_grace_time | unlimited | days | double | 0.00001 | 24855 | 7 | password -- 等价DBL_MAX，密码过期也永远可用 default | password_reuse_time | unlimited | days | double | 0.00001 | 24855 | 1 | password -- 等价0，密码可无限复用 default | password_reuse_max | unlimited | times | int | 1 | 2147483646 | 1 | password -- 等价INT_MAX，密码可无限复用 default | idle_time | unlimited | minutes | double | 0.00001 | 2147483646 | 10 | kernel -- 等价0，会话永远不过期 (与guc session_timeout 一致) -- 0.00001 day = 约0.8 second -- 24855 day = 约70 year 参考：以下是原guc参数的取值范围\nSELECT name,setting, unit, vartype, short_desc, extra_desc, min_val, max_val, boot_val, reset_val FROM pg_settings WHERE name in (\u0026#39;failed_login_attempts\u0026#39;, \u0026#39;password_lock_time\u0026#39;, \u0026#39;password_effect_time\u0026#39;, \u0026#39;password_reuse_time\u0026#39;, \u0026#39;password_reuse_max\u0026#39;, \u0026#39;session_timeout\u0026#39;); name | setting | short_desc | extra_desc | min_val | max_val | boot_val | reset_val ----------------------+---------+---------------------------------------------------------+-------------------------------------+---------+---------+----------+----------- int failed_login_attempts | 10 | max number of login attempts. | | 1 | 1000 | 5 | 5 reeal password_effect_time | 90 day | password effective time. | | 30 | 36500 | 36500 | 30 -- 天 int password_lock_time | 1 min | password lock time | | 1 | 525600 | 1440 | 1440 -- 分钟 int password_reuse_max | 0 | max times password can reuse. | | 1 | 100 | 3 | 3 real password_reuse_time | 60 | max days password can reuse. | | 30 | 90 | 90 | 90 -- 天 int session_timeout | 600 | Set the maximum allowed duration of any unused session. | A value of 0 turns off the timeout. | 0 | 86400 | 600 | 600 -- 秒 新增系统视图 dba_profiles (与oracle视图名与视图结构一致)\noracle只有dba_profiles，无user_profiles和all_profiles\nCREATE OR REPLACE VIEW SYS.DBA_PROFILES AS SELECT profile setname resource_name settype resource_type setval limit FROM vb_profiles; 默认查询结果如下：\nSELECT * FROM dba_profiles; profile | resource_name | resource_type | limit ---------+-----------------------+---------------+----------- default | failed_login_attempts | password | unlimited default | password_lock_time | password | unlimited default | password_life_time | password | unlimited default | password_grace_time | password | unlimited default | password_reuse_time | password | unlimited default | password_reuse_max | password | unlimited default | idle_time | kernel | unlimited 修改系统视图 DBA_USERS\n旧视图\nCREATE OR REPLACE VIEW SYS.DBA_USERS AS SELECT CAST(quote_ident_redwood(pga.rolname) AS VARCHAR2(64)) AS username, pga.oid AS user_id, ..., NULL::character varying(30) AS profle, -- 修改点 ... FROM pg_authid pga, pg_database pgd, pg_tablespace pgt, pg_user_status pgus -- 修改点 WHERE ((pgd.datname = current_database()) AND (pgd.dattablespace = pgt.oid) AND (pgus.roloid = pga.oid)); -- 修改点 新视图\nCREATE OR REPLACE VIEW SYS.DBA_USERS AS SELECT CAST(quote_ident_redwood(pga.rolname) AS VARCHAR2(64)) AS username, pga.oid AS user_id, ..., pgp.profile varying(64) AS profle, ----------------------- 修改 ... FROM pg_authid pga, vb_user_profiles pgp, pg_database pgd, pg_tablespace pgt, pg_user_status pgus -------------------- 新增 WHERE ((pgd.datname = current_database()) AND (pgd.dattablespace = pgt.oid) AND (pgus.roloid = pga.oid)) AND (pgp.roloid = pga.oid); -------------------------- 新增 影响系统视图 USER_USERS 与 ALL_USERS：这两个视图本质是从DBA_USERS，DBA_USERS中profile列内容变化，查询结果也会发生变化。\n二、数据库启动流程 在启动数据库时，需检查是否需要初始化pg_profiles系统表。一个集群中，该初始化操作永远只会触发一次。\n此处初始化的意义是，用户查询DBA_USERS视图时，profile列的表现与oralce一致，即所有用户都有profile，未主动设置profile的用户，其profile为default。对于已存在的旧用户，pg_profiles系统表中还未记录其profile信息，需要在pg_profiles中记录其profile为default。\n同步流程如下：\n1. 启动数据库 2. 读取GUC参数resource_limit 3. 如果resource_limit为on，且pg_profiles系统表为空，则表示首次使用profile功能，此时需初始化pg_profiles： 1. 遍历pg_authdid系统表，读取所有的[roloid, rolname] 2. 依次构造pg_profiles系统表tuple [roloid=roloid, rolname=rolname, profile=default] 3. 以此将tuple插入至pg_profiles系统表中 之后，每次CREATE USER时，即使用户未为用户指定profile，也会默认向pg_profiles中插入一行，表示用户默认使用default profile。\n三、定义PROFILE参数流程 CREATE PROFILE\n1. 用户执行SQL: CREATE PROFILE profilename LIMIT {setting_name {setting_value | UNLIMITED} ...} 2. 内核解析SQL：生成CreateProfileStmt语法树 3. 内核执行SQL：在DDL处理主函数中，处理CreateProfileStmt语法树 1. 检查resource_limit参数是否开启 2. 检查用户是否有CreateRole权限 3. 检查profilename是否已存在 4. 检查setting_name是否在7个配置项白名单中 5. 检查setting_value的值是否符合约束 6. 构造pg_profile_settings系统表tuple：[profile=profilename, setname=setting_name, setval=setting_value]，剩下的值[valunit,valtype,valmin,valmax,valdefault,settype]来自默认值 7. 将tuple插入到pg_profile_settings中 ALTER PROFILE\n1. 用户执行SQL: ALTER PROFILE profilename LIMIT [setting_name {setting_value | UNLIMITED} ...] 2. 内核解析SQL：生成AlterProfileStmt语法树 3. 内核执行SQL：在DDL处理主函数中，处理AlterProfileStmt语法树 1. 检查resource_limit参数是否开启 2. 检查用户是否有CreateRole权限 3. 检查profilename是否已存在 4. 检查setting_name是否在7个配置项白名单中 5. 检查setting_value的值是否符合约束 6. 如果系统表pg_profile_settings中未存在对应的setting_name 构造系统表tuple：[profile=profilename, setname=setting_name, setval=setting_value],剩下的值[valunit,valtype,valmin,valmax,valdefault,settype]来自默认值 将tuple插入至系统表 7. 如果系统表中已存在对应的setting_name 则更新tuple中的setting_value ALTER USER .. PROFILE\n1. 用户执行SQL：ALTER USER username ... [PROFILE profilename] ... 2. 内核解析SQL：生成AlterRoleStmt语法树 3. 内核执行SQL：在DDL处理主函数中，处理AlterRoleStmt语法树，首先检查用户是否有CreateRole权限，然后处理profile参数： 1. 检查resource_limit参数是否开启 2. 检查profilename是否已存在 3. 获取用户对应的roleid 4. 如果系统表pg_profiles中未存在对应的role与profile关系 构造系统表tuple，[roloid=roloid, rolname=username, profile=profilename] 将tuple插入至系统表 5. 如果系统表pg_profiles中已存在对应的role与profile关系 则更新tuple中的profile 四、使用PROFILE参数流程 首先，需要统计哪些场景中会使用到相关GUC\n场景一：用户建立连接\n在该场景中，可能使用到4个GUC参数\n# 此处以未开启线程池为例 PostgresMain # 第一阶段：接受用户的密码，并进行一系列检查 InitBackendWorker InitSession CheckAuthentication PerformAuthentication port-\u0026gt;protocol_config-\u0026gt;fn_authenticate ClientAuthentication # 1. 从pg_hba.conf中，读取password校验方式 hba_getauthmethod sendAuthRequest # 2. 接收客户端的password，检查password是否正确 recv_and_check_password_packet crypt_verify # 3. 从系统表pg_user_status中，获取rolstatus字段，判断用户是否被锁 GetAccountLockedStatus SearchSysCache1(\u0026#39;pg_user_status\u0026#39;) # 4. 无论密码正确与否，更新与锁定账号相关的参数 if role is lock or unlock: TryUnlockAccount GetPasswordTimeOfTuple transform \u0026#39;password_lock_time\u0026#39; UpdateUnlockAccountTuples # 5. 如果密码失败次数较多，锁定账户 if passwrong: if master: TryLockAccount if \u0026gt; \u0026#39;failed_login_attempts\u0026#39; tableam_tops_modify_tuple(\u0026#39;pg_user_status\u0026#39;) elif standby: UpdateFailCountToHashTable if \u0026gt; \u0026#39;failed_login_attempts\u0026#39; lock # 6. 如果密码正确，检查密码有效期（仅vastbase有此函数） checkPasswordEffect getLeftEffectSpan transform \u0026#39;password_effect_time\u0026#39; if leftday \u0026lt; 0: \u0026#39;ERROR: password expired\u0026#39; # 第二阶段：循环接收用户的其他数据，比如SQL语句 for (;;) ReadCommand # 此处，每接收一条客户端的消息，都会检查一次 session_timeout # 如果开启profile，此处需要缓存该用户的profile idle_time参数，否则，每次都从profile系统表中读取，对性能影响较大 # 理论上，如果无用户更新profile idle_time参数，一个连接缓存一次即可，即一个连接仅需读取一次系统表 if \u0026gt; \u0026#39;session_timeout\u0026#39;: \u0026#39;ERROR: timeout\u0026#39; exec_simple_query(\u0026#39;SQL\u0026#39;) 场景二、用户执行DDL\n在该场景中，可能使用到2个GUC参数\nexec_simple_query(\u0026#39;CREATE USER ..\u0026#39;) ... CreateRole AddAuthHistory transform \u0026#39;password_reuse_time\u0026#39; systable_beginscan(\u0026#39;pg_auth_history\u0026#39;) if password \u0026gt; \u0026#39;password_reuse_time\u0026#39; or \u0026#39;password_reuse_max\u0026#39;: ok exec_simple_query(\u0026#39;ALTER USER ..\u0026#39;) AlterRole AddAuthHistory 在所有使用guc参数的地方，均能获取到当前登录用户的oid。接下来，只需在代码中，所有使用guc参数的地方，判断使用guc的值，还是profile中配置的值即可。\n以’Failed_login_attempts’参数为例，使用guc参数的代码将修改为：\n旧代码\nvoid TryLockAccount() { ... if (u_sess-\u0026gt;attr.attr_security.Failed_login_attempts \u0026gt; 0 \u0026amp;\u0026amp; failedcount \u0026gt;= u_sess-\u0026gt;attr.attr_security.Failed_login_attempts) { .. } .. } 新代码\nvoid TryLockAccount() { ... ProfileVal setting = get_setting_from_guc_or_profile(PT_FAILED_LOGIN_ATTEMPTS); if (setting.intval \u0026gt; 0 \u0026amp;\u0026amp; failedcount \u0026gt;= setting.intval) { .. } .. } ProfileVal get_setting_from_guc_or_profile(ProfileType type) { ProfileVal setting = {0}; if (!resource_limit) { /* 如果未开启profile功能，则使用guc参数 */ setting.intval = u_sess-\u0026gt;attr.attr_security.Failed_login_attempts; } else { /* 如果未开启profile功能 */ roloid = GetCurrentUser(); /* 首先，从系统表pg_profiles中，查找用户使用的profile */ profile = catalog_find_user_profile(roloid); /* 然后，从系统表pg_profile_settings中，查找profile中具体的配置项的值 */ tuple = catalog_find_profile_setting(profile, type); setting.intval = tuple.setval; } return setting; } typedef union { int intval; double realval; char *strval; } ProfileVal; typedef enum { PT_FAILED_LOGIN_ATTEMPTS, PT_PASSWORD_LIFE_TIME, PT_PASSWORD_GRACE_TIME, PT_PASSWORD_REUSE_TIME, PT_PASSWORD_REUSE_MAX, PT_PASSWORD_REUSE_TIME, PT_IDLE_TIME } ProfileType; 1.3 接口说明 本特性变更的参数如下，参数的具体说明请看上一章：\n新增GUC参数：resource_limit\n修改6个GUC参数的生效条件：[failed_login_attempts, password_lock_time, password_effect_time, password_reuse_time, password_reuse_max, session_timeout]\n新增3个PROFILE的SQL语法：\nCREATE PROFILE profilename LIMIT {setting_name {setting_value | UNLIMITED} ...} ALTER PROFILE profilename LIMIT [setting_name {setting_value | UNLIMITED} ...] DROP PROFILE [IF EXISTS] profilename [, profilename, ...] 扩展2个SQL语法\nCREATE USER ... [PROFILE profilename] ... ALTER USER ... [PROFILE profilename] ... 新增系统表 vb_user_profiles\n新增系统表 vb_profiles\n修改系统表 pg_dependcy\n新增系统视图 dba_profiles\n修改系统视图 DBA_USERS：原来profile列的值都为空，现在不为空\n影响系统视图 USER_USERS 与 ALL_USERS的查询结果：原来profile列的值都为空，现在不为空\n1.4 内存管理 本特性主要占用的内存如下：\nLocalBuffer：如果开启profile功能，需要缓存pg_profiles与pg_profile_settings系统表中的数据。大部分场景中，缓存大小数据量级为几十k。 其他内存占用几乎可忽略。\n1.5 安全 访问控制：在处理CREATE PROFILE, ALTER PROFILE, DROP PROFILE语法时，需判断用户是否具有CreateRole权限。 备注：CreateRole是一个控制范围较大的权限，CREATE USER, ALTER USER, DROP USER等均由CreateRole这一个权限控制。 安全审计：在处理CREATE PROFILE, ALTER PROFILE, DROP PROFILE语法时，适配统一审计特性。 1.6 性能 本特性仅影响建立连接的过程，不影响数据库处理SQL的性能。\n1.7 专利 不涉及\n1.8 升级管理 部署类型 行为说明 新安装 新增1个guc resource_limit=on, 无效6个guc [failed_login_attempts, password_lock_time, password_effect_time, password_reuse_time, password_reuse_max, session_timeout]，新增5个PROFILE语法，新增2个系统表[pg_profiles，pg_profile_settings]，新增1行系统表行pg_dependcy，新增1个视图dba_profiles，修改3个视图[dba_users, user_users, all_users] 升级前 无变化 升级时 设置resource_limit=off 升级后 新增1个guc resource_limit=on, 无效6个guc [failed_login_attempts, password_lock_time, password_effect_time, password_reuse_time, password_reuse_max, session_timeout]，新增5个PROFILE语法，新增2个系统表[pg_profiles，pg_profile_settings]，新增1行系统表行pg_dependcy，新增1个视图dba_profiles，修改3个视图[dba_users, user_users, all_users] 升级失败 删除新增guc，SQL语法，系统表，视图，还原变更的视图 1.9 其他说明 无\n用户与数据库建立连接 查询profile系统表，将用户的profile配置，缓存在u_sess中 检查用户密码有效期、检查session_timoue等时 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/2-design-profile/","summary":"\u003ch1 id=\"1-oracle兼容性-支持profile功能\"\u003e1 Oracle兼容性-支持profile功能\u003c/h1\u003e\n\u003ch2 id=\"11-功能简述\"\u003e1.1 功能简述\u003c/h2\u003e\n\u003cp\u003e本特性实现与oracle profile相同的功能，支持为不同用户设置7个不同的配置参数：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003efailed_login_attempts\u003c/li\u003e\n\u003cli\u003epassword_lock_time\u003c/li\u003e\n\u003cli\u003epassword_life_time\u003c/li\u003e\n\u003cli\u003epassword_grace_time\u003c/li\u003e\n\u003cli\u003epassword_reuse_time\u003c/li\u003e\n\u003cli\u003epassword_reuse_max\u003c/li\u003e\n\u003cli\u003eidle_time\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e简单使用示例如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"12-实现方案\"\u003e1.2 实现方案\u003c/h2\u003e\n\u003ch3 id=\"一元数据\"\u003e一、元数据\u003c/h3\u003e\n\u003cp\u003e本特性的关键实现为：对用户提供DDL接口，在内核中存储配置数据。因此，在介绍代码流程前，先介绍接口与元数据。\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e新增GUC参数resource_limit (与oracle参数名一致)\u003cbr\u003e\n控制是否启用oracle profile功能。\u003cbr\u003e\n如果该参数为on，以下5个guc参数则不再生效：[failed_login_attempts, password_lock_time, password_effect_time, password_reuse_time, password_reuse_max]。另外，对于已经过身份认证的连接，session_timeout也不再生效，相关功能均由profile中的用户级参数控制。\u003cbr\u003e\n对于新安装的集群、旧版本升级的集群，该参数的值存在差异：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e新安装：新安装的数据库，即3.0.8版本及之后，该guc参数值默认为on（初始值为off，由initdb自动设置为on）\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e升级：从3.0.8之前版本，升级到3.0.8版本时，在升级的过程中，该参数的值仍然是off，即升级上来默认不可用profile功能\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_settings\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;resource_limit\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eRECORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"c1\"\u003e-------------------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"w\"\u003e       \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eresource_limit\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003esetting\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eon\u003c/span\u003e\u003cspan class=\"w\"\u003e         \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 默认为on （由initdb设置为on，从旧版本升级到新版本时，升级脚本会将该参数设置为off）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eunit\u003c/span\u003e\u003cspan class=\"w\"\u003e       \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003ecategory\u003c/span\u003e\u003cspan class=\"w\"\u003e   \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eUngrouped\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eshort_desc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eUsed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eto\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eenable\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprofile\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efeature\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eextra_desc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eon\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003econtext\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostmaster\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 需重启生效\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003evartype\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ebool\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003esource\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003emin_val\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003emax_val\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eenumvals\u003c/span\u003e\u003cspan class=\"w\"\u003e   \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eboot_val\u003c/span\u003e\u003cspan class=\"w\"\u003e   \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eoff\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003ereset_val\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eoff\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003esourcefile\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003esourceline\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e修改6个GUC参数的生效条件\u003cbr\u003e\n当GUC参数resource_limit取值为on时，以下6个GUC参数不再生效：[failed_login_attempts, password_lock_time, password_effect_time, password_reuse_time, password_reuse_max, session_timeout]\u003c/p\u003e","title":"海量 2 设计 profile"},{"content":"2 代码\n新增试图\nSELECT * FROM pg_user_settings; -- 新增视图 pg_user_settings SELECT rolname,profile FROM pg_authid WHERE rolcanlogin = true LEFT JOIN vb_profile ON rolname | setname | setting | settype | settype | setsource --------+-----------------------+----------+---------+-------------+---------------- u1 | password_effect_time | 90 | int | profile guc | pro1 | cluster guc | postgresql.conf 参数1: failed_login_attempts # opegauss使用1个内存中的hash表，存储密码失败次数 ClientAuthentication # 进行身份认证时，如果认证失败，则更新hash表中的失败次数值 UpdateFailCountToHashTable InitAccountLockHashTable hash_search # 如果失败次数超过GUC限制，则锁定账户 if failed_login_attempts： lockflag = True 参数2: password_lock_time 参数3: password_effect_time # 通过内置函数，主动查看密码剩余天数 gs_password_deadline GetCurrentUserId # 1 获取当前用户 GetUserCurrentPwdtime # 2 从系统表pg_auth_history中，获取密码创建时间passwordtime heap_open(\u0026#39;pg_auth_history\u0026#39;) systable_beginscan floor(u_sess-\u0026gt;attr.attr_security.Password_effect_time) # 3 从guc参数password_effect_time中获取密码有效天数 # 计算步骤2和3中的时间，返回剩余过期天数 参数4: password_reuse_max AddAuthHistory systable_beginscan(\u0026#39;pg_auth_history\u0026#39;) # 1 从系统表pg_auth_history中，获取曾用过的密码rolpassword，获取生成密码的时间passwordtime systable_getnext_back # 倒着从系统表扫描，即先扫描不太古老的旧密码，再扫描更古老的旧密码 pg_sha256_encrypt # 使用旧密码的salt，加密新密码 if strncmp : # 比较新密码是否与旧密码相等 hasSame = True # 如果新旧密码相等，计算新旧密码间隔天数，与GUC参数password_reuse_time比较，判断是否满足密码重用时间限制 if now - pg_auth_history.passwordtime \u0026gt; \u0026#39;password_reuse_time\u0026#39;： isTimeSafe = True # 计算这是倒数第几个密码 changeTimes++ if changeTimes \u0026gt; \u0026#39;password_reuse_max\u0026#39;: isMaxSafe # 满足 password_reuse_time 和 password_reuse_max 中任意一个条件，都可以修改密码 # - 要么用好几次之前的密码（满足 password_reuse_max 条件） # - 要么用很旧之间使用的密码（满足 password_reuse_time 条件） if hasSame and not isTimeSafe and not isMaxSafe: # 报错 参数5: password_reuse_time ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/2-design-profile-oracle/","summary":"\u003ch1 id=\"2\"\u003e2\u003c/h1\u003e\n\u003cp\u003e代码\u003cbr\u003e\n新增试图\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_user_settings\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 新增视图 pg_user_settings\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erolname\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eprofile\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_authid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erolcanlogin\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etrue\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eLEFT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eJOIN\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"n\"\u003evb_profile\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003erolname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"n\"\u003esetname\u003c/span\u003e\u003cspan class=\"w\"\u003e              \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esetting\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esettype\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esettype\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esetsource\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e--------+-----------------------+----------+---------+-------------+----------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_effect_time\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e90\u003c/span\u003e\u003cspan class=\"w\"\u003e       \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eint\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eprofile\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eguc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e                                                        \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecluster\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eguc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgresql\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003econf\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"参数1-failed_login_attempts\"\u003e参数1: failed_login_attempts\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# opegauss使用1个内存中的hash表，存储密码失败次数\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eClientAuthentication\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 进行身份认证时，如果认证失败，则更新hash表中的失败次数值\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eUpdateFailCountToHashTable\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eInitAccountLockHashTable\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ehash_search\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"c1\"\u003e# 如果失败次数超过GUC限制，则锁定账户\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003efailed_login_attempts\u003c/span\u003e\u003cspan class=\"err\"\u003e：\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003elockflag\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003eTrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"参数2-password_lock_time\"\u003e参数2: password_lock_time\u003c/h4\u003e\n\u003ch4 id=\"参数3-password_effect_time\"\u003e参数3: password_effect_time\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 通过内置函数，主动查看密码剩余天数\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003egs_password_deadline\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eGetCurrentUserId\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 1 获取当前用户\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eGetUserCurrentPwdtime\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 2 从系统表pg_auth_history中，获取密码创建时间passwordtime\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eheap_open\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pg_auth_history\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003esystable_beginscan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003efloor\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eu_sess\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eattr\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eattr_security\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ePassword_effect_time\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 3 从guc参数password_effect_time中获取密码有效天数\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 计算步骤2和3中的时间，返回剩余过期天数\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"参数4-password_reuse_max\"\u003e参数4: password_reuse_max\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eAddAuthHistory\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003esystable_beginscan\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pg_auth_history\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 1 从系统表pg_auth_history中，获取曾用过的密码rolpassword，获取生成密码的时间passwordtime\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003esystable_getnext_back\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 倒着从系统表扫描，即先扫描不太古老的旧密码，再扫描更古老的旧密码\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_sha256_encrypt\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 使用旧密码的salt，加密新密码\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003estrncmp\u003c/span\u003e \u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 比较新密码是否与旧密码相等\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ehasSame\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003eTrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 如果新旧密码相等，计算新旧密码间隔天数，与GUC参数password_reuse_time比较，判断是否满足密码重用时间限制\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003enow\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"n\"\u003epg_auth_history\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epasswordtime\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;password_reuse_time\u0026#39;\u003c/span\u003e\u003cspan class=\"err\"\u003e：\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eisTimeSafe\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"kc\"\u003eTrue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 计算这是倒数第几个密码\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003echangeTimes\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003echangeTimes\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;password_reuse_max\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eisMaxSafe\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 满足 password_reuse_time 和 password_reuse_max 中任意一个条件，都可以修改密码\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# - 要么用好几次之前的密码（满足 password_reuse_max 条件）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# - 要么用很旧之间使用的密码（满足 password_reuse_time 条件）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003ehasSame\u003c/span\u003e \u003cspan class=\"ow\"\u003eand\u003c/span\u003e \u003cspan class=\"ow\"\u003enot\u003c/span\u003e \u003cspan class=\"n\"\u003eisTimeSafe\u003c/span\u003e \u003cspan class=\"ow\"\u003eand\u003c/span\u003e \u003cspan class=\"ow\"\u003enot\u003c/span\u003e \u003cspan class=\"n\"\u003eisMaxSafe\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"c1\"\u003e# 报错\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"参数5-password_reuse_time\"\u003e参数5: password_reuse_time\u003c/h4\u003e","title":"海量 2 设计 oracle profile"},{"content":"1 简介 1.1 目的 vastbase与oracle都支持设置运行参数：\nvastbase：支持设置集群级guc参数，例如，guc参数failed_login_attempts用于设置’用户密码错误多少次后锁定账户’，该参数对集群中所有用户（非初始用户）都有效。 oracle：也支持failed_login_attempts参数，但是oracle支持为不同用户设置不同的failed_login_attempts值。我们且将此类参数称为用户级参数。 与oracle相比，vastbase的guc参数功能存在2个差异：\n作用范围：oracle支持设置用户级参数，vastbase大部分参数都是集群级guc参数 参数个数：23版本的oracle支持18个用户级参数，其中6个可在vastbase找到对应的guc参数 参数取值：vastbase中，6个guc参数的取值范围与oracle profile不同 本文主要介绍以下几点：\noracle用户级参数的个数、设置方法 vastbase中对应集群级guc参数的个数、设置方法 vastbase新需求：尽量实现与oracle一致的用户级guc参数 本文档可指导开发者、测试者熟悉vastbase用户级guc配置参数特性\n本文档的内容已被上传至tapd，tapd上，排版更好看，测试用例更方便复制。建议直接从tapd上查看本文档原文: https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007196\n1.2 适用范围 vastbase 3.0.8及之后版本，vastbase用户级参数profile特性接口设计、使用指导等。\n1.3 术语定义、首字母缩写词和缩略语 GUC：Grand Unifed Configuralion，postgresql和vastbase的配置参数 1.3 参考资料 原始需求： https://www.tapd.cn/60475194/prong/stories/view/1160475194001074627 tapd上本需求文档链接： https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007196 tapd上6个与密码相关的guc参数的使用参考： https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007200 oracle 23 profile语法以及相关参数： https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/CREATE-PROFILE.html mysql 8.0 create user语法以及相关参数： https://mysql.net.cn/doc/refman/8.0/en/create-user.html mysql 配置参数列表：https://mysql.net.cn/doc/refman/8.0/en/server-system-variable-reference.html vastbase g100 create user语法以及相关参数： https://docs.vastdata.com.cn/zh_CN/VastbaseG100/V3.0.8/1/6a4766151e29496b9f88cd2d9dd3db2e 2 支持oracle用户级配置profile 2.1 功能简述 【需求来源】桂林银行 需求链接：https://www.tapd.cn/60475194/prong/stories/view/1160475194001074627 需求描述：桂林银行客户指出，目前对于数据库用户的管理方式不够便捷，无法像oracle profile方式为用户赋予一组安全策略。一些属性如密码有效期、密码过期天数、密码尝试次数等也只能全局设定，无法指定用户配置。- 需求范围：桂林银行使用的数据库兼容模式包括oracle和mysql两种兼容模式。 【需求背景】oracle 23的profile功能 通俗来讲，oracle的profle可理解为细粒度的配置参数。1个profile包含1组配置参数，不同用户可使用不同的profile。按上述例子，要单独控制某个用户的密码有效期，操作步骤如下：\n创建用户\nCREATE USER u1 IDENTIFIED BY \u0026#34;u1.1234\u0026#34;; 创建profile，同时设置用户级参数\n此处，以设置密码有效期参数为例：\nCREATE PROFILE pro1 LIMIT FAILED_LOGIN_ATTEMPTS 10; 设置用户u1使用profile pro1\nALTER USER u1 PROFILE pro1; 查看用户u1使用的profile\nSELECT username, profile FROM dba_users WHERE username = \u0026#39;U1\u0026#39;; USERNAME | PROFILE -----------+-------------- U1 | PRO1 查看profile pro1中的全部配置参数\noracle 8版本中，有16个用户级配置参数，oracle 23本中，有18个用户级配置参数。\nSELECT * FROM dba_profiles WHERE profile = \u0026#39;PRO1\u0026#39; ORDER BY resource_type; PROFILE | RESOURCE_NAME | RESOURCE_TYPE | LIMIT -----------------+---------------------------+---------------+----------- PRO1 | FAILED_LOGIN_ATTEMPTS | PASSWORD | 10 PRO1 | PASSWORD_LIFE_TIME | PASSWORD | DEFAULT PRO1 | PASSWORD_REUSE_TIME | PASSWORD | DEFAULT PRO1 | PASSWORD_REUSE_MAX | PASSWORD | DEFAULT PRO1 | PASSWORD_LOCK_TIME | PASSWORD | DEFAULT PRO1 | PASSWORD_GRACE_TIME | PASSWORD | DEFAULT PRO1 | INACTIVE_ACCONT_TIME | PASSWORD | DEFAULT PRO1 | PASSWORD_VERIFY_FUNCTION | PASSWORD | DEFAULT PRO1 | PASSWORD_ROLLOVER_TIME | PASSWORD | DEFAULT PRO1 | SESSIONS_PER_USER | KERNEL | DEFAULT PRO1 | CPU_PER_SESSION | KERNEL | DEFAULT PRO1 | CPU_PER_CALL | KERNEL | DEFAULT PRO1 | CONNECT_TIME | KERNEL | DEFAULT PRO1 | IDLE_TIME | KERNEL | DEFAULT PRO1 | LOGICAL_READS_PER_CALL | KERNEL | DEFAULT PRO1 | LOGICAL_READS_PER_SESSION | KERNEL | DEFAULT PRO1 | PRIVATE_SGA | KERNEL | DEFAULT PRO1 | CONPOSITE_LIMIT | KERNEL | DEFAULT 在oracle 23版本中，profile功能支持的18个用户级参数中，这些参数分为2类，详见本文\u0026lt;1.3 参考资料\u0026gt;\n系统资源类：比如1个用户可建立多少连接 身份认证类：比如密码有效期等\n但是，在vastbase中，仅能找到6个与之对应的参数 编号 oracle profile 参数 oracle取值范围 vastbase guc 参数 vb取值范围 参数分类 参数功能 1 FAILED_LOGIN_ATTEMPTS [1, max] unlimited failed_login_attempts [1,1000] 认证类 登录数据库时，如果密码错误次数超过\u0026lt;本参数\u0026gt;，则账号会被锁定，短期内无法再登录 2 PASSWORD_LOCK_TIME [1, max] unlimited password_lock_time [1,525600]min 认证类 如果因密码错误次数过多，导致账号被锁，将锁定\u0026lt;本参数\u0026gt;的时间 3 PASSWORD_LIFE_TIME [1, max] unlimited password_effect_time [30,36500]day 认证类 设置或更新用户密码时，超过\u0026lt;本参数\u0026gt;的时间，密码会过期（oracle与vastase表现不同） 4 PASSWORD_GRACE_TIME - - - 认证类 如果密码过期，在\u0026lt;本参数\u0026gt;的时间内，密码仍可使用 5 PASSWORD_REUSE_TIME [1, max] unlimited password_reuse_time [30, 90]day 认证类 用户设置密码时，如果密码在过去的\u0026lt;本参数\u0026gt;的时间内别用过，则密码不能复用，opengauss [0,3650] 6 PASSWORD_REUSE_MAX - password_reuse_max [1,100] 认证类 用户设置密码时，如果密码已被重复使用过\u0026lt;本参数\u0026gt;的次数，则密码不能复用 7 INACTIVE_ACCONT_TIME - - - 认证类 如果一个账号在\u0026lt;本参数\u0026gt;的时间内，未登录过，则锁定账号 8 PASSWORD_VERIFY_FUNCTION - - - 认证类 用户设置密码时，调用\u0026lt;本参数\u0026gt;指定的函数，检查密码是否符合要求 9 PASSWORD_ROLLOVER_TIME - - - 认证类 新旧密码滚动更新天数 10 SESSIONS_PER_USER - - - 资源类 1个用户可建立的最大连接数 11 CPU_PER_SESSION - - - 资源类 1个连接可使用CPU时间数 12 CPU_PER_CALL - - - 资源类 1个调用（比如1个SQL）可使用CPU时间数 13 CONNECT_TIME - - - 资源类 1个连接可持续的时间 14 IDLE_TIME [1, max] unlimited session_timeout [0,86400] 资源类 1个连接空闲时间限制 15 LOGICAL_READS_PER_CALL - - - 资源类 1次调用（比如1个SQL）允许读写的page数量 16 LOGICAL_READS_PER_SESSION - - - 资源类 1个连接允许读取的page数量 17 PRIVATE_SGA - - - 资源类 1个连接可使用的共享内存空间大小 18 CONPOSITE_LIMIT - - - 资源类 1个连接可可使用的总资源：按cpu时间、连接时间、page读写数等加权求和 【需求背景】mysql 8的密码安全策略 经调研，mysql无类似profile的功能，仅支持global或session级的参数，可通过以下语法设置参数：（详见本文\u0026lt;1.3 参考资料\u0026gt;）\nSET GLOBAL default_password_lifetime = 90; mysql无法单独为某个用户设置参数。但是，可通过语法，设置某些属性（详见本文\u0026lt;1.3 参考资料\u0026gt;）\nCREATE USER user .. [password_option] password_option: { PASSWORD EXPIRE [DEFAULT | NEVER | INTERVAL N DAY] -- 与oracle的password_effect_time参数等效 | PASSWORD HISTORY {DEFAULT | N} | PASSWORD REUSE INTERVAL {DEFAULT | N DAY} -- 与oracle的password_reuse_time参数等效 | PASSWORD REQUIRE CURRENT [DEFAULT | OPTIONAL] | FAILED_LOGIN_ATTEMPTS N -- 与oracle的failed_login_attempts参数等效 | PASSWORD_LOCK_TIME {N | UNBOUNDED} } 同时，vastbase也支持通过CREATE USER等语法设置少数几个与密码相关的参数：（详见本文\u0026lt;1.3 参考资料\u0026gt;）\nCREATE USER username [option] PASSWORD \u0026#39;password\u0026#39;; option { .. | VALID BEGIN \u0026#39;timestamp\u0026#39; | VALID UNTIL \u0026#39;timestamp\u0026#39; | TEMP SPACE \u0026#39;tmpspacelimit\u0026#39; -- 临时表的存储空间 | .. } 【需求说明】vastbase如何实现profile功能 从用户的角度看，本特性将实现与oracle功能接近的profile功能，该特性的核心分为以下3个部分：\n支持管理profile（语法与oracle一致）\n包括创建、更新、查询、删除profile。1个profile存储1组guc参数，当前版本仅能支持6个用户级GUC（下文介绍），这些guc参数可看做用户级guc参数，只针对部分用户生效，作用范围与原有的集群级guc参数不同\nCREATE PROFILE pro1; -- 创建 ALTER PROFILE pro1 LIMIT failed_login_attempts 10；-- 更新：仅支持更新profile的中的配置项，不支持更新profile本身的名称等元信息，在pro1中更新配置项failed_login_attempts的值 SELECT proname FROM vb_profile_settings; -- 查询 DROP PROFILE pro1; -- 删除 支持管理用户的profle（语法与oracle一致）\n包括为用户设置、查询、撤销profile。如果为用户设置profile，该用户使用profile中guc的优先级大于集群级guc\nCREATE USER u1 .. PROFILE pro1; -- 设置 ALTER USER u1 PROFILE pro1; -- 设置 SELECT rolname, profname FROM vb_profiles; -- 查询 ALTER USER u1 PROFILE default; -- 删除，即用户恢复使用集群级guc 支持管理profile中的配置项（语法与oracle一致）\n包括新增、更新、查询、删除配置项目。1个配置项即1个guc参数。名称、取值范围等与原guc一致、只是作用范围不一致。\nCREATE PROFILE pro1 LIMIT failed_login_attempts 10; -- 新增（可一次新增多个） ALTER PROFILE pro1 LIMIT password_lock_time 20; -- 新增（可一次新增多个） ALTER PROFILE pro1 LIMIT failed_login_attempts 20 password_lock_time 20; -- 更新 SELECT proname, name, setting FROM vb_profile_settings; -- 查询 ALTER PROFILE pro1 LIMIT failed_login_attempts default; -- 删除 此外，需确认几个问题：\nprofile guc数量：当前版本，仅支持上表中6个vb已存在的guc failed_login_attempts password_lock_time password_effect_time (oracle PASSWORD_LIFE_TIME) password_reuse_time password_reuse_max session_timeout (oracle IDLE_TIME) profile guc名称：6个guc中，2个参数的参数名与oracle不一致，即上表中第3和第14个，仍采用当前vb的guc名称 profile guc取值范围：6个guc的取值范围与集群级guc的取值范围一致 特性兼容性：在[oracle兼容性、mysql兼容性、postgresql兼容性、sqlserver兼容性]模式下，仅oracle兼容性下支持该特性 show sql_comp.. 2.2 功能说明 2.2.1 使用流程 场景一、管理profile 创建profile\nprofile可理解为1组用户级GUC配置参数。\nCREATE PROFILE pro1; -- 新增语法 CREATE PROFILE 创建profile，同时，设置配置参数\nCREATE PROFILE pro2 LIMIT failed_login_attempts 2 password_effect_time 20； -- 当前版本，支持6个guc参数 更新profile\n仅支持更新中profile中的配置项，比如新增、删除配置项，更新配置的值等。\n可一次更新1个或多个用户级配置参数。此处以2个配置参数为例：\nALTER PROFILE pro2 LIMIT failed_login_attempts 3 password_effect_time 30; -- 新增语法 ALTER PROFILE 此处，并未设置用户使用pro1，pro1暂时无任何作用。\n查询profile\nSELECT * FROM vb_profile_settings; -- 新增系统表 vb_profile_settings proname | setname | setting | settype ------------+---------------------------+--------------------+------------ pro1 | profile_status | active | enum -- 此时，pro1无任何配置项，但是，需要存储1行特殊行，表示profile存在 pro2 | profile_status | active | enum pro2 | failed_login_attempts | 3 | int pro2 | password_effect_time | 30 | int 删除profile\nDROP PROFILE pro1, pro2; DROP PROFILE IF EXISTS pro1, pro2; -- 新增语法 DROP PROFILE 场景二、管理用户的profile 前置：创建profile\nCREATE PROFILE pro1 failed_login_attempts 4 password_effect_time 10; 用户设置profile\n在创建用户时，即可指定profile\nCREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39; PROFILE pro1; -- 扩展语法：CREATE USER/ROLE .. PROFILE .. 用户设置profile\n对于已存在的用户，设置profile的语法如下\nCREATE USER u2 PASSWORD \u0026#39;u2.12345\u0026#39;; ALTER USER u2 PROFILE pro1; -- 扩展语法 ALTER USER .. PROFILE .. 用户查询profile\n假设存在用户u3，但是未为u3设置profile，则系统表中不存储u3的信息\nSELECT * FROM vb_profiles; -- 新增系统表 vb_profiles roloid | rolname | profile -------+---------+---------- 1600 | u1 | pro1 16001 | u2 | pro2 验证profile与user的denpendcy关系\nSELECT * FROM pg_depend; DROP PROFILE pro1; -- 预期输出 DROP失败，u1与u2依赖profile1 验证profile与user的denpendcy关系\nDROP USER u1; SELECT * FROM vb_profiles; -- 预期输出 roloid | rolname | profile -------+---------+---------- 16001 | u2 | pro2 清理环境\nDROP USER u2; DROP PROFILE pro1; 场景三、管理profile中的配置项 前置：创建profile\nCREATE PROFILE pro1 failed_login_attempts 1; 在profile新增配置项\nALTER PROFILE pro1 password_effect_time 10; 在profile查询配置项\nSELECT * FROM vb_profile_settings; proname | setname | setting | settype ------------+---------------------------+--------------------+------------ pro1 | profile_status | active | enum pro1 | failed_login_attempts | 1 | int pro1 | password_effect_time | 10 | int -- 以下语法可查询集群级GUC参数的值 SELECT name, setting FROM pg_settings WHERE name in ( \u0026#39;failed_login_attempts\u0026#39;, \u0026#39;password_effect_time\u0026#39;, \u0026#39;password_reuse_time\u0026#39;, \u0026#39;password_reuse_max\u0026#39;, \u0026#39;password_lock_time\u0026#39;, \u0026#39;session_timeout\u0026#39;); 在profile更新配置项\nALTER PROFILE pro1 LIMIT failed_login_attempts 20 password_lock_time 20; 在profile删除配置项\n将配置项设置为默认值，即与集群级guc参数保持一致，此时，系统表vb_profile_settings中将不再重复存储配置项的值。\nALTER PROFILE pro1 LIMIT password_lock_time default; 清理环境\nDROP PROFILE pro1; 场景四、验证约束场景 前置：创建profile\nCREATE PROFILE pro1; 约束：仅支持设置6个白名单中的guc参数\n即不支持的guc参数\nALTER PROFILE pro1 LIMIT password_min_length 3; -- 预期输出 不支持在profile中设置此参数 约束：不支持在设置配置项的值时使用表达式\n由于（配置项、配置项取值）之间使用空格隔开，(配置项、配置项)之间也使用空格隔开，使用表达式时，可能会存在语法规约冲突的问题\nALTER PROFILE pro1 LIMIT failed_login_attempts 2 + 1; -- 预期输出 ERROR: 语法解析错误 CREATE TABLE t1 (c1 INT); INSERT INTO t1 VALUES (3); ALTER PROFILE pro1 LIMIT failed_login_attempts (SELECT c1 FROM t1); -- 预期输出 ERROR: 语法解析错误 约束：具有管理员权限的账号，才能设置profile的配置项的值\nCREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; gsql -d postgresql -U u1 -W \u0026#39;u1.pass1\u0026#39; -c \u0026#34;ALTER PROFILE pro1 LIMIT password_min_length 3;\u0026#34; -- 预期输出 ERROR: 权限不足 约束：该特性只在oracle兼容性模式下生效\n-- 设置mysql兼容性 CREATE PROFILE pro1; -- 预期输出 ERROR: profile特性仅在oracle兼容性模式下生效 配置项的值不符合数据类型约束\nALTER PROFILE pro1 LIMIT failed_login_attempts \u0026#39;a_string\u0026#39;; -- 预期输出 ERROR: 参数值的数据类型错误 清理环境\nDROP TABLE t1; DROP USER u1; DROP PROFILE pro1; 场景五、验证参数1: failed_login_attempts 设置profile参数failed_login_attempts\nCREATE PROFILE pro1 failed_login_attempts 2; -- 为做对照，确保集群级guc参数failed_login_attempts的值不是2 show failed_login_attempts; 为用户设置profile\nCREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39; PROFILE pro1; 验证profile参数failed_login_attempts\n首先，输入2次错误密码，达到failed_login_attempts的阈值，再输入正确密码\n-- 错误密码2次 gsql -d postgresql -U u1 -W \u0026#39;1.wrong_pass\u0026#39; gsql -d postgresql -U u1 -W \u0026#39;2.wrong_pass\u0026#39; -- 正确密码 gsql -d postgresql -U u1 -W \u0026#39;2.wrong_pass\u0026#39; -- 预期输出 FATAL: The account has been locked. 从系统表中，使用其他用户，查看用户u1的失败登录次数\ngsql -d postgres -c \u0026#34; SELECT * FROM pg_user_status WHERE roloid = (SELECT oid FROM pg_authid WHERE rolname = \u0026#39;u1\u0026#39;);\u0026#34; roloid | failcount | locktime | rolstatus | permspace | tempspace | passwordexpired -------+-----------+-------------------------------+-----------+-----------+-----------+----------------- 16411 | 2 | 2025-02-21 12:05:10.199257+08 | 0 | 0 | 0 | 0 解锁方法：等一会，或者手动解锁\ngsql -d postgres -c \u0026#34;ALTER USER u1 ACCOUNT UNLOCK;\u0026#34; 对照组：验证集群级guc参数failed_login_attempts\n首先，设置集群级guc参数\nexport DATA_DIR=数据库安装目录 gs_guc reload -D $DATA_DIR -c \u0026#34;failed_login_attempts=5\u0026#34; 然后，创建新用户，新用户不指定profile，即新用户将使用集群级guc参数\nCREATE USER u2 PASSWORD \u0026#39;u2.pass1\u0026#39;; 接下来，新用户连续输入多次错误密码\n-- 错误密码2次 gsql -d postgresql -U u2 -W \u0026#39;1.wrong_pass\u0026#39; -c \u0026#34;SELECT 1\u0026#34; gsql -d postgresql -U u2 -W \u0026#39;2.wrong_pass\u0026#39; -c \u0026#34;SELECT 1\u0026#34; -- 正确密码 gsql -d postgresql -U u2 -W \u0026#39;u2.pass1\u0026#39; -c \u0026#34;SELECT 1\u0026#34; -- 预期输出 登录成功 清理环境\nDROP USER u1,u2; DROP PROFILE pro1; gs_guc reload -D $DATA_DIR -c \u0026#34;failed_login_attempts=default\u0026#34; 场景六、验证参数2: password_lock_time 该参数与failed_login_attempts结合使用，只能用来解锁自动锁定场景，即出发密码错误次数导致的锁定，不能解锁主动锁定场景\n设置profile参数password_lock_time\n-- 1天 = 24 * 60 * 60 = 86400秒，0.0001天是 8.64秒 CREATE PROFILE pro1 password_lock_time 0.0001; -- 设置failed_login_attempts，方便更好触发password_lock_time gs_guc reload -D $DATA_DIR -c \u0026#34;failed_login_attempts=2\u0026#34; -- 为做对照，确保集群级guc参数password_lock_time的值不是0.0001 show password_lock_time; 为用户设置profile\nCREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39; PROFILE pro1; 验证profile参数\n-- 密码错误2次，触发账号锁定 gsql -d postgresql -U u1 -W \u0026#39;1.wrong_pass\u0026#39; -c \u0026#34;SELECT 1\u0026#34; gsql -d postgresql -U u1 -W \u0026#39;2.wrong_pass\u0026#39; -c \u0026#34;SELECT 1\u0026#34; -- 密码正确，账号被锁 gsql -d postgresql -U u1 -W \u0026#39;u1.pass1\u0026#39; -c \u0026#34;SELECT 1\u0026#34; -- 等约8秒左右，即pro1 password_lock_time的值后，账号自动解锁 gsql -d postgresql -U u1 -W \u0026#39;u1.pass1\u0026#39; -c \u0026#34;SELECT 1\u0026#34; -- 预期输出 登录成功 对照组：验证集群级guc参数password_lock_time\n集群级guc password_lock_time的默认值是1天，不用额外设置\nshow password_lock_time; 创建新用户，新用户不指定profile，即新用户将使用集群级guc参数\nCREATE USER u2 PASSWORD \u0026#39;u2.pass1\u0026#39;; 接下来，新用户连续输入多次错误密码，触发密码锁定\n-- 错误密码2次 gsql -d postgresql -U u2 -W \u0026#39;1.wrong_pass\u0026#39; -c \u0026#34;SELECT 1\u0026#34; gsql -d postgresql -U u2 -W \u0026#39;2.wrong_pass\u0026#39; -c \u0026#34;SELECT 1\u0026#34; -- 正确密码 gsql -d postgresql -U u2 -W \u0026#39;u2.pass1\u0026#39; -c \u0026#34;SELECT 1\u0026#34; -- 预期输出 账号被锁，即使等待很久，远超8秒，账号仍然被锁 场景七、验证参数3: password_effect_time 设置profile参数password_effect_time\nCREATE PROFILE pro1 password_effect_time 10; -- 10天 -- 为做对照，确保集群级guc参数password_effect_time的值不是10 show password_effect_time; 为用户设置profile\nCREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39; PROFILE pro1; 验证profile参数\n首先，修改系统时间到11天后\ndata -s \u0026#34;+10 day\u0026#34; 然后，连接数据库\nvsql -d postgres -U u1 -W \u0026#39;u1.pass1\u0026#39; -r -- 预期输出 连接失败 密码过期 这里和opengauss不一致，opengauss密码过期后，只会打印一条提示，但是不会锁定账户\n对照组：验证集群级guc参数password_effect_time\n请参考上述2个guc参数验证方式，为节约篇幅，此处不再继续给示例\n清理环境\nDROP USER u1; DROP PROFILE pro1; 场景八、验证参数4: password_reuse_max 在修改密码的场景中，如果新密码与曾经的旧密码相同，password_reuse_max参数，用于设置不用重复使用过去几次的密码，从参数名上，判断不出参数的具体作用，看下面的示例方便一些。\n设置profile参数password_reuse_max\nCREATE PROFILE pro1 password_reuse_max 3; -- 为做对照，确保集群级guc参数password_reuse_max的值不是3 show password_reuse_max; 为用户设置profile\nCREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39; PROFILE pro1; 验证profile参数\nALTER USER u1 PASSWORD \u0026#39;u1.pass2\u0026#39;; ALTER USER u1 PASSWORD \u0026#39;u1.pass3\u0026#39;; -- 重复倒数第3次使用的密码 ALTER USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; -- 预期输出 ERROR: The password cannot be reused. -- 再修改1次密码 ALTER USER u1 PASSWORD \u0026#39;u1.pass4\u0026#39;; -- 重读倒是读4次使用的密码 ALTER USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; -- 预期输出 修改密码成功 对照组：验证集群级guc参数password_reuse_max\n请参考上述2个guc参数验证方式，为节约篇幅，此处不再继续给示例\n查看用户曾使用过的密码的语法如下，但是该语法查到的rolpassword列是sha256(password || salt)的值，无法从肉眼判断password是否相同\nSELECT * FROM pg_auth_history WHERE roloid = (SELECT oid FROM pg_authid WHERE rolname = \u0026#39;u1\u0026#39;); roloid | passwordtime | rolpassword --------+-------------------------------+------------------------------------ 16419 | 2025-02-21 15:20:50.308879+08 | sha256c84795e1631bbb8bf1ecf923... 16419 | 2025-02-21 15:22:06.754397+08 | sha2562939db0b3ffc71ee3115e010... 清理环境\nDROP USER u1; DROP PROFILE pro1; 场景九、验证参数5: password_reuse_time 在修改密码的场景中，如果新密码与曾经的旧密码相同，password_reuse_max参数，用于设置不能重复使用过去一段时间内使用的密码\n设置profile参数password_reuse_time\n-- 1天 = 24 * 60 * 60 = 86400秒，0.0001天是 8.64秒 CREATE PROFILE pro1 password_reuse_time 0.0001; -- 为做对照，确保集群级guc参数password_reuse_max的值不是3 show password_reuse_time; 为用户设置profile\nCREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39; PROFILE pro1; ALTER USER u1 PASSWORD \u0026#39;u1.pass2\u0026#39;; 验证profile参数\n-- 使用不太古老的密码（确保不要超过8.64秒） ALTER USER u1 PASSWORD \u0026#39;u1.pass3\u0026#39;; ALTER USER u1 PASSWORD \u0026#39;u1.pass3\u0026#39;; -- 预期输出 ERROR: The password cannot be reused. -- 再等几秒，超过8.64秒再改回pass3 ALTER USER u1 PASSWORD \u0026#39;u1.pass3\u0026#39;; -- 预期输出 修改成功 对照组：验证集群级guc参数password_reuse_time\n请参考上述2个guc参数验证方式，为节约篇幅，此处不再继续给示例\n查看用户曾使用过的密码的语法如下，passwordtime是密码使用时间\nSELECT * FROM pg_auth_history WHERE roloid = (SELECT oid FROM pg_authid WHERE rolname = \u0026#39;u1\u0026#39;); roloid | passwordtime | rolpassword --------+-------------------------------+------------------------------------ 16419 | 2025-02-21 15:20:50.308879+08 | sha256c84795e1631bbb8bf1ecf923... 16419 | 2025-02-21 15:22:06.754397+08 | sha2562939db0b3ffc71ee3115e010... password_reuse_time与password_reuse_max参数，在新密码与旧密码相同的场景中，只要满足二者中任意一个条件，都可以修改成功\n清理环境\nDROP USER u1; DROP PROFILE pro1; 场景十、验证参数6: session_timeout 设置profile参数session_timeout\nCREATE PROFILE pro1 session_timeout \u0026#39;8s\u0026#39;; -- 为做对照，确保集群级guc参数session_timeout的值不是8s show session_timeout; 为用户设置profile\nCREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39; PROFILE pro1; 验证profile参数\ngsql -d postgres -U u1 -W \u0026#39;u1.pass1\u0026#39; -r SELECT 1; -- 等8秒 SELECT 1; -- 预期输出 WARNING: Session unused timeout. 对照组：验证集群级guc参数session_timeout\n请参考上述2个guc参数验证方式，为节约篇幅，此处不再继续给示例\n清理环境\nDROP USER u1; DROP PROFILE pro1; 场景十一、其他场景 前向兼容：升级旧版本数据库，即可使用profile 备机生效：备机的参数生效机制，与集群级guc参数类似，只是特定用户的参数值采用profile中的参数值 2.2.2 配置参数和文件 2.2.3 数据相关性 GUC参数：未新增guc参数。6个guc参数的生效范围，由 [集群级] 变为 [集群级，用户级] 兼容性模式：仅oracle兼容性模式生效 2.3 接口信息 新增guc\nresource_limit = on / off\n新增3个SQL语法：\nCREATE PROFILE profilename LIMIT [setting_name {setting_value | UNLIMITED} ...] ALTER PROFILE profilename LIMIT [setting_name {setting_value | UNLIMITED} ...] DROP PROFILE [IF EXISTS] profilename [, profilename, ..] 扩展2个SQL语法\nCREATE USER .. [PROFILE profilename] .. ALTER USER .. [PROFILE profilename] .. 新增2个系统表\npg_user_settings\n新安装或升级到3.0.8版本的vastbase时，有一个默认的profile，profile中有7个配置项：\n新安装：7个配置项的默认值如下\n升级：7个配置项中，5个配置项的默认值来源于旧版本数据库的guc参数的取值\nsetgroup | setname | setval | valunit | valtype | valmin | valmax | valdefault | settype | ------------+---------------------------+--------------------+---------+--------------------+------------+------------+----------+ default | failed_login_attempts | unlimited | times | int | 1 | 2147483646 | 10 | password | default | password_lock_time | unlimited | days | double | 0.00001 | 2147483646 | 1 | password | default | password_life_time | unlimited | days | double | 0.00001 | 2147483646 | 180 | password | default | password_grace_time | unlimited | days | double | 0.00001 | 2147483646 | 7 | password | default | password_reuse_time | unlimited | days | double | 0.00001 | 2147483646 | 1 | password | default | password_reuse_max | unlimited | times | int | 1 | 2147483646 | 1 | password | default | idle_time | unlimited | minutes | double | 0.00001 | 2147483646 | 10 | kernel | pg_auth_profile\nroloid | rolname | profile -------+---------+---------- 新增1个系统视图\ndba_profiles\nCREATE OR REPLACE VIEW dba_profiles AS SELECT setgroup profile setname resource_name settype resource_type setval limit FROM pg_user_settings; 默认查询结果如下：\nSELECT * FROM dba_profiles; SELECT * FROM user_profiles; -- oracle 无此视图 SELECT * FROM all_profiles; -- oracle 无此视图 profile | resource_name | resource_type | limit ---------+-----------------------+---------------+----------- default | failed_login_attempts | password | unlimited default | password_lock_time | password | unlimited default | password_life_time | password | unlimited default | password_grace_time | password | unlimited default | password_reuse_time | password | unlimited default | password_reuse_max | password | unlimited default | idle_time | kernel | unlimited default | failed_login_attempts | password | unlimited 编号 参数名 取值范围 默认值 功能 1 failed_login_attempts [1, 2147483646], unlimited 10 登录数据库时，如果密码错误次数超过\u0026lt;本参数\u0026gt;，则账号会被锁定，短期内无法再登录 2 password_lock_time [0.00001, 2147483646], unlimited 1(day) 如果因密码错误次数过多，导致账号被锁，将锁定\u0026lt;本参数\u0026gt;的时间 3 password_life_time [0.00001, 2147483646], unlimited 180(day) password_effect_time, 设置或更新用户密码时，超过\u0026lt;本参数\u0026gt;的时间，密码会过期 4 password_grace_time [0.00001, 2147483646], unlimited 7(day) 如果密码过期，在\u0026lt;本参数\u0026gt;的时间内，密码仍可使用 5 password_reuse_time [0.00001, 2147483646], unlimited 1(day) 用户户设置密码时，如果密码在过去的\u0026lt;本参数\u0026gt;的时间内别用过，则密码不能复用 6 password_reuse_max [1, 2147483646], unlimited 1 用户设置密码时，如果密码已被重复使用过\u0026lt;本参数\u0026gt;的次数，则密码不能复用 7 idle_time [0.00001, 2147483646], unlimited 10(min) session_timeout 1个连接空闲时间限制 default\n2.4 正反向行为 2.4.1 生效说明 特性可用\n数据库可解析以下语法，则说明特性生效\nCREATE PROFILE profilename; 特性生效\n系统表vb_profiles与vb_profile_settings不为空，系统表中指定的用户使用系统表中的用户级GUC参数\n2.4.2 提示信息 新增DDL语法，正确执行时，符合DDL的显示格式CREATE PROFILE，ALTER PROFILE, DROP PROFILE 设置不符合约束的参数、参数取值类型等时，有明显的报错信息 2.4.3 约束和依赖 参数类型范围：在profile中，仅支持设置6个参数：[failed_login_attempts, password_effect_time, password_reuse_time, password_reuse_max, password_lock_time, session_timeout] 参数取值范围：profile支持的参数的取值类型、取值范围与对应的集群级guc参数相同 参数赋值约束：设置profile参数的值时，不支持使用表达式，例如CREATE PROFILE pro1 LIMIT failed_login_attempts 2 + 1，CREATE PROFILE pro1 LIMIT failed_login_attempts (SELECT num FROM t1) 特性生效模式：本特性在oracle兼容性模式下可用，在其他兼容性模式下不可用 特性权限约束：本特性中的CREATE PROFILE / ALTER PROFILE / DROP PROFILE的权限约束，与CREATE USER / ALTER USER / DROP USER一致 2.5 安全性 2.5.1 权限控制 本特性中的CREATE PROFILE / ALTER PROFILE / DROP PROFILE的权限约束，与CREATE USER / ALTER USER / DROP USER一致\n2.5.2 审计 适配统一审计，记录CREATE PROFILE / ALTER PROFILE / DROP PROFILE语法中的关键信息\n2.6 影响范围 2.6.1 对已有UDT,UDF, ECPG的影响 不涉及\n2.6.2 对系统函数的影响 未新增系统函数\n2.6.3 对系统CATALOG的影响 新增2个系统表\nvb_profile_settings\nproname | setname | setting | settype ------------+---------------------------+--------------------+------------ vb_profiles\nroloid | rolname | profile -------+---------+---------- 2.6.4 对xlog日志格式、数据格式的影响 未新增xlog类型，未修改现有xlog格式\n2.6.5 与其他功能交互时的行为表现 不涉及\n2.6.6 版本兼容性 本特性在oracle兼容性模式下可用，在其他兼容性模式下不可用\n2.7 指标相关 2.7.1 关键资源指标 内存占用：非常小。本特性将在内存中缓存系统表vb_profile_settings与vb_profiles的部分字段，假设有100个用户设置profile，每个用户设置3个参数，内存占用为100 * 3 * 100bytes = 30k 外存占用：非常小。与内存占用接近，数据级一般为几十到几百k CPU占用：非常小。仅在每个用户建立连接时，判断使用集群级还是用户级GUC参数检查密码登信息 网络占用：非常小 2.7.2 系统性指标 本特性是功能特性，无其他指标\n2.7.3 性能指标 仅影响建立连接的过程，不影响tpcc， tpch等指标。\n如果原来存在户与数据库建立连接的性能，该场景整体劣化不超过10%\n2.8 测试建议 可对比集群级GUC参数的值，验证用户级GUC参数（即profile功能）是否生效\n2.8 其他说明 无\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/2-requirement-profile/","summary":"\u003ch1 id=\"1-简介\"\u003e1 简介\u003c/h1\u003e\n\u003ch2 id=\"11-目的\"\u003e1.1 目的\u003c/h2\u003e\n\u003cp\u003evastbase与oracle都支持设置运行参数：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003evastbase：支持设置集群级guc参数，例如，guc参数failed_login_attempts用于设置’用户密码错误多少次后锁定账户’，该参数对集群中所有用户（非初始用户）都有效。\u003c/li\u003e\n\u003cli\u003eoracle：也支持failed_login_attempts参数，但是oracle支持为不同用户设置不同的failed_login_attempts值。我们且将此类参数称为用户级参数。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e与oracle相比，vastbase的guc参数功能存在2个差异：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e作用范围：oracle支持设置用户级参数，vastbase大部分参数都是集群级guc参数\u003c/li\u003e\n\u003cli\u003e参数个数：23版本的oracle支持18个用户级参数，其中6个可在vastbase找到对应的guc参数\u003c/li\u003e\n\u003cli\u003e参数取值：vastbase中，6个guc参数的取值范围与oracle profile不同\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e本文主要介绍以下几点：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eoracle用户级参数的个数、设置方法\u003c/li\u003e\n\u003cli\u003evastbase中对应集群级guc参数的个数、设置方法\u003c/li\u003e\n\u003cli\u003evastbase新需求：尽量实现与oracle一致的用户级guc参数\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e本文档可指导开发者、测试者熟悉vastbase用户级guc配置参数特性\u003c/p\u003e\n\u003cp\u003e本文档的内容已被上传至tapd，tapd上，排版更好看，测试用例更方便复制。建议直接从tapd上查看本文档原文: \u003ca href=\"https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007196\"\u003ehttps://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007196\u003c/a\u003e\u003c/p\u003e\n\u003ch2 id=\"12-适用范围\"\u003e1.2 适用范围\u003c/h2\u003e\n\u003cp\u003evastbase 3.0.8及之后版本，vastbase用户级参数profile特性接口设计、使用指导等。\u003c/p\u003e\n\u003ch2 id=\"13-术语定义首字母缩写词和缩略语\"\u003e1.3 术语定义、首字母缩写词和缩略语\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eGUC：Grand Unifed Configuralion，postgresql和vastbase的配置参数\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"13-参考资料\"\u003e1.3 参考资料\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e原始需求： \u003ca href=\"https://www.tapd.cn/60475194/prong/stories/view/1160475194001074627\"\u003ehttps://www.tapd.cn/60475194/prong/stories/view/1160475194001074627\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003etapd上本需求文档链接： \u003ca href=\"https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007196\"\u003ehttps://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007196\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003etapd上6个与密码相关的guc参数的使用参考： \u003ca href=\"https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007200\"\u003ehttps://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007200\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eoracle 23 profile语法以及相关参数： \u003ca href=\"https://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/CREATE-PROFILE.html\"\u003ehttps://docs.oracle.com/en/database/oracle/oracle-database/23/sqlrf/CREATE-PROFILE.html\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003emysql 8.0 create user语法以及相关参数： \u003ca href=\"https://mysql.net.cn/doc/refman/8.0/en/create-user.html\"\u003ehttps://mysql.net.cn/doc/refman/8.0/en/create-user.html\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003emysql 配置参数列表：\u003ca href=\"https://mysql.net.cn/doc/refman/8.0/en/server-system-variable-reference.html\"\u003ehttps://mysql.net.cn/doc/refman/8.0/en/server-system-variable-reference.html\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003evastbase g100 create user语法以及相关参数： \u003ca href=\"https://docs.vastdata.com.cn/zh_CN/VastbaseG100/V3.0.8/1/6a4766151e29496b9f88cd2d9dd3db2e\"\u003ehttps://docs.vastdata.com.cn/zh_CN/VastbaseG100/V3.0.8/1/6a4766151e29496b9f88cd2d9dd3db2e\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-支持oracle用户级配置profile\"\u003e2 支持oracle用户级配置profile\u003c/h1\u003e\n\u003ch2 id=\"21-功能简述\"\u003e2.1 功能简述\u003c/h2\u003e\n\u003ch3 id=\"需求来源桂林银行\"\u003e【需求来源】桂林银行\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e需求链接：\u003ca href=\"https://www.tapd.cn/60475194/prong/stories/view/1160475194001074627\"\u003ehttps://www.tapd.cn/60475194/prong/stories/view/1160475194001074627\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e需求描述：桂林银行客户指出，目前对于数据库用户的管理方式不够便捷，无法像oracle profile方式为用户赋予一组安全策略。一些属性如密码有效期、密码过期天数、密码尝试次数等也只能全局设定，无法指定用户配置。- 需求范围：桂林银行使用的数据库兼容模式包括oracle和mysql两种兼容模式。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"需求背景oracle-23的profile功能\"\u003e【需求背景】oracle 23的profile功能\u003c/h3\u003e\n\u003cp\u003e通俗来讲，oracle的profle可理解为细粒度的配置参数。1个profile包含1组配置参数，不同用户可使用不同的profile。按上述例子，要单独控制某个用户的密码有效期，操作步骤如下：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e创建用户\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eIDENTIFIED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;u1.1234\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e创建profile，同时设置用户级参数\u003cbr\u003e\n此处，以设置密码有效期参数为例：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePROFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epro1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eFAILED_LOGIN_ATTEMPTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e设置用户u1使用profile pro1\u003c/p\u003e","title":"海量 2 需求 profile"},{"content":"https://www.nowcoder.com/exam/oj/ta?page=1\u0026amp;tpId=13\u0026amp;type=13\n链表 从尾到头打印链表\n栈 递归 链表反转\n栈\n双指针\n1 -\u0026gt; 2 -\u0026gt; 3 -\u0026gt; 4 1 \u0026lt;- 2 -\u0026gt; 3 -\u0026gt; 4 递归\n合并两个有序链表\n迭代 递归 两个链表的第一个公共结点\n1 -\u0026gt; 2 -\u0026gt; 3 | 4 -\u0026gt; 5 |-\u0026gt; 6 -\u0026gt; 7 栈 双指针：先计算长度，再找起点 map：第一个cnt \u0026gt; 1的节点 链表中环的入口节点\n1 -\u0026gt; 2 -\u0026gt; 3 -\u0026gt; 4 -\u0026gt; 5 -\u0026gt; 6 -\u0026gt; 7 -\u0026gt; 8 ^ ^ 环 相遇（相遇时，快指针多走了1个环） 快指针：1 2 3 4 5 6 7 8 3 4 5 6 （前后长度一定相等：1 2 和 7 8） 慢指针：1 2 3 4 5 6 快指针：1 2 3 4 5 2 3 4 满指针：1 2 3 4 map：第一个cnt \u0026gt; 1的节点 快慢指针：首先，找到相遇节点；然后，慢指针接着走，新指针从头走（一次一步），再次相遇。 链表倒数第K个节点\n双指针：前指针先走K步 栈 复杂链表的复制\n1 -\u0026gt; 2 -\u0026gt; 3 -\u0026gt; 4 -\u0026gt; 5 3 5 * 2 * 1 _1 2 _2 3 _3 4 _4 5 _5 # 1. 复制后的新节点放在旧节点之后 3 5 * 2 * # 2. 找到旧节点的旧random节点 _3 _5 * _2 * # 3. 旧random节点的下一个节点即为新random节点 # 4. 拆分链表 双指针 哈希表：hash(旧节点) = 新节点 删除链表中重复节点\n输入：1 -\u0026gt; 2 -\u0026gt; 3 -\u0026gt; 3 -\u0026gt; 4 -\u0026gt; 4 -\u0026gt; 5 输出：1 -\u0026gt; 2 -\u0026gt; 5 直接删除 哈希表 删除链表的节点\n输入：1 -\u0026gt; 2 -\u0026gt; 3 -\u0026gt; 4 -\u0026gt; 5，删除 3 输出：1 -\u0026gt; 2 -\u0026gt; 4 -\u0026gt; 5 树 二叉树的深度\n按之字形顺序打印二叉树\n输入： 8 6 10 5 7 8 11 输出：[8], [10, 6], [5, 7, 9, 11] 队列 双栈 二叉搜索树的第k个节点\n输入： 8 第4个节点 6 10 5 7 8 11 输出：8 (5-\u0026gt;6-\u0026gt;7-\u0026gt;8) 递归：中序遍历，左子树小于根节点 重建二叉树：输入：前序遍历结果，中序遍历结果\n输入：[1,2,4,7,3,5,6,8], [4,7,2,1,5,3,8,6] 输出：{1,2,3,4,n,5,6,n,7,n,n,8} s1: 1 [2 4 7] [3 5 6 8] s2: 2 [4] [7] 3 [5] [8 6] 递归 树的子结构：tree a是tree b的子结构\n8 8 8 7 9 2 9 2 4 7 递归 二叉树的镜像：翻转二叉树\n从上往下打印二叉树：简单的层次打印\n数组是否是二叉搜索树的后序遍历\n递归\n[1 2 3 7 9 8 5] for left \u0026lt; root: 左子树小于root for right \u0026lt; root: 右子树大于root 递归 非递归：栈\n二叉树某一路径的和\n是否存在路径：根到叶子节点之和 = num\n8 22=8+8+2+4 8 7 9 2 4 7 二叉树某一路径的和 II\n所有路径：根节点到叶子节点之和 = sum\nDFS\nBFS\nleftpath = ... rightpath = ... rootpath = {l for l in leftpath.append(root), r for r in rightpath.append(root)} 二叉搜索树与双向链表\n将二叉树转换为双向链表\n递归\n输入： 10 6 14 4 8 12 16 输出：4 \u0026lt;-\u0026gt; 6 \u0026lt;-\u0026gt; 8 \u0026lt;-\u0026gt; 10 \u0026lt;-\u0026gt; 12 \u0026lt;-\u0026gt; 14 \u0026lt;-\u0026gt; 16 二叉树是否是平衡二叉树\n平衡二叉树：左右子树高度差不超过1\n递归 二叉树的下一个节点\n图 https://leetcode.cn/tag/graph/problemset/\n克隆图\n课程表\n先转换为临界表，{未搜索，搜索中，已搜索}\nDFS BFS 课程表II\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/algorithm/2-coding-interview-guide/","summary":"\u003cp\u003e\u003ca href=\"https://www.nowcoder.com/exam/oj/ta?page=1\u0026amp;tpId=13\u0026amp;type=13\"\u003ehttps://www.nowcoder.com/exam/oj/ta?page=1\u0026amp;tpId=13\u0026amp;type=13\u003c/a\u003e\u003c/p\u003e\n\u003ch1 id=\"链表\"\u003e链表\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e从尾到头打印链表\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e栈\u003c/li\u003e\n\u003cli\u003e递归\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e链表反转\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e栈\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e双指针\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e2\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e3\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e4\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e \u0026lt;- \u003cspan class=\"m\"\u003e2\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e3\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e4\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e递归\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e合并两个有序链表\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e迭代\u003c/li\u003e\n\u003cli\u003e递归\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e两个链表的第一个公共结点\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e2\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e3\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e     \u003cspan class=\"m\"\u003e4\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e5\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e-\u0026gt; \u003cspan class=\"m\"\u003e6\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e7\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e栈\u003c/li\u003e\n\u003cli\u003e双指针：先计算长度，再找起点\u003c/li\u003e\n\u003cli\u003emap：第一个cnt \u0026gt; 1的节点\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e链表中环的入口节点\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e2\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e3\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e4\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e5\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e6\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e7\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e8\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e          ^              ^\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e          环            相遇（相遇时，快指针多走了1个环）\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e快指针：1 \u003cspan class=\"m\"\u003e2\u003c/span\u003e \u003cspan class=\"m\"\u003e3\u003c/span\u003e \u003cspan class=\"m\"\u003e4\u003c/span\u003e \u003cspan class=\"m\"\u003e5\u003c/span\u003e \u003cspan class=\"m\"\u003e6\u003c/span\u003e \u003cspan class=\"m\"\u003e7\u003c/span\u003e \u003cspan class=\"m\"\u003e8\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e           \u003cspan class=\"m\"\u003e3\u003c/span\u003e \u003cspan class=\"m\"\u003e4\u003c/span\u003e \u003cspan class=\"m\"\u003e5\u003c/span\u003e \u003cspan class=\"m\"\u003e6\u003c/span\u003e     （前后长度一定相等：1 \u003cspan class=\"m\"\u003e2\u003c/span\u003e 和 \u003cspan class=\"m\"\u003e7\u003c/span\u003e 8）\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e慢指针：1 \u003cspan class=\"m\"\u003e2\u003c/span\u003e \u003cspan class=\"m\"\u003e3\u003c/span\u003e \u003cspan class=\"m\"\u003e4\u003c/span\u003e \u003cspan class=\"m\"\u003e5\u003c/span\u003e \u003cspan class=\"m\"\u003e6\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e快指针：1 \u003cspan class=\"m\"\u003e2\u003c/span\u003e \u003cspan class=\"m\"\u003e3\u003c/span\u003e \u003cspan class=\"m\"\u003e4\u003c/span\u003e \u003cspan class=\"m\"\u003e5\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e         \u003cspan class=\"m\"\u003e2\u003c/span\u003e \u003cspan class=\"m\"\u003e3\u003c/span\u003e \u003cspan class=\"m\"\u003e4\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e满指针：1 \u003cspan class=\"m\"\u003e2\u003c/span\u003e \u003cspan class=\"m\"\u003e3\u003c/span\u003e \u003cspan class=\"m\"\u003e4\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003emap：第一个cnt \u0026gt; 1的节点\u003c/li\u003e\n\u003cli\u003e快慢指针：首先，找到相遇节点；然后，慢指针接着走，新指针从头走（一次一步），再次相遇。\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e链表倒数第K个节点\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e双指针：前指针先走K步\u003c/li\u003e\n\u003cli\u003e栈\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e复杂链表的复制\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e2\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e3\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e4\u003c/span\u003e -\u0026gt; \u003cspan class=\"m\"\u003e5\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"m\"\u003e3\u003c/span\u003e    \u003cspan class=\"m\"\u003e5\u003c/span\u003e    *    \u003cspan class=\"m\"\u003e2\u003c/span\u003e    *\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e _1 \u003cspan class=\"m\"\u003e2\u003c/span\u003e _2 \u003cspan class=\"m\"\u003e3\u003c/span\u003e _3 \u003cspan class=\"m\"\u003e4\u003c/span\u003e _4 \u003cspan class=\"m\"\u003e5\u003c/span\u003e _5 \u003cspan class=\"c1\"\u003e# 1. 复制后的新节点放在旧节点之后\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   \u003cspan class=\"m\"\u003e3\u003c/span\u003e    \u003cspan class=\"m\"\u003e5\u003c/span\u003e    *    \u003cspan class=\"m\"\u003e2\u003c/span\u003e   *  \u003cspan class=\"c1\"\u003e# 2. 找到旧节点的旧random节点\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  _3   _5    *   _2   *  \u003cspan class=\"c1\"\u003e# 3. 旧random节点的下一个节点即为新random节点\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                         \u003cspan class=\"c1\"\u003e# 4. 拆分链表\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e双指针\u003c/li\u003e\n\u003cli\u003e哈希表：hash(旧节点) = 新节点\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e删除链表中重复节点\u003c/p\u003e","title":"数据结构与算法 2 剑指offer"},{"content":"1 语法解析概述 1.1 语法解析的目的 语法解析的目的\n用户向数据发送以下SQL语句时：\nCREATE TABLE t1 (c1 INT, c2 TEXT); INSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;); DELETE FROM t1 WHERE c1 = 1; 从用户的角度，掌握SQL语法后，我们很容易理解上述SQL的含义。\n从PostgreSQL的角度，上述语句知识一串字符串，需要根据SQL语法的规则，从字符串中解析表名、列名、数据等关键信息。\n语法解析的流程\n此处将语法解析的步骤简要分为以下4个阶段：\n定义语法：PostgreSQL开发人员需要根据SQL标准，制定一些类语法规则。比如： 当用户执行CREATE TABLE ..时，表示用户需要创建表 当用户执行CREATE TABLE tablename ..时，表示用户要创建的表名叫tablename 发布语法：PostgreSQL会在官网上发布其定义的各种语法 构造语句：当开发人员想让数据执行某些操作时，需根据数据库定义的语法，构造SQL语句，再让数据库执行。比如： 当用户想创建一个名为t1的表，需要构造SQL语句CREATE TABLE t1 .. 解析语法：PostgreSQL接收SQL语句后，根据语法规则，可解析SQL想要执行什么操作，生成1个结构体，结构中存储了SQL语句的关键信息，比如： 处理CREATE TABLE t1 ..，结构体中，将有1个变量表示表名，该变量的值将被复制为t1 执行语法：在解析用户操作后，生成一个结构体，即根据结构体，开始执行各种操作 1.2 语法解析的类型 PostgreSQL支持上百种语法，本文主要介绍以下4个常用的语法：\nCREATE TABLE .. SELECT .. FROM .. INSERT INTO .. DELETE FROM .. 2 解析语法 [ WITH [ RECURSIVE ] with_query [, ...] ] SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] * | expression [ [ AS ] output_name ] [, ...] [ FROM from_item [, ...] ] [ WHERE condition ] [ GROUP BY expression [, ...] ] [ HAVING condition [, ...] ] [ WINDOW window_name AS ( window_definition ) [, ...] ] [ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ] [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ] [ LIMIT { count | ALL } ] [ OFFSET start [ ROW | ROWS ] ] [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ] [ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ] -- from_item [ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ] [ LATERAL ] ( select ) [ AS ] alias [ ( column_alias [, ...] ) ] with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ] [ LATERAL ] function_name ( [ argument [, ...] ] ) [ AS ] alias [ ( column_alias [, ...] | column_definition [, ...] ) ] [ LATERAL ] function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] ) from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ] -- with_query with_query_name [ ( column_name [, ...] ) ] AS ( select | values | insert | update | delete ) TABLE [ ONLY ] table_name [ * ] 参考 http://www.postgres.cn/docs/9.3/sql-select.html\n1.2 语法解析 [SelectStmt] [select_with_parens] \u0026#39;(\u0026#39; select_no_parens \u0026#39;)\u0026#39; \u0026#39;(\u0026#39; select_with_parens \u0026#39;)\u0026#39; [select_no_parens] simple_select [select_clause] sort_clause [simple_select] SELECT opt_distinct target_list into_clause from_clause where_clause group_clause having_clause window_clause [values_clause] VALUES ctext_row values_clause \u0026#39;,\u0026#39; ctext_row TABLE [relation_expr] qualified_name qualified_name \u0026#39;*\u0026#39; ONLY qualified_name ONLY \u0026#39;(\u0026#39; qualified_name \u0026#39;)\u0026#39; select_clause UNION [opt_all] select_clause ALL DISTINCT - select_clause INTERSECT opt_all select_clause select_clause EXCEPT opt_all select_clause select_with_parens select_clause opt_sort_clause for_locking_clause opt_select_limit select_clause opt_sort_clause [select_limit] opt_for_locking_clause [limit_clause] offset_clause LIMIT [select_limit_value] a_expr ALL LIMIT select_limit_value \u0026#39;,\u0026#39; [select_offset_value] a_expr FETCH first_or_next [opt_select_fetch_first_value] row_or_rows ONLY SignedIconst \u0026#39;(\u0026#39; a_expr \u0026#39;)\u0026#39; - offset_clause limit_clause limit_clause [offset_clause] OFFSET select_offset_value OFFSET [select_offset_value2] row_or_rows c_expr [with_clause] select_clause WITH [cte_list] common_table_expr name [opt_name_list] AS \u0026#39;(\u0026#39; PreparableStmt \u0026#39;)\u0026#39; with_clause cte_list WITH RECURSIVE cte_list with_clause select_clause sort_clause with_clause select_clause opt_sort_clause for_locking_clause [opt_select_limit] select_limit - with_clause select_clause opt_sort_clause select_limit opt_for_locking_clause target_list [target_el] a_expr AS ColLabel a_expr IDENT a_expr \u0026#39;*\u0026#39; target_list \u0026#39;,\u0026#39; target_el into_clause INTO [OptTempTableName] TEMPORARY [opt_table] qualified_name TABLE - TEMP opt_table qualified_name LOCAL TEMPORARY opt_table qualified_name LOCAL TEMP opt_table qualified_name GLOBAL TEMPORARY opt_table qualified_name GLOBAL TEMP opt_table qualified_name UNLOGGED opt_table qualified_name TABLE qualified_name qualified_name - [from_clause] FROM [from_list] [table_ref] relation_expr relation_expr [alias_clause] AS ColId \u0026#39;(\u0026#39; name_list \u0026#39;)\u0026#39; AS ColId ColId \u0026#39;(\u0026#39; name_list \u0026#39;)\u0026#39; ColId [func_table] [func_expr] func_name \u0026#39;(\u0026#39; \u0026#39;)\u0026#39; [over_clause] OVER [window_specification] \u0026#39;(\u0026#39; [opt_existing_window_name] opt_partition_clause opt_sort_clause opt_frame_clause \u0026#39;)\u0026#39; ColId - OVER ColId - func_name \u0026#39;(\u0026#39; [func_arg_list] \u0026#39;)\u0026#39; over_clause [func_arg_expr] a_expr param_name COLON_EQUALS a_expr func_arg_list \u0026#39;,\u0026#39; func_arg_expr func_name \u0026#39;(\u0026#39; VARIADIC func_arg_expr \u0026#39;)\u0026#39; over_clause func_name \u0026#39;(\u0026#39; func_arg_list \u0026#39;,\u0026#39; VARIADIC func_arg_expr \u0026#39;)\u0026#39; over_clause func_name \u0026#39;(\u0026#39; func_arg_list sort_clause \u0026#39;)\u0026#39; over_clause func_name \u0026#39;(\u0026#39; ALL func_arg_list opt_sort_clause \u0026#39;)\u0026#39; over_clause func_name \u0026#39;(\u0026#39; DISTINCT func_arg_list opt_sort_clause \u0026#39;)\u0026#39; over_clause func_name \u0026#39;(\u0026#39; \u0026#39;*\u0026#39; \u0026#39;)\u0026#39; over_clause COLLATION FOR \u0026#39;(\u0026#39; a_expr \u0026#39;)\u0026#39; CURRENT_DATE CURRENT_TIME CURRENT_TIME \u0026#39;(\u0026#39; Iconst \u0026#39;)\u0026#39; CURRENT_TIMESTAMP ... CAST \u0026#39;(\u0026#39; a_expr AS Typename \u0026#39;)\u0026#39; POSITION \u0026#39;(\u0026#39; position_list \u0026#39;)\u0026#39; func_table alias_clause func_table AS \u0026#39;(\u0026#39; [TableFuncElementList] \u0026#39;)\u0026#39; ColId [Typename] opt_collate_clause SimpleTypename [opt_array_bounds] opt_array_bounds \u0026#39;[\u0026#39; \u0026#39;]\u0026#39; opt_array_bounds \u0026#39;[\u0026#39; Iconst \u0026#39;]\u0026#39; - SETOF [SimpleTypename] opt_array_bounds ... SimpleTypename ARRAY \u0026#39;[\u0026#39; Iconst \u0026#39;]\u0026#39; SETOF SimpleTypename ARRAY \u0026#39;[\u0026#39; Iconst \u0026#39;]\u0026#39; SimpleTypename ARRAY SETOF SimpleTypename ARRAY func_table AS ColId \u0026#39;(\u0026#39; TableFuncElementList \u0026#39;)\u0026#39; func_table ColId \u0026#39;(\u0026#39; TableFuncElementList \u0026#39;)\u0026#39; select_with_parens select_with_parens alias_clause [joined_table] \u0026#39;(\u0026#39; joined_table \u0026#39;)\u0026#39; table_ref CROSS JOIN table_ref table_ref [join_type] JOIN table_ref join_qual FULL [join_outer] OUTER_P - LEFT join_outer RIGHT join_outer INNER_P table_ref JOIN table_ref [join_qual] USING \u0026#39;(\u0026#39; name_list \u0026#39;)\u0026#39; ON a_expr table_ref NATURAL join_type JOIN table_ref table_ref NATURAL JOIN table_ref \u0026#39;(\u0026#39; joined_table \u0026#39;)\u0026#39; alias_clause from_list \u0026#39;,\u0026#39; table_ref - [group_clause] GROUP_P BY [expr_list] a_expr expr_list \u0026#39;,\u0026#39; a_expr - [opt_distinct] DISTINCT DISTINCT ON \u0026#39;(\u0026#39; expr_list \u0026#39;)\u0026#39; ALL - [opt_sort_clause] sort_clause ORDER BY [sortby_list] sortby a_expr USING qual_all_Op opt_nulls_order a_expr opt_asc_desc opt_nulls_order sortby_list \u0026#39;,\u0026#39; sortby - [row_or_rows] ROW ROWS [first_or_next] FIRST_P NEXT [having_clause] HAVING a_expr - [opt_for_locking_clause] [for_locking_clause] [for_locking_items] [for_locking_item] FOR UPDATE [locked_rels_list] opt_nowait OF qualified_name_list - FOR SHARE locked_rels_list opt_nowait for_locking_items for_locking_item FOR READ ONLY - [where_clause] WHERE [a_expr] c_expr a_expr TYPECAST Typename a_expr COLLATE any_name a_expr AT TIME ZONE a_expr \u0026#39;+\u0026#39; a_expr \u0026#39;-\u0026#39; a_expr a_expr {\u0026#39;+ - * / % ^ \u0026lt; \u0026gt; =\u0026#39;} a_expr a_expr qual_Op a_expr qual_Op a_expr a_expr qual_Op a_expr AND a_expr a_expr OR a_expr NOT a_expr a_expr LIKE a_expr a_expr LIKE a_expr ESCAPE a_expr a_expr NOT LIKE a_expr a_expr NOT LIKE a_expr ESCAPE a_expr a_expr ILIKE a_expr a_expr NOT ILIKE a_expr a_expr SIMILAR TO a_expr a_expr SIMILAR TO a_expr ESCAPE a_expr a_expr NOT SIMILAR TO a_expr a_expr NOT SIMILAR TO a_expr ESCAPE a_expr a_expr IS NULL_P a_expr ISNULL a_expr IS NOT NULL_P a_expr NOTNULL row OVERLAPS row a_expr IS TRUE_P a_expr IS FALSE_P a_expr IS NOT FALSE_P ... - [b_expr] ... [c_expr] todo [window_clause] WINDOW [window_definition_list] [window_definition] ColId AS window_specification window_definition_list \u0026#39;,\u0026#39; window_definition - [opt_partition_clause] PARTITION BY expr_list - [opt_frame_clause] RANGE [frame_extent] [frame_bound] UNBOUNDED PRECEDING UNBOUNDED FOLLOWING CURRENT_P ROW a_expr PRECEDING a_expr FOLLOWING BETWEEN frame_bound AND frame_bound ROWS frame_extent - 参考 pg源码 src/backend/parser/gram.y\n个人源码阅读 http://124.70.36.226:3000/?folder=/home/lorand/postgres/postgresql_9.2.4\nsql语法 1 概述 1.1 语法 [ WITH [ RECURSIVE ] with_query [, ...] ] SELECT [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ] * | expression [ [ AS ] output_name ] [, ...] [ FROM from_item [, ...] ] [ WHERE condition ] [ GROUP BY expression [, ...] ] [ HAVING condition [, ...] ] [ WINDOW window_name AS ( window_definition ) [, ...] ] [ { UNION | INTERSECT | EXCEPT } [ ALL | DISTINCT ] select ] [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ] [ LIMIT { count | ALL } ] [ OFFSET start [ ROW | ROWS ] ] [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ] [ FOR { UPDATE | NO KEY UPDATE | SHARE | KEY SHARE } [ OF table_name [, ...] ] [ NOWAIT ] [...] ] -- from_item [ ONLY ] table_name [ * ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ] [ LATERAL ] ( select ) [ AS ] alias [ ( column_alias [, ...] ) ] with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ] [ LATERAL ] function_name ( [ argument [, ...] ] ) [ AS ] alias [ ( column_alias [, ...] | column_definition [, ...] ) ] [ LATERAL ] function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] ) from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ] -- with_query with_query_name [ ( column_name [, ...] ) ] AS ( select | values | insert | update | delete ) TABLE [ ONLY ] table_name [ * ] 参考 http://www.postgres.cn/docs/9.3/sql-select.html\n1.2 语法解析 [SelectStmt] [select_with_parens] \u0026#39;(\u0026#39; select_no_parens \u0026#39;)\u0026#39; \u0026#39;(\u0026#39; select_with_parens \u0026#39;)\u0026#39; [select_no_parens] simple_select [select_clause] sort_clause [simple_select] SELECT opt_distinct target_list into_clause from_clause where_clause group_clause having_clause window_clause [values_clause] VALUES ctext_row values_clause \u0026#39;,\u0026#39; ctext_row TABLE [relation_expr] qualified_name qualified_name \u0026#39;*\u0026#39; ONLY qualified_name ONLY \u0026#39;(\u0026#39; qualified_name \u0026#39;)\u0026#39; select_clause UNION [opt_all] select_clause ALL DISTINCT - select_clause INTERSECT opt_all select_clause select_clause EXCEPT opt_all select_clause select_with_parens select_clause opt_sort_clause for_locking_clause opt_select_limit select_clause opt_sort_clause [select_limit] opt_for_locking_clause [limit_clause] offset_clause LIMIT [select_limit_value] a_expr ALL LIMIT select_limit_value \u0026#39;,\u0026#39; [select_offset_value] a_expr FETCH first_or_next [opt_select_fetch_first_value] row_or_rows ONLY SignedIconst \u0026#39;(\u0026#39; a_expr \u0026#39;)\u0026#39; - offset_clause limit_clause limit_clause [offset_clause] OFFSET select_offset_value OFFSET [select_offset_value2] row_or_rows c_expr [with_clause] select_clause WITH [cte_list] common_table_expr name [opt_name_list] AS \u0026#39;(\u0026#39; PreparableStmt \u0026#39;)\u0026#39; with_clause cte_list WITH RECURSIVE cte_list with_clause select_clause sort_clause with_clause select_clause opt_sort_clause for_locking_clause [opt_select_limit] select_limit - with_clause select_clause opt_sort_clause select_limit opt_for_locking_clause target_list [target_el] a_expr AS ColLabel a_expr IDENT a_expr \u0026#39;*\u0026#39; target_list \u0026#39;,\u0026#39; target_el into_clause INTO [OptTempTableName] TEMPORARY [opt_table] qualified_name TABLE - TEMP opt_table qualified_name LOCAL TEMPORARY opt_table qualified_name LOCAL TEMP opt_table qualified_name GLOBAL TEMPORARY opt_table qualified_name GLOBAL TEMP opt_table qualified_name UNLOGGED opt_table qualified_name TABLE qualified_name qualified_name - [from_clause] FROM [from_list] [table_ref] relation_expr relation_expr [alias_clause] AS ColId \u0026#39;(\u0026#39; name_list \u0026#39;)\u0026#39; AS ColId ColId \u0026#39;(\u0026#39; name_list \u0026#39;)\u0026#39; ColId [func_table] [func_expr] func_name \u0026#39;(\u0026#39; \u0026#39;)\u0026#39; [over_clause] OVER [window_specification] \u0026#39;(\u0026#39; [opt_existing_window_name] opt_partition_clause opt_sort_clause opt_frame_clause \u0026#39;)\u0026#39; ColId - OVER ColId - func_name \u0026#39;(\u0026#39; [func_arg_list] \u0026#39;)\u0026#39; over_clause [func_arg_expr] a_expr param_name COLON_EQUALS a_expr func_arg_list \u0026#39;,\u0026#39; func_arg_expr func_name \u0026#39;(\u0026#39; VARIADIC func_arg_expr \u0026#39;)\u0026#39; over_clause func_name \u0026#39;(\u0026#39; func_arg_list \u0026#39;,\u0026#39; VARIADIC func_arg_expr \u0026#39;)\u0026#39; over_clause func_name \u0026#39;(\u0026#39; func_arg_list sort_clause \u0026#39;)\u0026#39; over_clause func_name \u0026#39;(\u0026#39; ALL func_arg_list opt_sort_clause \u0026#39;)\u0026#39; over_clause func_name \u0026#39;(\u0026#39; DISTINCT func_arg_list opt_sort_clause \u0026#39;)\u0026#39; over_clause func_name \u0026#39;(\u0026#39; \u0026#39;*\u0026#39; \u0026#39;)\u0026#39; over_clause COLLATION FOR \u0026#39;(\u0026#39; a_expr \u0026#39;)\u0026#39; CURRENT_DATE CURRENT_TIME CURRENT_TIME \u0026#39;(\u0026#39; Iconst \u0026#39;)\u0026#39; CURRENT_TIMESTAMP ... CAST \u0026#39;(\u0026#39; a_expr AS Typename \u0026#39;)\u0026#39; POSITION \u0026#39;(\u0026#39; position_list \u0026#39;)\u0026#39; func_table alias_clause func_table AS \u0026#39;(\u0026#39; [TableFuncElementList] \u0026#39;)\u0026#39; ColId [Typename] opt_collate_clause SimpleTypename [opt_array_bounds] opt_array_bounds \u0026#39;[\u0026#39; \u0026#39;]\u0026#39; opt_array_bounds \u0026#39;[\u0026#39; Iconst \u0026#39;]\u0026#39; - SETOF [SimpleTypename] opt_array_bounds ... SimpleTypename ARRAY \u0026#39;[\u0026#39; Iconst \u0026#39;]\u0026#39; SETOF SimpleTypename ARRAY \u0026#39;[\u0026#39; Iconst \u0026#39;]\u0026#39; SimpleTypename ARRAY SETOF SimpleTypename ARRAY func_table AS ColId \u0026#39;(\u0026#39; TableFuncElementList \u0026#39;)\u0026#39; func_table ColId \u0026#39;(\u0026#39; TableFuncElementList \u0026#39;)\u0026#39; select_with_parens select_with_parens alias_clause [joined_table] \u0026#39;(\u0026#39; joined_table \u0026#39;)\u0026#39; table_ref CROSS JOIN table_ref table_ref [join_type] JOIN table_ref join_qual FULL [join_outer] OUTER_P - LEFT join_outer RIGHT join_outer INNER_P table_ref JOIN table_ref [join_qual] USING \u0026#39;(\u0026#39; name_list \u0026#39;)\u0026#39; ON a_expr table_ref NATURAL join_type JOIN table_ref table_ref NATURAL JOIN table_ref \u0026#39;(\u0026#39; joined_table \u0026#39;)\u0026#39; alias_clause from_list \u0026#39;,\u0026#39; table_ref - [group_clause] GROUP_P BY [expr_list] a_expr expr_list \u0026#39;,\u0026#39; a_expr - [opt_distinct] DISTINCT DISTINCT ON \u0026#39;(\u0026#39; expr_list \u0026#39;)\u0026#39; ALL - [opt_sort_clause] sort_clause ORDER BY [sortby_list] sortby a_expr USING qual_all_Op opt_nulls_order a_expr opt_asc_desc opt_nulls_order sortby_list \u0026#39;,\u0026#39; sortby - [row_or_rows] ROW ROWS [first_or_next] FIRST_P NEXT [having_clause] HAVING a_expr - [opt_for_locking_clause] [for_locking_clause] [for_locking_items] [for_locking_item] FOR UPDATE [locked_rels_list] opt_nowait OF qualified_name_list - FOR SHARE locked_rels_list opt_nowait for_locking_items for_locking_item FOR READ ONLY - [where_clause] WHERE [a_expr] c_expr a_expr TYPECAST Typename a_expr COLLATE any_name a_expr AT TIME ZONE a_expr \u0026#39;+\u0026#39; a_expr \u0026#39;-\u0026#39; a_expr a_expr {\u0026#39;+ - * / % ^ \u0026lt; \u0026gt; =\u0026#39;} a_expr a_expr qual_Op a_expr qual_Op a_expr a_expr qual_Op a_expr AND a_expr a_expr OR a_expr NOT a_expr a_expr LIKE a_expr a_expr LIKE a_expr ESCAPE a_expr a_expr NOT LIKE a_expr a_expr NOT LIKE a_expr ESCAPE a_expr a_expr ILIKE a_expr a_expr NOT ILIKE a_expr a_expr SIMILAR TO a_expr a_expr SIMILAR TO a_expr ESCAPE a_expr a_expr NOT SIMILAR TO a_expr a_expr NOT SIMILAR TO a_expr ESCAPE a_expr a_expr IS NULL_P a_expr ISNULL a_expr IS NOT NULL_P a_expr NOTNULL row OVERLAPS row a_expr IS TRUE_P a_expr IS FALSE_P a_expr IS NOT FALSE_P ... - [b_expr] ... [c_expr] todo [window_clause] WINDOW [window_definition_list] [window_definition] ColId AS window_specification window_definition_list \u0026#39;,\u0026#39; window_definition - [opt_partition_clause] PARTITION BY expr_list - [opt_frame_clause] RANGE [frame_extent] [frame_bound] UNBOUNDED PRECEDING UNBOUNDED FOLLOWING CURRENT_P ROW a_expr PRECEDING a_expr FOLLOWING BETWEEN frame_bound AND frame_bound ROWS frame_extent - 参考 pg源码 src/backend/parser/gram.y\n个人源码阅读 http://124.70.36.226:3000/?folder=/home/lorand/postgres/postgresql_9.2.4\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/2-1-parse/","summary":"\u003ch1 id=\"1-语法解析概述\"\u003e1 语法解析概述\u003c/h1\u003e\n\u003ch2 id=\"11-语法解析的目的\"\u003e1.1 语法解析的目的\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e语法解析的目的\u003cbr\u003e\n用户向数据发送以下SQL语句时：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-fallback\" data-lang=\"fallback\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eCREATE TABLE t1 (c1 INT, c2 TEXT);\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eINSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;);\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eDELETE FROM t1 WHERE c1 = 1;\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e从用户的角度，掌握SQL语法后，我们很容易理解上述SQL的含义。\u003cbr\u003e\n从PostgreSQL的角度，上述语句知识一串字符串，需要根据SQL语法的规则，从字符串中解析表名、列名、数据等关键信息。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e语法解析的流程\u003cbr\u003e\n此处将语法解析的步骤简要分为以下4个阶段：\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003col\u003e\n\u003cli\u003e定义语法：PostgreSQL开发人员需要根据SQL标准，制定一些类语法规则。比如：\n\u003cul\u003e\n\u003cli\u003e当用户执行\u003ccode\u003eCREATE TABLE ..\u003c/code\u003e时，表示用户需要创建表\u003c/li\u003e\n\u003cli\u003e当用户执行\u003ccode\u003eCREATE TABLE tablename ..\u003c/code\u003e时，表示用户要创建的表名叫\u003ccode\u003etablename\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e发布语法：PostgreSQL会在官网上发布其定义的各种语法\u003c/li\u003e\n\u003cli\u003e构造语句：当开发人员想让数据执行某些操作时，需根据数据库定义的语法，构造SQL语句，再让数据库执行。比如：\n\u003cul\u003e\n\u003cli\u003e当用户想创建一个名为\u003ccode\u003et1\u003c/code\u003e的表，需要构造SQL语句\u003ccode\u003eCREATE TABLE t1 ..\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e解析语法：PostgreSQL接收SQL语句后，根据语法规则，可解析SQL想要执行什么操作，生成1个结构体，结构中存储了SQL语句的关键信息，比如：\n\u003cul\u003e\n\u003cli\u003e处理\u003ccode\u003eCREATE TABLE t1 ..\u003c/code\u003e，结构体中，将有1个变量表示表名，该变量的值将被复制为\u003ccode\u003et1\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e执行语法：在解析用户操作后，生成一个结构体，即根据结构体，开始执行各种操作\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"12-语法解析的类型\"\u003e1.2 语法解析的类型\u003c/h2\u003e\n\u003cp\u003ePostgreSQL支持上百种语法，本文主要介绍以下4个常用的语法：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eCREATE TABLE ..\u003c/li\u003e\n\u003cli\u003eSELECT .. FROM ..\u003c/li\u003e\n\u003cli\u003eINSERT INTO ..\u003c/li\u003e\n\u003cli\u003eDELETE FROM ..\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"2-解析语法\"\u003e2 解析语法\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eRECURSIVE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ewith_query\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eALL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDISTINCT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eexpression\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eexpression\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eoutput_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efrom_item\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003econdition\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eGROUP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eexpression\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eHAVING\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003econdition\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eWINDOW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ewindow_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ewindow_definition\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUNION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTERSECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXCEPT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eALL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDISTINCT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eselect\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eexpression\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eASC\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDESC\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSING\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eoperator\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eNULLS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFIRST\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLAST\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLIMIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecount\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eALL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eOFFSET\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003estart\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eROW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eROWS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFETCH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFIRST\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eNEXT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecount\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eROW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eROWS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eONLY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUPDATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eNO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUPDATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSHARE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSHARE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eOF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etable_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eNOWAIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- from_item\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eONLY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etable_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ealias\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecolumn_alias\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLATERAL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eselect\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ealias\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecolumn_alias\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003ewith_query_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ealias\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecolumn_alias\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLATERAL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efunction_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eargument\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ealias\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecolumn_alias\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecolumn_definition\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLATERAL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efunction_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eargument\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecolumn_definition\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003efrom_item\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eNATURAL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ejoin_type\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efrom_item\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ejoin_condition\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSING\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ejoin_column\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- with_query\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003ewith_query_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecolumn_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eselect\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003evalues\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003einsert\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eupdate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003edelete\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eONLY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etable_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cblockquote\u003e\n\u003cp\u003e参考 \u003ca href=\"http://www.postgres.cn/docs/9.3/sql-select.html\"\u003ehttp://www.postgres.cn/docs/9.3/sql-select.html\u003c/a\u003e\u003c/p\u003e","title":"PostgreSQL 2-1 Parse"},{"content":"1 概述 1.1 语义分析的目的 语义分析的目的\n上文提到，PostgreSQL接收SQL语句时，会生成1个语法解析树，语法解析树存储了SQL语法中的关键信息。比如，在语法INSERT INTO t1 VALUES(1, 'data1')中，解析结果可说明： 这是一条用于插入数据的INSERT语法 数据将插入t1表中 要插入的数据是(1, 'data1') …\n但是，数据库执行时，还需要更多的关键信息才行，比如，在INSERT INTO t1 VALUES(1, 'data1')的语法树中，PostgreSQL需要获取一些关键信息： 数据库中是否有表叫t1 t1表有几列，每列的的数据类型是什么 语法中的值(1, 'data1')是否符合t1表的定义 … 1.2 本文的目标 本文以几个常见且简单的语法为例，介绍语义分析的详细功能\nCREATE TABLE .. SELECT .. FROM .. INSERT INTO .. DELETE FROM .. 1.3 语义分析的调用关系 exec_simple_query pg_parse_query pg_analyze_and_rewrite parse_analyze 1.1 整体流程 // 语义分析 exec_simple_query pg_parse_query pg_analyze_and_rewrite parse_analyze transformTopLevelStmt transformOptionalSelectInto transformStmt transformInsertStmt exec_simple_query() pg_parse_query() for (;;): pg_analyze_and_rewrite() Query *query = parse_analyze(Node *parsetree) List *querytree_list = pg_rewrite_query(query) pg_plan_queries() PortalRun() 1.2 分析器 Query *parse_analyze(Node *parseTree) ParseState *pstate = make_parsestate() Query *query = query = transformTopLevelStmt(pstate, parseTree) query = transformStmt(pstate, parseTree) /* 对各种类型语法进行语义分析 */ Query *result switch nodeTag(parseTree) { case T_InsertStmt: result = transformInsertStmt(pstate, (InsertStmt *) parseTree) case T_DeleteStmt: result = transformDeleteStmt(pstate, (DeleteStmt *) parseTree) case T_UpdateStmt: result = transformUpdateStmt(pstate, (UpdateStmt *) parseTree) case T_SelectStmt: SelectStmt *n = (SelectStmt *) parseTree; if n-\u0026gt;valuesLists: transformValuesClause(pstate, n) else if n-\u0026gt;op == SETOP_NONE: result = transformSelectStmt(pstate, n) case T_DeclareCursorStmt: ... case T_ExplainStmt: ... case T_CreateTableAsStmt: ... default: result = makeNode(Query) result-\u0026gt;commandType = CMD_UTILITY result-\u0026gt;utilityStmt = (Node *) parseTree } return result; 1.3 SELECT 分析 Query *transformSelectStmt(ParseState *pstate, SelectStmt *stmt) Query *qry = makeNode(Query) if stmt-\u0026gt;withClause: qry-\u0026gt;cteList = transformWithClause(pstate, stmt-\u0026gt;withClause) transformFromClause(pstate, stmt-\u0026gt;fromClause) qry-\u0026gt;targetList = transformTargetList(pstate, stmt-\u0026gt;targetList) markTargetListOrigins(pstate, qry-\u0026gt;targetList) Node *qual = transformWhereClause(pstate, stmt-\u0026gt;whereClause) qry-\u0026gt;havingQual = transformWhereClause(pstate, stmt-\u0026gt;havingClause) qry-\u0026gt;sortClause = transformSortClause(pstate, stmt-\u0026gt;sortClause, \u0026amp;qry-\u0026gt;targetList) qry-\u0026gt;groupClause = transformGroupClause(pstate, stmt-\u0026gt;groupClause, \u0026amp;qry-\u0026gt;groupingSets, \u0026amp;qry-\u0026gt;targetList, qry-\u0026gt;sortClause) qry-\u0026gt;distinctClause = transformDistinctOnClause(pstate, stmt-\u0026gt;distinctClause, \u0026amp;qry-\u0026gt;targetList, qry-\u0026gt;sortClause) qry-\u0026gt;limitOffset = transformLimitClause(pstate, stmt-\u0026gt;limitOffset) qry-\u0026gt;limitCount = transformLimitClause(pstate, stmt-\u0026gt;limitCount) qry-\u0026gt;windowClause = transformWindowDefinitions(pstate, pstate-\u0026gt;p_windowdefs, \u0026amp;qry-\u0026gt;targetList) qry-\u0026gt;jointree = makeFromExpr(pstate-\u0026gt;p_joinlist, qual) if pstate-\u0026gt;p_hasAggs || qry-\u0026gt;groupClause || qry-\u0026gt;groupingSets || qry-\u0026gt;havingQual: parseCheckAggregates(pstate, qry) assign_query_collations(pstate, qry) return qry ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/2-2-analyze/","summary":"\u003ch1 id=\"1-概述\"\u003e1 概述\u003c/h1\u003e\n\u003ch2 id=\"11-语义分析的目的\"\u003e1.1 语义分析的目的\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e语义分析的目的\u003cbr\u003e\n上文提到，PostgreSQL接收SQL语句时，会生成1个语法解析树，语法解析树存储了SQL语法中的关键信息。比如，在语法\u003ccode\u003eINSERT INTO t1 VALUES(1, 'data1')\u003c/code\u003e中，解析结果可说明：\u003c/li\u003e\n\u003c/ul\u003e\n\u003col\u003e\n\u003cli\u003e这是一条用于插入数据的INSERT语法\u003c/li\u003e\n\u003cli\u003e数据将插入t1表中\u003c/li\u003e\n\u003cli\u003e要插入的数据是\u003ccode\u003e(1, 'data1')\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e…\u003cbr\u003e\n但是，数据库执行时，还需要更多的关键信息才行，比如，在\u003ccode\u003eINSERT INTO t1 VALUES(1, 'data1')\u003c/code\u003e的语法树中，PostgreSQL需要获取一些关键信息：\u003c/li\u003e\n\u003cli\u003e数据库中是否有表叫t1\u003c/li\u003e\n\u003cli\u003et1表有几列，每列的的数据类型是什么\u003c/li\u003e\n\u003cli\u003e语法中的值\u003ccode\u003e(1, 'data1')\u003c/code\u003e是否符合t1表的定义\u003c/li\u003e\n\u003cli\u003e…\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"12-本文的目标\"\u003e1.2 本文的目标\u003c/h2\u003e\n\u003cp\u003e本文以几个常见且简单的语法为例，介绍语义分析的详细功能\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eCREATE TABLE ..\u003c/li\u003e\n\u003cli\u003eSELECT .. FROM ..\u003c/li\u003e\n\u003cli\u003eINSERT INTO ..\u003c/li\u003e\n\u003cli\u003eDELETE FROM ..\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"13-语义分析的调用关系\"\u003e1.3 语义分析的调用关系\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eexec_simple_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_parse_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_analyze_and_rewrite\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eparse_analyze\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"11-整体流程\"\u003e1.1 整体流程\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 语义分析\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eexec_simple_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_parse_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_analyze_and_rewrite\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eparse_analyze\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003etransformTopLevelStmt\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003etransformOptionalSelectInto\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003etransformStmt\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003etransformInsertStmt\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eexec_simple_query\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003epg_parse_query\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(;;)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003epg_analyze_and_rewrite\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eQuery\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003equery\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eparse_analyze\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eNode\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eparsetree\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eList\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003equerytree_list\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003epg_rewrite_query\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003equery\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003epg_plan_queries\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003ePortalRun\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"12-分析器\"\u003e1.2 分析器\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eQuery\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"nf\"\u003eparse_analyze\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eNode\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eparseTree\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eParseState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003emake_parsestate\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eQuery\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003equery\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003equery\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etransformTopLevelStmt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eparseTree\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003equery\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etransformStmt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eparseTree\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 对各种类型语法进行语义分析 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eQuery\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eresult\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"nf\"\u003enodeTag\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eparseTree\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003eT_InsertStmt\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eresult\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etransformInsertStmt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eInsertStmt\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003eparseTree\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003eT_DeleteStmt\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eresult\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etransformDeleteStmt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eDeleteStmt\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003eparseTree\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003eT_UpdateStmt\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eresult\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etransformUpdateStmt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eUpdateStmt\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003eparseTree\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003eT_SelectStmt\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eSelectStmt\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003en\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSelectStmt\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003eparseTree\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"nl\"\u003evaluesLists\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"nf\"\u003etransformValuesClause\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"k\"\u003eelse\u003c/span\u003e \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eop\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"nl\"\u003eSETOP_NONE\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eresult\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etransformSelectStmt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003en\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003eT_DeclareCursorStmt\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"p\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003eT_ExplainStmt\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"p\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003eT_CreateTableAsStmt\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"p\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eresult\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003emakeNode\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eQuery\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eresult\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ecommandType\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eCMD_UTILITY\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eresult\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eutilityStmt\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eNode\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003eparseTree\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eresult\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"13-select-分析\"\u003e1.3 SELECT 分析\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eQuery\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"nf\"\u003etransformSelectStmt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eParseState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eSelectStmt\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eQuery\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eqry\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003emakeNode\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eQuery\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"nl\"\u003ewithClause\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ecteList\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etransformWithClause\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ewithClause\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003etransformFromClause\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003efromClause\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etargetList\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etransformTargetList\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etargetList\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003emarkTargetListOrigins\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etargetList\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eNode\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003equal\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etransformWhereClause\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ewhereClause\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ehavingQual\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etransformWhereClause\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ehavingClause\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003esortClause\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etransformSortClause\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003esortClause\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etargetList\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003egroupClause\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etransformGroupClause\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003egroupClause\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003egroupingSets\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etargetList\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003esortClause\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003edistinctClause\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etransformDistinctOnClause\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003edistinctClause\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etargetList\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003esortClause\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003elimitOffset\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etransformLimitClause\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003elimitOffset\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003elimitCount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etransformLimitClause\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estmt\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003elimitCount\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ewindowClause\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etransformWindowDefinitions\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ep_windowdefs\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etargetList\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ejointree\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003emakeFromExpr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ep_joinlist\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003equal\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ep_hasAggs\u003c/span\u003e \u003cspan class=\"o\"\u003e||\u003c/span\u003e \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003egroupClause\u003c/span\u003e \u003cspan class=\"o\"\u003e||\u003c/span\u003e \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003egroupingSets\u003c/span\u003e \u003cspan class=\"o\"\u003e||\u003c/span\u003e \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"nl\"\u003ehavingQual\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003eparseCheckAggregates\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eassign_query_collations\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eqry\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"PostgreSQL 2-2 Analyze"},{"content":" 重写功能\n-- 创建2个表 CREATE TABLE t1 (c1 INT, c2 TEXT); CREATE TABLE t2 (c1 INT, c2 TEXT); -- 创建1条重写规则 -- 触发条件：向t1表写入数据时 -- 执行操作：将SQL语句重写为：同时向t2写入相同数据 CREATE OR REPLACE RULE r1 AS ON INSERT TO t1 DO ALSO INSERT INTO t2 VALUES (new.c1, new.c2); -- 向t1写入一条数据 INSERT INTO t1 VALUES (1, \u0026#39;abc\u0026#39;); -- 验证t2也写入了一条数据 SELECT * FROM t2; DROP TABLE t1,t2; 重写规则\n语法\n定义重写规则的语法如下：\nCREATE [ OR REPLACE ] RULE name AS ON { SELECT | INSERT | UPDATE | DELETE } TO table_name [ WHERE condition ] DO [ ALSO | INSTEAD ] { NOTHING | command | ( command ; command ... ) } 约束\nSELECT：只能有1个动作，不带条件的INSTEAD INSERT / UPDATE / DELETE：可以无动作，可以多动作；可使用伪关系NEW和OLD。可使用规则条件。不修改查询树，废弃院查询树，重建0或多个查询树 重写原理\n创建重写规则\n用户使用CREATE RULE语法定义重写规则时，将重写规则存储至系统表中\nCREATE TABLE t1 (c1 INT, c2 TEXT); CREATE TABLE t2 (c1 INT, c2 TEXT); CREATE OR REPLACE RULE r1 AS ON INSERT TO t1 WHERE c1 \u0026gt; 1 DO ALSO INSERT INTO t2 VALUES (new.c1 + 1, new.c2); -- 查看系统表 SELECT * FROM pg_rewrite WHERE rulename = \u0026#39;r1\u0026#39;; -- 解释：如果在ev_class表上，执行ev_type，而且满足ev_qual操作，则执行ev_action中的动作 -- 在pg.10版本中，执行以下函数报错 SELECT pg_get_expr(ev_action, ev_class) FROM pg_rewrite WHERE rulename = \u0026#39;r1\u0026#39;; -- 走读代码，发现以下SQL语句可查看所有视图 SELECT pg_get_ruledef((SELECT oid FROM pg_rewrite WHERE rulename = \u0026#39;r1\u0026#39;)); -- 扩展：以下SQL语句可查看所有视图 SELECT ev_class::regclass WHERE pg_rewrite; -- 查看视图 SELECT * FROM pg_rules; 出发重写规则\npg_rewrite_query QueryRewrite RewriteQuery # 处理 INSERT / UPDATe / DELETE，因为可能包含ALSO，增加额外的SQL语句 if CMD_SELECT: rewriteTargetListIU elif CMD_UPDATE: rewriteTargetListUD elif CMD_DELETE: rewriteTargetListUD if not instead: # 如果不是 INSTEAD 类型的 重写规则 rewriteTargetView fireRIRules ApplyRetriiveRule get_row_security_policies # \u0026lt;安全模块\u0026gt; 行级访问控制，后面讲 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/2-3-rewrite/","summary":"\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e重写功能\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 创建2个表\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 创建1条重写规则\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 触发条件：向t1表写入数据时\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 执行操作：将SQL语句重写为：同时向t2写入相同数据\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eREPLACE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eRULE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003er1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eALSO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003enew\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 向t1写入一条数据\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;abc\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 验证t2也写入了一条数据\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e重写规则\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e语法\u003cbr\u003e\n定义重写规则的语法如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eREPLACE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eRULE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ename\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUPDATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDELETE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etable_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003econdition\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eDO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eALSO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINSTEAD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e{\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eNOTHING\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecommand\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecommand\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecommand\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e...\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e}\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e约束\u003c/p\u003e","title":"PostgreSQL 2-3 Rewrite"},{"content":"SQL 引擎 1 概述 1.1 生成计划的目的 上文提到，在语法分析、语义分析之后，PostgreSQL已获取执行所需的详细信息。计划生成主要针对一些复杂的SQL语句，主要是SQL语句，计划器主要告诉PostgreSQL，如何更高效地执行复杂的SQL语句：\n示例1\n假设，有1个表，表上有1个索引，表中有1000万条数据\nCREATE TABLE t1 (c1 INT, c2 TEXT); CREATE INDEX i1 ON t1(c1); INSERT INTO t1 .. -- 假设1000万条数据 当用户执行以下SQL语句时，数据库需要从t1表中，依次扫描所有的数据，此时，索引并没有什么作用：\nSELECT * FROM t1; 当用户执行以下数据时，数据有2种执行方案：\n语句\nSELECT * FROM t1 WHERE c1 = 10000; 方案1：依次扫描t1表所有数据，然后找到c1=10000的几行\n方案2：先扫描索引i1，找到c1=10000的几行数据所在的位置，再去t1表中指定位置读取数据\n显然，上述示例中，方案2的执行速度更快，数据库需要根据一定的策略，选择哪种执行方案。这便是计划器的职责。\n1.2 生成计划的场景 SQL语法\nCREATE TABLE t1 (c1 INT, c2 TEXT); INSERT INTO t1 VALUES (1, \u0026#39;data-1\u0026#39;), (2, \u0026#39;data-2\u0026#39;); ANALYZE; SELECT * FROM pg_statistic WHERE starelid = \u0026#39;t1\u0026#39;::regclass; 1.3 计划的简单表示 1.4 算子的分类 共40个\n扫描算子(16)\nNode Init Function Exec Function End Function Seq Scan ExecInitSeqScan ExecSeqScan ExecEndSeqScan Index Scan ExecInitIndexScan ExecIndexScan ExecEndIndexScan Index Only Scan ExecInitIndexOnlyScan ExecIndexOnlyScan ExecEndIndexOnlyScan Bitmap Heap Scan ExecInitBitmapHeapScan ExecBitmapHeapScan ExecEndBitmapHeapScan Bitmap Index Scan ExecInitBitmapIndexScan ExecBitmapIndexScan ExecEndBitmapIndexScan Tid Scan ExecInitTidScan ExecTidScan ExecEndTidScan Tid Range Scan ExecInitTidRangeScan ExecTidRangeScan ExecEndTidRangeScan Subquery Scan ExecInitSubqueryScan ExecSubqueryScan ExecEndSubqueryScan Function Scan ExecInitFunctionScan ExecFunctionScan ExecEndFunctionScan Table Func Scan ExecInitTableFuncScan ExecTableFuncScan ExecEndTableFuncScan Values Scan ExecInitValuesScan ExecValuesScan ExecEndValuesScan CTE Scan ExecInitCteScan ExecCteScan ExecEndCteScan Named Tuplestore Scan ExecInitNamedTuplestoreScan ExecNamedTuplestoreScan ExecEndNamedTuplestoreScan WorkTable Scan ExecInitWorkTableScan ExecWorkTableScan ExecEndWorkTableScan Foreign Scan ExecInitForeignScan ExecForeignScan ExecEndForeignScan Sample Scan ExecInitSampleScan ExecSampleScan ExecEndSampleScan 连接算子(3)\nNode Init Function Exec Function End Function Nested Loop ExecInitNestLoop ExecNestLoop ExecEndNestLoop Hash Join ExecInitHashJoin ExecHashJoin ExecEndHashJoin Merge Join ExecInitMergeJoin ExecMergeJoin ExecEndMergeJoin 聚集算子(15)\nNode Init Function Exec Function End Function Sort ExecInitSort ExecSort ExecEndSort Incremental Sort ExecInitIncrementalSort ExecIncrementalSort ExecEndIncrementalSort Aggregate ExecInitAgg ExecAgg ExecEndAgg Group ExecInitGroup ExecGroup ExecEndGroup Unique ExecInitUnique ExecUnique ExecEndUnique Hash ExecInitHash ExecHash ExecEndHash Limit ExecInitLimit ExecLimit ExecEndLimit Material ExecInitMaterial ExecMaterial ExecEndMaterial Memoize ExecInitMemoize ExecMemoize ExecEndMemoize Gather ExecInitGather ExecGather ExecEndGather Gather Merge ExecInitGatherMerge ExecGatherMerge ExecEndGatherMerge Window Agg ExecInitWindowAgg ExecWindowAgg ExecEndWindowAgg Set Op ExecInitSetOp ExecSetOp ExecEndSetOp Lock Rows ExecInitLockRows ExecLockRows ExecEndLockRows Modify Table ExecInitModifyTable ExecModifyTable ExecEndModifyTable 物化算子(6)\nNode Init Function Exec Function End Function Append ExecInitAppend ExecAppend ExecEndAppend Merge Append ExecInitMergeAppend ExecMergeAppend ExecEndMergeAppend Result ExecInitResult ExecResult ExecEndResult Project Set ExecInitProjectSet ExecProjectSet ExecEndProjectSet Recursive Union ExecInitRecursiveUnion ExecRecursiveUnion ExecEndRecursiveUnion Custom Scan ExecInitCustomScan ExecCustomScan ExecEndCustomScan 2 算子 2.0 算子分类 一、扫描算子 - SeqScan CREATE TABLE t1 (c1 INT, c2 TEXT); INSERT INTO t1 VALUES (generate_series(1, 1000), \u0026#39;data\u0026#39;); SELECT * FROM t1 WHERE c1 = 1; - SampleScan CREATE TABLE t1 (c1 INT, c2 TEXT); INSERT INTO t1 VALUES (generate_series(1, 1000), \u0026#39;data\u0026#39;); SELECT count(*) FROM t1 TABLESAMPLE BERNOULLI(10); -- 随机查询约10%的数据 - IndexScan CREATE TABLE t1 (c1 INT, c2 TEXT); INSERT INTO t1 VALUES (generate_series(1, 1000), \u0026#39;data\u0026#39;); CREATE INDEX i1 ON t1(c1); ANALYZE; SELECT * FROM t1 WHERE c1 = 1; - IndexOnlyScan CREATE TABLE t1 (c1 INT, c2 TEXT); INSERT INTO t1 VALUES (generate_series(1, 1000), \u0026#39;data\u0026#39;); CREATE INDEX i1 ON t1(c1); ANALYZE; SELECT c1 FROM t1 WHERE c1 = 1; - BitmapIndexScan - 根据Tid构造Bitmap - BitmapHeapScan - 根据Bitmap扫描表 - TidScan CREATE TABLE t1 (c1 INT, c2 TEXT); INSERT INTO t1 VALUES (generate_series(1, 1000), \u0026#39;data\u0026#39;); SELECT * FROM t1 WHERE ctid = \u0026#39;(0, 3)\u0026#39;; -- 查询第0号Page中的第3个Tuple (只查询可见Tuple) SELECT ctid FROM t1 WHERE c1 = 100; - FunctionScan SELECT * FROM random(); -- 函数的返回值构成1个Tuple - ValuesScan SELECT * FROM (VALUES (1, \u0026#39;data1\u0026#39;), (2, \u0026#39;data2\u0026#39;), (3, \u0026#39;data3\u0026#39;)) AS t1(c1, c2); - CteScan - ForeignScan - CustomScan - 使用C语言自定义扫描路径与扫描计划 二、控制算子 - Result SELECT 1 + 2; -- 场景1：优化一些与常量等价的条件 INSERT INTO t1 VALUES (1, \u0026#39;data\u0026#39;); -- 场景2：封装一些VALUES子句 - ModifyTable CREATE TABLE t1 (c1 INT, c2 TEXT); INSERT INTO t1 VALUES (1, \u0026#39;data\u0026#39;); -- ModifyTable算子包括：INSERT / UPDATE / DELTE 算子 UPDATE t1 SET c2 = \u0026#39;data2\u0026#39; WHERE c1 = 1; DELETE FROM t1 WHERE c1 = 1; - Append CREATE TABLE t1 (c1 INT, c2 TEXT); CREATE TABLE t2 (c1 INT, c2 TEXT); (SELECT * FROM t1) UNION ALL (SELECT * FROM t2); -- 拼接不同执行计划的结果 - MergeAppend - RecursiveUnion - BitmapAnd - BitmapOr 三、连接算子 - NestLoop CREATE TABLE t1 (c1 INT, c2 TEXT); CREATE TABLE t2 (c1 INT, c2 TEXT); INSERT INTO t1 VALUES (generate_series(1, 1000), \u0026#39;data\u0026#39;); INSERT INTO t2 VALUES (generate_series(1, 100), \u0026#39;data\u0026#39;); SELECT t1.c1,t2.c1 FROM t1 INNER JOIN t2 ON t1.c1 = 1; -- 2层for循环 -- for i in t1 [tup-1, tup-1000] -- for j in t2 [tup-1, tup-100] -- do compare - MergeJoin CREATE TABLE t1 (c1 INT, c2 TEXT); CREATE TABLE t2 (c1 INT, c2 TEXT); INSERT INTO t1 VALUES (generate_series(1, 1000), \u0026#39;data\u0026#39;); INSERT INTO t2 VALUES (generate_series(1, 100), \u0026#39;data\u0026#39;); SELECT t1.c1,t2.c1 FROM t1 INNER JOIN t2 ON (t1.c1 = t2.c1); -- 先排序，再循环 -- sort for i in t1 [tup-1, tup-1000] -- sort for j in t2 [tup-1, tup-100 -- for i in sort [tup-1, tup-1000] -- for j in sort [tup-1, tup-100] -- do compare - HashJoin CREATE TABLE t1 (c1 INT, c2 TEXT); CREATE TABLE t2 (c1 INT, c2 TEXT); INSERT INTO t1 VALUES (generate_series(1, 1000), \u0026#39;data\u0026#39;); INSERT INTO t2 VALUES (generate_series(1, 100), \u0026#39;data\u0026#39;); SELECT t1.c1,t2.c1 FROM t1 INNER JOIN t2 ON (t1.c1 = t2.c1); -- 先哈希，再循环 -- hash [tup-1, tup-1000] -- for j in t2 sort [tup-1, tup-100] -- do compare 四、物化算子 - Material CREATE TABLE t1 (c1 INT, c2 TEXT); CREATE TABLE t2 (c1 INT, c2 TEXT); SELECT * FROM t1 WHERE c1 \u0026gt; ANY (SELECT c1 FROM t2); -- 如果某些数据集合较大，需增加物化算子缓存数据集合 - Sort CREATE TABLE t1 (c1 INT, c2 TEXT); SELECT * FROM t1 ORDER BY c1; - Group CREATE TABLE t1 (c1 INT, c2 TEXT); INSERT INTO t1 VALUES (generate_series(1, 1000), \u0026#39;data\u0026#39;); SELECT c1 FROM t1 GROUP BY c1 ORDER BY c1; - Agg - HashAgg - GroupAgg CREATE TABLE t1 (c1 INT, c2 TEXT); INSERT INTO t1 VALUES (generate_series(1, 1000), \u0026#39;data\u0026#39;); SELECT c1 FROM t1 GROUP BY c1; -- 聚合数据，使用HASH聚合 SELECT count(*) FROM t1 GROUP BY c1 ORDER BY c1; -- 聚合数据，使用Group聚合 - WindowAgg - Unique CREATE TABLE t1 (c1 INT, c2 TEXT); INSERT INTO t1 VALUES (1, \u0026#39;data1-1\u0026#39;), (1, \u0026#39;data1-2\u0026#39;), (2, \u0026#39;data2\u0026#39;); ANALYZE; SELECT DISTINCT(c1) FROM t1 GROUP BY c1; - Hash - SetOp - LockRows - Limit CREATE TABLE t1 (c1 INT, c2 TEXT); INSERT INTO t1 VALUES (1, \u0026#39;data1-1\u0026#39;), (1, \u0026#39;data1-2\u0026#39;), (2, \u0026#39;data2\u0026#39;); SELECT * FROM t1 LIMIT 1; 2.1 扫描算子 问题场景 一、SeqScan | PageIdx | Tuple Idx | c1 | c2 | +---------+-----------+----+-------+ | | 1 | 6 | data6 | | 1 | 2 | 8 | data8 | | | 3 | 4 | data4 | +---------+-----------+----+-------+ | | 1 | 9 | data9 | | 2 | 2 | 1 | data1 | | | 3 | 8 | data8 | +---------+-----------+----+-------+ 源码\nExecSeqScan ExecScan ExecScanFetch SeqNext heap_beginscan heap_getnext heapgettup 二、IndexScan 前置条件：存储数据\n| PageIdx | Tuple Idx | c1 | c2 | +---------+-----------+----+-------+ | | 1 [delete]| 6 | data6 | | 1 | 2 | 8 | data8 | 存在被删除的数据 | [delete]| 3 | 4 | data4 | +---------+-----------+----+-------+---- | | 1 | 9 | data9 | | 2 | 2 | 1 | data1 | 不存在被删除的数据 | | 3 | 8 | data8 | +---------+-----------+----+-------+ | PageIdx | Tuple Idx | c1 | tid | +---------+-----------+----+-------+ | | 1 | 1 | [2,2] | | 1 | 2 | 4 | [1,3] | | | 3 | 6 | [1,1] | +---------+-----------+----+-------+ \\ \\ | PageIdx | Tuple Idx | c1 | tid | +---------+-----------+----+-------+ | | 1 | 8 | [1,2] | | 2 | 2 | 8 | [2,3] | | | 3 | 9 | [2,1] | +---------+-----------+----+-------+ 查询数据\nSELECT * FROM t1 WHERE c1 \u0026gt; 6 AND c1 \u0026lt; 9; 查找数据\n在Index中，找到c1=8的数据对应的tid=[1,2] 在Heap中，读取1个Page，获取第2个Tuple 在Index中，找到c1=8的数据对应的tid=[2,3] 在Heap中，读取2个Page，获取第3个Tuple 返回数据\nc1 | c2 ----+-------- 8 | data8 8 | data8 源码\nExecIndexScan ExecScan ExecScanFetch IndexNext index_beginscan index_getnext tid = index_getnext_tid # 1 扫描index page, 获取idx tup，获取heap tup的tid amgettuple -\u0026gt; btgettup # 5 如果上次扫描的idx tup对应的heap tup已被删除，将上次扫描的idx tup记录在scan中 if scan-\u0026gt;kill_prior_tuple: so-\u0026gt;killedItems[so-\u0026gt;numKilled++] index_fetch_heap # 2 根据tid，从heap page中，获取heap tup heap_page_prune_opt heap_hot_search_buffer # 3 遍历 hot 链，查找tuple scan-\u0026gt;kill_prior_tuple = true # 4 如果未找到，标记当前heap tup已被删除 ExecEndIndexScan index_endscan amendscan -\u0026gt; btendscan _bt_killitems # 6 如果有些heap tup已被删除，将它们对于的idx tup也设置删除标记 _bt_killitems _bt_getbuf ItemIdMarkDead # ItemId-\u0026gt;lp_flags = LP_DEAD IndexScanEnd 三、IndexOnlyScan 功能：直接从Index中获取大部分数据\n前置条件：存储数据\n| PageIdx | Tuple Idx | c1 | c2 | +---------+-----------+----+-------+ | | 1 [delete]| 6 | data6 | | 1 | 2 | 8 | data8 | 存在被删除的数据 | [delete]| 3 | 4 | data4 | +---------+-----------+----+-------+---- | | 1 | 9 | data9 | | 2 | 2 | 1 | data1 | 不存在被删除的数据 | | 3 | 8 | data8 | +---------+-----------+----+-------+ | PageIdx | Tuple Idx | c1 | tid | +---------+-----------+----+-------+ | | 1 | 1 | [2,2] | | 1 | 2 | 4 | [1,3] | | | 3 | 6 | [1,1] | +---------+-----------+----+-------+ \\ \\ | PageIdx | Tuple Idx | c1 | tid | +---------+-----------+----+-------+ | | 1 | 8 | [1,2] | | 2 | 2 | 8 | [2,3] | | | 3 | 9 | [2,1] | +---------+-----------+----+-------+ 查询数据\n必要条件：要查找的列，全在索引文件中\nSELECT c1 FROM t1 WHERE c1 \u0026gt; 6 AND c1 \u0026lt; 9; 查找数据\n从索引中，基于B+树的原理，快速找到c1=6的Tid为[1,1] 从Vm文件中，判断第1个表Page是否包含被标记删除的Tuple，发现1第个Page，存在被删除的Tuple 读取表文件的第1个Page，然后找到第1个Tuple 从索引中，找到c1=8,Tid=[1,2]的Tuple 源码\nExecIndexOnlyScan ExecScan ExecScanFetch IndexOnlyNext index_beginscan tid = index_getnext_tid # 1 扫描index page, 获取idx tup，获取heap tup的tid if !VM_ALL_VISIBLE(tid.ip_blkid) # 2 判断heap tup所在的page，是否全部tup可见 tup = index_fetch_heap # 3 如果非全部可见，扫描haep page，获取heap tup # 如果tup不可见，继续扫描一个idx tup ExecStoreTuple # 从idx tup中，获取数据，此次扫描结束 四、BitmapScan 场景1 多个索引上查询\nCREATE TABLE t1 (c1 INT, c2 INT); CREATE INDEX i1 ON t1(c1); CREATE INDEX i2 ON t1(c2); explain SELECT * FROM t1 WHERE c1 \u0026gt; 5 AND c2 \u0026lt; 5; 使用索引 i1，构造bitmap 1\n使用所以 i2，构造bitmap 2\nbitmap 1 AND bitmap 2\n查找数据 找到需要读取的Tuple [1,1] [1,2] [2,3] 读取第1个Page，获取第1和第2个Tuple 读取第2个Page，获取第3个Tuple ExecBitmapIndexScan ExecBitmapHeapScan ExecScan ExecScanFetch BitmapHeapNext 五、SubquryScan 六、 1.1 概述 优化方法\n逻辑优化：RBO：基于规则：关系代数，等价变化 物理优化：CBO：查询优化：物理执行路径 1.2 逻辑优化 关系代数\n选择 投影 笛卡尔积 并集 差集 非关系代数\n聚集 分组 常用方法\n选择操作下推 叶子节点投影 1.2 物理优化 四个法宝\nb+树 hash表 排序 物化 物理路径搜索\n自底向上：动态规划 自顶向下：枚举 随机搜索 postgresql\n表少：动态规划 表多：遗传算法 2 查询树 结构体 Var RangeTblEntry / RangleTblRef JoinExpr FromExpr Query 函数 query_tree_mutator / query_tree_walker walker：遍历查询树：修改节点值，但不会增加或删除节点 mutator：增加或删除节点 3 逻辑重写优化 3.2 提升子查询 查询\n子连接 sublink：以表达式形式存在 WHERE / ON 子句 （伴随 ANY/ALL/IN/EXISTS/SOME 等谓语） 投影 子句 子查询 subquery：范围表形式 FROM 子句 子查询\n相关子查询：子查询引用外层表列属性：外层表执行一次，子查询执行一次 （可提升） 非相关子查询：子查询语句独立，外表重复利用子查询结果 3.2.1 提升子链接 子链接类型\nEXISTS_SUBLINK （提升） ALL_SUBLINK ANY_SUBLINK (提升) exec_simple_query() pg_parse_query() for (;;): pg_analyze_and_rewrite() pg_plan_queries() PortalRun() 1.2 计划器 pg_plan_queries() pg_plan_query(Query) PlannedStmt *plan = planner(Query) standard_planner(Query) PlannerGlobal *glob = makeNode(PlannerGlobal) subquery_planner(PlannerGlobal *glob, Query *parse, PlannerInfo **subroot) PlannerInfo *root = makeNode(PlannerInfo) root-\u0026gt;parse = parse if parse-\u0026gt;cteList: SS_process_ctes(root) if parse-\u0026gt;hasSubLinks: pull_up_sublinks(root) inline_set_returning_functions(root) pull_up_subqueries(root) if parse-\u0026gt;setOperations: flatten_simple_union_all(root) preprocess_rowmarks(root) xpand_inherited_tables(root) parse-\u0026gt;targetList = preprocess_expression(root, parse-\u0026gt;targetList) parse-\u0026gt;returningList = preprocess_expression(root, parse-\u0026gt;returningList) preprocess_qual_conditions(root, parse-\u0026gt;jointree) parse-\u0026gt;havingQual = preprocess_expression(root, parse-\u0026gt;havingQual) parse-\u0026gt;limitOffset = preprocess_expression(root, parse-\u0026gt;limitOffset) parse-\u0026gt;limitCount = preprocess_expression(root, parse-\u0026gt;limitCount) root-\u0026gt;append_rel_list = preprocess_expression(root, root-\u0026gt;append_rel_list) ... if hasOuterJoins: reduce_outer_joins(root) /* do the main plainning */ if parse-\u0026gt;resultRelation: plan = inheritance_planner(root) else: plan = grouping_planner(root) if parse-\u0026gt;commandType != CMD_SELECT: plan = make_modifytable(root, plan, SS_assign_special_param(root)) return plan 1.3 计划器执行流程 grouping_planner(PlannerInfo *root) Query *parse = root-\u0026gt;parse if parse-\u0026gt;limitCount || parse-\u0026gt;limitOffset: preprocess_limit(root) if parse-\u0026gt;setOperations: List *set_sortclauses Plan *result_plan = plan_set_operations(root, \u0026amp;set_sortclauses) List *current_pathkeys = make_pathkeys_for_sortclauses(root, set_sortclauses, result_plan-\u0026gt;targetlist) parse-\u0026gt;targetList = postprocess_setop_tlist(result_plan-\u0026gt;targetlist) root-\u0026gt;sort_pathkeys = make_pathkeys_for_sortclauses(root, parse-\u0026gt;sortClause) else: ... parse-\u0026gt;targetList = preprocess_targetlist(root, parse-\u0026gt;targetList) expand_security_quals(root, parse-\u0026gt;targetList) ... RelOptInfo *final_rel = query_planner(root, standard_qp_callback) path_rows = clamp_row_est(final_rel-\u0026gt;rows) ... sorted_path = get_cheapest_fractional_path_for_pathkeys() ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/2-4-plan/","summary":"\u003ch1 id=\"sql-引擎\"\u003eSQL 引擎\u003c/h1\u003e\n\u003ch1 id=\"1-概述\"\u003e1 概述\u003c/h1\u003e\n\u003ch2 id=\"11-生成计划的目的\"\u003e1.1 生成计划的目的\u003c/h2\u003e\n\u003cp\u003e上文提到，在语法分析、语义分析之后，PostgreSQL已获取执行所需的详细信息。计划生成主要针对一些复杂的SQL语句，主要是SQL语句，计划器主要告诉PostgreSQL，如何更高效地执行复杂的SQL语句：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e示例1\u003cbr\u003e\n假设，有1个表，表上有1个索引，表中有1000万条数据\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINDEX\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假设1000万条数据\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e当用户执行以下SQL语句时，数据库需要从t1表中，依次扫描所有的数据，此时，索引并没有什么作用：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e当用户执行以下数据时，数据有2种执行方案：\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e语句\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10000\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e方案1：依次扫描t1表所有数据，然后找到c1=10000的几行\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e方案2：先扫描索引i1，找到c1=10000的几行数据所在的位置，再去t1表中指定位置读取数据\u003cbr\u003e\n显然，上述示例中，方案2的执行速度更快，数据库需要根据一定的策略，选择哪种执行方案。这便是计划器的职责。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"12-生成计划的场景\"\u003e1.2 生成计划的场景\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003eSQL语法\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;data-1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;data-2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eANALYZE\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_statistic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estarelid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eregclass\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"13-计划的简单表示\"\u003e1.3 计划的简单表示\u003c/h2\u003e\n\u003ch2 id=\"14-算子的分类\"\u003e1.4 算子的分类\u003c/h2\u003e\n\u003cp\u003e共40个\u003c/p\u003e","title":"PostgreSQL 2-4 Plan"},{"content":"1 概述 1.1 总接口 main PostmasterMain ServerLoop for (;;) select # 接收TCP连接 BackendStartup fork_process # fork postgres进程，用于处理SQL # postgres子进程执行： BackendRun # postgres子进程 BackendRun PostgresMain for (;;) ReadCommand exec_simple_query pg_parse_query # 语法解析 pg_analyze_and_rewrite # 语义分析 查询重写 pg_plan_queries # 计划生成 CreatePortal PortalDefineQuery PortalStart PortalRun PortalRunSelect ExecutorRun # 计划执行 standard_ExecutorRun ExecutePlan for (;;) ExecProcNode ExecSeqScan # SELECT 计划执行 SeqNext heap_beginscan heap_getnext PortalRunMulti # DDL执行 PortalRunUtility ProcessUtility standard_ProcessUtility ExecDropStmt # DROP TABLE ProcessUtilitySlow DefineRelation # CREATE TABLE ProcessQuery ExecutorStart ExecutorRun # 计划执行 standard_ExecutorRun ExecutePlan for (;;) ExecProcNode ExecModifyTable ExecInsert # INSERT 计划执行 heap_insert ExecUpdate # UPDATE 计划执行 heap_update ExecDelete # DELETE 计划执行 heap_delete ExecutorFinish ExecutorEnd PortalDrop exec_simple_query pg_plan_queries pg_plan_query planner standard_planner subquery_planner pull_up_subqueries preprocess_qual_conditions grouping_planner query_planner make_one_rel set_base_rel_pathlists # 查找所有Scan类型 set_rel_pathlist set_plain_rel_pathlist create_seqscan_path create_index_paths get_index_paths generate_bitmap_or_paths create_tidscan_paths get_cheapest_fractional_path create_plan create_plan_recurse create_scan_plan 1.2 算子类型 TupleTableSlot *ExecProcNode(PlanState *node) /* 控制算子 */ ExecResult((ResultState *) node); ExecModifyTable((ModifyTableState *) node); ExecAppend((AppendState *) node); ExecMergeAppend((MergeAppendState *) node); ExecRecursiveUnion((RecursiveUnionState *) node); /* 扫描算子 */ ExecSeqScan((SeqScanState *) node); ExecSampleScan((SampleScanState *) node); ExecIndexScan((IndexScanState *) node); ExecIndexOnlyScan((IndexOnlyScanState *) node); ExecBitmapHeapScan((BitmapHeapScanState *) node); ExecTidScan((TidScanState *) node); ExecSubqueryScan((SubqueryScanState *) node); ExecFunctionScan((FunctionScanState *) node); ExecValuesScan((ValuesScanState *) node); ExecCteScan((CteScanState *) node); ExecWorkTableScan((WorkTableScanState *) node); ExecForeignScan((ForeignScanState *) node); ExecCustomScan((CustomScanState *) node); /* 连接算子 */ ExecNestLoop((NestLoopState *) node); ExecMergeJoin((MergeJoinState *) node); ExecHashJoin((HashJoinState *) node); /* 物化算子 */ ExecMaterial((MaterialState *) node); ExecSort((SortState *) node); ExecGroup((GroupState *) node) ExecAgg((AggState *) node); ExecWindowAgg((WindowAggState *) node) ExecUnique((UniqueState *) node); ExecHash((HashState *) node); ExecSetOp((SetOpState *) node) ExecLockRows((LockRowsState *) node); ExecLimit((LimitState *) node); 2 算子 2.1 ExecSort /* 主要流程 */ TupleTableSlot *ExecSort(SortState *node) Tuplesortstate *tuplesortstate = node-\u0026gt;tuplesortstate if !node-\u0026gt;sort_Done: PlanState *outerNode = outerPlanState(node) tuplesortstate = tuplesort_begin_heap(ExecGetResultType(outerNode), numCols, sortColIdx, sortOperators) for (;;) /* 子节点扫描tup */ slot = ExecProcNode(outerNode) tuplesort_puttupleslot(tuplesortstate, slot) tuplesort_performsort(tuplesortstate) slot = node-\u0026gt;ss.ps.ps_ResultTupleSlot tuplesort_gettupleslot(tuplesortstate, ScanDirectionIsForward(dir), slot) return slot /* 1 准备 */ Tuplesortstate *tuplesort_begin_heap(TupleDesc tupDesc, int nkeys, AttrNumber *attNums, Oid *sortOperators, Oid *sortCollations, bool *nullsFirstFlags) Tuplesortstate *state; state-\u0026gt;comparetup = comparetup_heap state-\u0026gt;copytup = copytup_heap; state-\u0026gt;writetup = writetup_heap state-\u0026gt;readtup = readtup_heap state-\u0026gt;sortKeys = palloc0(nkeys * sizeof(SortSupportData)) for i in range(nkeys): SortSupport sortKey = state-\u0026gt;sortKeys + i sortKey-\u0026gt;ssup_attno = attNums[i] /* 2 扫描存储 */ void tuplesort_puttupleslot(Tuplesortstate *state, TupleTableSlot *slot) SortTuple stup COPYTUP(state, \u0026amp;stup, (void *) slot) puttuple_common(state, \u0026amp;stup) { switch state-\u0026gt;status: case TSS_INITIAL: if state-\u0026gt;memtupcount \u0026gt;= state-\u0026gt;memtupsize: grow_memtuples(state) state-\u0026gt;memtuples[state-\u0026gt;memtupcount++] = *tuple if state-\u0026gt;bounded: make_bounded_heap(state) inittapes(state) { int maxTapes = tuplesort_merge_order(state-\u0026gt;allowedMem) + 1 tapeSpace = (int64) maxTapes *TAPE_BUFFER_OVERHEAD /* 创建临时文件 */ PrepareTempTablespaces() state-\u0026gt;tapeset = LogicalTapeSetCreate(maxTapes) state-\u0026gt;mergenext = palloc0(maxTapes * sizeof(int)) state-\u0026gt;mergeavailslots = palloc0(maxTapes * sizeof(int)) ... ntuples = state-\u0026gt;memtupcount state-\u0026gt;memtupcount = 0 for j = 0; j \u0026lt; ntuples; j++ SortTuple stup = state-\u0026gt;memtuples[j] tuplesort_heap_insert(state, \u0026amp;stup, 0, false) ... state-\u0026gt;status = TSS_BUILDRUNS } dumptuples(state, false) { while state-\u0026gt;memtupcount \u0026gt;= state-\u0026gt;memtupsize: /* = writetup_heap */ WRITETUP(state, state-\u0026gt;tp_tapenum[state-\u0026gt;destTape], \u0026amp;state-\u0026gt;memtuples[0]) tuplesort_heap_siftup(state, true) if state-\u0026gt;memtupcount == 0 || state-\u0026gt;currentRun != state-\u0026gt;memtuples[0].tupindex: markrunend(state, state-\u0026gt;tp_tapenum[state-\u0026gt;destTape]) state-\u0026gt;currentRun++ if state-\u0026gt;memtupcount == 0: break selectnewtape(state) } case TSS_BOUNDED: if COMPARETUP(state, tuple, \u0026amp;state-\u0026gt;memtuples[0]) \u0026lt;= 0: free_sort_tuple(state, tuple) else: free_sort_tuple(state, \u0026amp;state-\u0026gt;memtuples[0]) tuplesort_heap_siftup(state, false) tuplesort_heap_insert(state, tuple, 0, false) case TSS_BUILDRUNS: if COMPARETUP(state, tuple, \u0026amp;state-\u0026gt;memtuples[0]) \u0026gt;= 0: tuplesort_heap_insert(state, tuple, state-\u0026gt;currentRun, true) else: tuplesort_heap_insert(state, tuple, state-\u0026gt;currentRun + 1, true) dumptuples(state, false) } /* 3 排序 */ void tuplesort_performsort(Tuplesortstate *state) switch state-\u0026gt;status: case TSS_INITIAL: /* 可在内存存放所有tup */ if state-\u0026gt;memtupcount \u0026gt; 1: if state-\u0026gt;onlyKey != NULL: qsort_ssup(state-\u0026gt;memtuples, state-\u0026gt;memtupcount, state-\u0026gt;onlyKey) else: qsort_tuple(state-\u0026gt;memtuples, state-\u0026gt;memtupcount, state-\u0026gt;comparetup, state) state-\u0026gt;current = 0; state-\u0026gt;status = TSS_SORTEDINMEM case TSS_BOUNDED: /* 使用堆排消除多余tup*/ sort_bounded_heap(state) state-\u0026gt;status = TSS_SORTEDINMEM case TSS_BUILDRUNS: dumptuples(state, true) /* 将内存中所有元组写到持久化存储tape */ mergeruns(state) /* 合并执行 */ 2.2 tup读写 writetup_heap(Tuplestorestate *state, void *tup) MinimalTuple tuple = (MinimalTuple) tup ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/2-5-execute/","summary":"\u003ch1 id=\"1-概述\"\u003e1 概述\u003c/h1\u003e\n\u003ch2 id=\"11-总接口\"\u003e1.1 总接口\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ePostmasterMain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eServerLoop\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(;;)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eselect\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 接收TCP连接\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eBackendStartup\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003efork_process\u003c/span\u003e \u003cspan class=\"c1\"\u003e# fork postgres进程，用于处理SQL\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"c1\"\u003e# postgres子进程执行：\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eBackendRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# postgres子进程\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eBackendRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ePostgresMain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(;;)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eReadCommand\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eexec_simple_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003epg_parse_query\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 语法解析\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003epg_analyze_and_rewrite\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 语义分析 查询重写\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003epg_plan_queries\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 计划生成\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eCreatePortal\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003ePortalDefineQuery\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003ePortalStart\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003ePortalRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003ePortalRunSelect\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eExecutorRun\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 计划执行\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003estandard_ExecutorRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003eExecutePlan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(;;)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                        \u003cspan class=\"n\"\u003eExecProcNode\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"n\"\u003eExecSeqScan\u003c/span\u003e \u003cspan class=\"c1\"\u003e# SELECT 计划执行\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"n\"\u003eSeqNext\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"n\"\u003eheap_beginscan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"n\"\u003eheap_getnext\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003ePortalRunMulti\u003c/span\u003e \u003cspan class=\"c1\"\u003e# DDL执行\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003ePortalRunUtility\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eProcessUtility\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003estandard_ProcessUtility\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eExecDropStmt\u003c/span\u003e \u003cspan class=\"c1\"\u003e# DROP TABLE\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eProcessUtilitySlow\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                        \u003cspan class=\"n\"\u003eDefineRelation\u003c/span\u003e \u003cspan class=\"c1\"\u003e# CREATE TABLE\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eProcessQuery\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eExecutorStart\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eExecutorRun\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 计划执行\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003estandard_ExecutorRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eExecutePlan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                        \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(;;)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"n\"\u003eExecProcNode\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"n\"\u003eExecModifyTable\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"n\"\u003eExecInsert\u003c/span\u003e \u003cspan class=\"c1\"\u003e# INSERT 计划执行\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                        \u003cspan class=\"n\"\u003eheap_insert\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"n\"\u003eExecUpdate\u003c/span\u003e \u003cspan class=\"c1\"\u003e# UPDATE 计划执行\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                        \u003cspan class=\"n\"\u003eheap_update\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"n\"\u003eExecDelete\u003c/span\u003e \u003cspan class=\"c1\"\u003e# DELETE 计划执行\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                        \u003cspan class=\"n\"\u003eheap_delete\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eExecutorFinish\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eExecutorEnd\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003ePortalDrop\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eexec_simple_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_plan_queries\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003epg_plan_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eplanner\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003estandard_planner\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003esubquery_planner\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003epull_up_subqueries\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003epreprocess_qual_conditions\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003egrouping_planner\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003equery_planner\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003emake_one_rel\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eset_base_rel_pathlists\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 查找所有Scan类型\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                        \u003cspan class=\"n\"\u003eset_rel_pathlist\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"n\"\u003eset_plain_rel_pathlist\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"n\"\u003ecreate_seqscan_path\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"n\"\u003ecreate_index_paths\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"n\"\u003eget_index_paths\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"n\"\u003egenerate_bitmap_or_paths\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"n\"\u003ecreate_tidscan_paths\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eget_cheapest_fractional_path\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003ecreate_plan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ecreate_plan_recurse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ecreate_scan_plan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"12-算子类型\"\u003e1.2 算子类型\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eTupleTableSlot\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"nf\"\u003eExecProcNode\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ePlanState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 控制算子 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecResult\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eResultState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecModifyTable\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eModifyTableState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecAppend\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eAppendState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecMergeAppend\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eMergeAppendState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecRecursiveUnion\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eRecursiveUnionState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 扫描算子 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecSeqScan\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eSeqScanState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecSampleScan\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eSampleScanState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecIndexScan\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eIndexScanState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecIndexOnlyScan\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eIndexOnlyScanState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecBitmapHeapScan\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eBitmapHeapScanState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecTidScan\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eTidScanState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecSubqueryScan\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eSubqueryScanState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecFunctionScan\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eFunctionScanState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecValuesScan\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eValuesScanState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecCteScan\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eCteScanState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecWorkTableScan\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eWorkTableScanState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecForeignScan\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eForeignScanState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecCustomScan\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eCustomScanState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 连接算子 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecNestLoop\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eNestLoopState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecMergeJoin\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eMergeJoinState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecHashJoin\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eHashJoinState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 物化算子 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecMaterial\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eMaterialState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecSort\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eSortState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecGroup\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eGroupState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecAgg\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eAggState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecWindowAgg\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eWindowAggState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecUnique\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eUniqueState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecHash\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eHashState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecSetOp\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eSetOpState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecLockRows\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eLockRowsState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eExecLimit\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003eLimitState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"2-算子\"\u003e2 算子\u003c/h1\u003e\n\u003ch2 id=\"21-execsort\"\u003e2.1 ExecSort\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 主要流程 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eTupleTableSlot\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"nf\"\u003eExecSort\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSortState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eTuplesortstate\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003etuplesortstate\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etuplesortstate\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"nl\"\u003esort_Done\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ePlanState\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eouterNode\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eouterPlanState\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003etuplesortstate\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e  \u003cspan class=\"nf\"\u003etuplesort_begin_heap\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nf\"\u003eExecGetResultType\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eouterNode\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003enumCols\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003esortColIdx\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003esortOperators\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(;;)\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 子节点扫描tup */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eslot\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eExecProcNode\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eouterNode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nf\"\u003etuplesort_puttupleslot\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etuplesortstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eslot\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003etuplesort_performsort\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etuplesortstate\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eslot\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ess\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eps\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eps_ResultTupleSlot\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003etuplesort_gettupleslot\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etuplesortstate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nf\"\u003eScanDirectionIsForward\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edir\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003eslot\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eslot\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 1 准备 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eTuplesortstate\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"nf\"\u003etuplesort_begin_heap\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTupleDesc\u003c/span\u003e \u003cspan class=\"n\"\u003etupDesc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003enkeys\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eAttrNumber\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eattNums\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eOid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003esortOperators\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eOid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003esortCollations\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003enullsFirstFlags\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eTuplesortstate\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ecomparetup\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ecomparetup_heap\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ecopytup\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ecopytup_heap\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ewritetup\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ewritetup_heap\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ereadtup\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ereadtup_heap\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003esortKeys\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003epalloc0\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003enkeys\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"k\"\u003esizeof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSortSupportData\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"n\"\u003ein\u003c/span\u003e \u003cspan class=\"nf\"\u003erange\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003enkeys\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eSortSupport\u003c/span\u003e \u003cspan class=\"n\"\u003esortKey\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003esortKeys\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003esortKey\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003essup_attno\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eattNums\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 2 扫描存储 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003etuplesort_puttupleslot\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTuplesortstate\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTupleTableSlot\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eslot\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eSortTuple\u003c/span\u003e \u003cspan class=\"n\"\u003estup\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eCOPYTUP\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003estup\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003eslot\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eputtuple_common\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003estup\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"nl\"\u003estatus\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003eTSS_INITIAL\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtupcount\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"nl\"\u003ememtupsize\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003egrow_memtuples\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtuples\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtupcount\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003etuple\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"nl\"\u003ebounded\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003emake_bounded_heap\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nf\"\u003einittapes\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003emaxTapes\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etuplesort_merge_order\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eallowedMem\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003etapeSpace\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eint64\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003emaxTapes\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eTAPE_BUFFER_OVERHEAD\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"cm\"\u003e/* 创建临时文件 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003ePrepareTempTablespaces\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etapeset\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eLogicalTapeSetCreate\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emaxTapes\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003emergenext\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003epalloc0\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emaxTapes\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"k\"\u003esizeof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003emergeavailslots\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003epalloc0\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emaxTapes\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"k\"\u003esizeof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"p\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003entuples\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtupcount\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtupcount\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003entuples\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eSortTuple\u003c/span\u003e \u003cspan class=\"n\"\u003estup\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtuples\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ej\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"nf\"\u003etuplesort_heap_insert\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003estup\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"p\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003estatus\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eTSS_BUILDRUNS\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nf\"\u003edumptuples\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtupcount\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"nl\"\u003ememtupsize\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"cm\"\u003e/* = writetup_heap */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"nf\"\u003eWRITETUP\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etp_tapenum\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003edestTape\u003c/span\u003e\u003cspan class=\"p\"\u003e],\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtuples\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e])\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"nf\"\u003etuplesort_heap_siftup\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtupcount\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e \u003cspan class=\"o\"\u003e||\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ecurrentRun\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtuples\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e].\u003c/span\u003e\u003cspan class=\"nl\"\u003etupindex\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"nf\"\u003emarkrunend\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003etp_tapenum\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003edestTape\u003c/span\u003e\u003cspan class=\"p\"\u003e])\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ecurrentRun\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtupcount\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"k\"\u003ebreak\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"nf\"\u003eselectnewtape\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003eTSS_BOUNDED\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"nf\"\u003eCOMPARETUP\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003etuple\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtuples\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e])\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003efree_sort_tuple\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003etuple\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003efree_sort_tuple\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtuples\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e])\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003etuplesort_heap_siftup\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003etuplesort_heap_insert\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003etuple\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003eTSS_BUILDRUNS\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"nf\"\u003eCOMPARETUP\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003etuple\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtuples\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e])\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003etuplesort_heap_insert\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003etuple\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ecurrentRun\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003etuplesort_heap_insert\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003etuple\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ecurrentRun\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nf\"\u003edumptuples\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 3 排序 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003etuplesort_performsort\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTuplesortstate\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"nl\"\u003estatus\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003eTSS_INITIAL\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e  \u003cspan class=\"cm\"\u003e/* 可在内存存放所有tup */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtupcount\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eonlyKey\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003eqsort_ssup\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtuples\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtupcount\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eonlyKey\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003eqsort_tuple\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtuples\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ememtupcount\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ecomparetup\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ecurrent\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003estatus\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eTSS_SORTEDINMEM\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003eTSS_BOUNDED\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 使用堆排消除多余tup*/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nf\"\u003esort_bounded_heap\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003estatus\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eTSS_SORTEDINMEM\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003eTSS_BUILDRUNS\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nf\"\u003edumptuples\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 将内存中所有元组写到持久化存储tape */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nf\"\u003emergeruns\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 合并执行 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"22-tup读写\"\u003e2.2 tup读写\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003ewritetup_heap\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTuplestorestate\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003etup\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eMinimalTuple\u003c/span\u003e \u003cspan class=\"n\"\u003etuple\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eMinimalTuple\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003etup\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"PostgreSQL 2-5 Execute"},{"content":"1 常用系统表与视图 1.1 系统表 1.2 视图 堆内存（区分线程）\nSELECT * FROM gs_thread_memory_context ORDER BY totalsize DESC; 堆内存（不区分线程）\nSELECT * FROM gs_shared_memory_detail ORDER BY totalsize DESC; 会话\nSELECT * FROM pg_stat_activity; 1 新增系统表 获取空闲的oid\ncd src/include/catalog/ chmod +x unused_oids ./unused_oids 2 读取系统表 创建表时涉及的系统表操作：\nheap_create_with_catalog() Relation pg_class_desc = heap_open(RelationRelationId) Oid old_type_oid = GetSysCacheOid2(TYPENAMENSP) Oid relid = GetNewRelFileNode(pg_class_desc) Relation new_rel_desc = heap_create(relname) ObjectAddress new_type_addr = AddNewRelationType(relname) AddNewRelationTuple(pg_class_desc, new_rel_desc) AddNewAttributeTuples(relid, new_rel_desc-\u0026gt;rd_att) ObjectAddress myself, referenced; myself.objectId = relid referenced.objectId = relnamespace recordDependencyOn(\u0026amp;myself, \u0026amp;referenced, DEPENDENCY_NORMAL) recordDependencyOnOwner(RelationRelationId, relid) recordDependencyOnNewAcl(RelationRelationId, relid) recordDependencyOnCurrentExtension(\u0026amp;myself) StoreConstraints(new_rel_desc, cooked_constraints) 打开系统表\nRelation heap_open(Oid relationId, LOCKMODE lockmode) Relation r = relation_open(relationId, lockmode) LockRelationOid(relationId, lockmode) Relation r = RelationIdGetRelation(relationId) Relation rd RelationIdCacheLookup(relationId, rd) RelIdCacheEnt hentry = hash_search(RelationIdCache, relationId) rd = hentry-\u0026gt;reldesc RelationIncrementReferenceCount(rd) /* find cache, return */ if !rd-\u0026gt;rd_isvalid: if (rd-\u0026gt;rd_rel-\u0026gt;relkind == RELKIND_INDEX) RelationReloadIndexInfo(rd); else: RelationClearRelation(rd) return rd; /* no cache, so build */ rd = RelationBuildDesc(relationId) HeapTuple pg_class_tuple = ScanPgRelation(targetRelId) relid = HeapTupleGetOid(pg_class_tuple) Form_pg_class relp = (Form_pg_class) GETSTRUCT(pg_class_tuple) relation = AllocateRelationDesc(relp) RelationGetRelid(relation) = relid RelationBuildTupleDesc(relation) if ..: RelationBuildRuleLock(relation) if ..: RelationBuildTriggers(relation) if ..: RelationBuildRowSecurity(relation) RelationParseRelOptions(relation, pg_class_tuple) RelationInitLockInfo(relation) RelationInitPhysicalAddr(relation) heap_freetuple(pg_class_tuple) RelationIncrementReferenceCount(rd) pgstat_initstats(r) typedef struct { Oid reloid; Relation reldesc; } RelIdCacheEnt; 扫描系统表\nScanPgRelation() ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/2-6-catalog/","summary":"\u003ch1 id=\"1-常用系统表与视图\"\u003e1 常用系统表与视图\u003c/h1\u003e\n\u003ch2 id=\"11-系统表\"\u003e1.1 系统表\u003c/h2\u003e\n\u003ch2 id=\"12-视图\"\u003e1.2 视图\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e堆内存（区分线程）\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egs_thread_memory_context\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etotalsize\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDESC\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e堆内存（不区分线程）\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egs_shared_memory_detail\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etotalsize\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDESC\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e会话\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_stat_activity\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"1-新增系统表\"\u003e1 新增系统表\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e获取空闲的oid\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e src/include/catalog/\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod +x unused_oids\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e./unused_oids\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"2-读取系统表\"\u003e2 读取系统表\u003c/h1\u003e\n\u003cp\u003e创建表时涉及的系统表操作：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eheap_create_with_catalog\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003epg_class_desc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eheap_open\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelationRelationId\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eOid\u003c/span\u003e \u003cspan class=\"n\"\u003eold_type_oid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eGetSysCacheOid2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTYPENAMENSP\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eOid\u003c/span\u003e \u003cspan class=\"n\"\u003erelid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eGetNewRelFileNode\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epg_class_desc\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003enew_rel_desc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eheap_create\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelname\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eObjectAddress\u003c/span\u003e \u003cspan class=\"n\"\u003enew_type_addr\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eAddNewRelationType\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelname\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eAddNewRelationTuple\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epg_class_desc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003enew_rel_desc\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eAddNewAttributeTuples\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003enew_rel_desc\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003erd_att\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eObjectAddress\u003c/span\u003e \u003cspan class=\"n\"\u003emyself\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ereferenced\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003emyself\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eobjectId\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erelid\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ereferenced\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eobjectId\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erelnamespace\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003erecordDependencyOn\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003emyself\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ereferenced\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eDEPENDENCY_NORMAL\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003erecordDependencyOnOwner\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelationRelationId\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003erelid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003erecordDependencyOnNewAcl\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelationRelationId\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003erelid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003erecordDependencyOnCurrentExtension\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003emyself\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eStoreConstraints\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003enew_rel_desc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ecooked_constraints\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e打开系统表\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"nf\"\u003eheap_open\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eOid\u003c/span\u003e \u003cspan class=\"n\"\u003erelationId\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eLOCKMODE\u003c/span\u003e \u003cspan class=\"n\"\u003elockmode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003er\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003erelation_open\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelationId\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003elockmode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003eLockRelationOid\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelationId\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003elockmode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003er\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eRelationIdGetRelation\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelationId\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003erd\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nf\"\u003eRelationIdCacheLookup\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelationId\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003erd\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eRelIdCacheEnt\u003c/span\u003e \u003cspan class=\"n\"\u003ehentry\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003ehash_search\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelationIdCache\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003erelationId\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003erd\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ehentry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ereldesc\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nf\"\u003eRelationIncrementReferenceCount\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erd\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"cm\"\u003e/* find cache, return */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"n\"\u003erd\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"nl\"\u003erd_isvalid\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erd\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003erd_rel\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003erelkind\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"n\"\u003eRELKIND_INDEX\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003eRelationReloadIndexInfo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erd\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003eRelationClearRelation\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erd\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003erd\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"cm\"\u003e/* no cache, so build */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003erd\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eRelationBuildDesc\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelationId\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eHeapTuple\u003c/span\u003e \u003cspan class=\"n\"\u003epg_class_tuple\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eScanPgRelation\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etargetRelId\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003erelid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eHeapTupleGetOid\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epg_class_tuple\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eForm_pg_class\u003c/span\u003e \u003cspan class=\"n\"\u003erelp\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eForm_pg_class\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"nf\"\u003eGETSTRUCT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epg_class_tuple\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003erelation\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eAllocateRelationDesc\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelp\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nf\"\u003eRelationGetRelid\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelation\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erelid\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nf\"\u003eRelationBuildTupleDesc\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelation\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e..\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003eRelationBuildRuleLock\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelation\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e..\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003eRelationBuildTriggers\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelation\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e..\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003eRelationBuildRowSecurity\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelation\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nf\"\u003eRelationParseRelOptions\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelation\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003epg_class_tuple\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nf\"\u003eRelationInitLockInfo\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelation\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nf\"\u003eRelationInitPhysicalAddr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelation\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nf\"\u003eheap_freetuple\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epg_class_tuple\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nf\"\u003eRelationIncrementReferenceCount\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erd\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003epgstat_initstats\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003etypedef\u003c/span\u003e \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003eOid\u003c/span\u003e \u003cspan class=\"n\"\u003ereloid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003ereldesc\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"n\"\u003eRelIdCacheEnt\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e扫描系统表\u003c/p\u003e","title":"PostgreSQL 2-6 Catalog"},{"content":"SQL.别名 摘要\n本文以实际使用为例，介绍SQL语法中别名的使用约束\n目录\nSQL.别名 1 介绍 2 示例 3 复杂场景 1 介绍 什么是别名：\n别名语法:\n表名 | 列名 | 表名.列名 [AS] 别名\n2 示例 0 建表\nCREATE TABLE t1 ( c1 INT, c2 INT, c3 INT ); INSERT INTO t1 VALUES (1, 1, 1), (2, 2, 2); 1 [列] 别名：\nSELECT c1 AS col1 FROM t1; 2 [表] 别名：\nSELECT c1 FROM t1 AS tbl1; 3 [表.列] 别名：\nSELECT t1.c1 tbl1_col1 FROM t1; 4 [表别名.列] 别名：\nSELECT tbl1.c1 tbl1_col1 FROM t1 tbl1; -- error SELECT t1.c1 tbl1_col1 FROM t1 tbl1; 5 [表别名.列别名]\n-- error SELECT c1 col1, tbl1.col1 FROM t1 tbl1; -- error SELECT tbl1.c1 tbl1_col1, tbl1.tbl1_col1 FROM t1 tbl1; 6 [别名] 别名\n-- error SELECT tbl1.c1 tbl1_col1, tbl1_col1 copy_col1 FROM t1 tbl1; 7 总结\n别名处理顺序：先处理FROM子句，再处理TARGET子句 别名嵌套：可在别名上取别名 3 复杂场景 0 建表\nDROP TABLE t1; CREATE TABLE t1 ( c1 INT, c2 INT, c3 INT ); CREATE TABLE t2 ( c1 INT, c2 INT, c4 INT ); INSERT INTO t1 VALUES (1, 1, 1), (2, 2, 2); INSERT INTO t2 VALUES (2, 2, 2), (3, 3, 3); 1 多表JOIN\nSELECT * FROM t1 JOIN t2 ON c3 = c4 -- succeed -- ON c1 = c1; -- error -- ON c1 = c2; -- error -- ON c1 = c4; -- error ; SELECT -- c1 -- error c3, -- t1.c1 -- error tbl1.c1, t2.c1, tbl1.c1 tbl1_c1, t2.c1 tbl2_c1, t2.c1 FROM t1 tbl1 JOIN t2 -- ON t1.c1 = t2.c1 -- error ON tbl1.c1 = t2.c1 ; 2 多表JOIN，ORDER BY\nSELECT c3, c4 col4, tbl1.c1, t2.c1, tbl1.c1 tbl1_c1, t2.c1 tbl2_c1, t2.c1 FROM t1 tbl1 JOIN t2 ON tbl1.c1 = t2.c1 ORDER BY c3, col4, tbl1.c1, t2.c1, tbl1_c1, tbl2_c1, t2.c1 -- c1 -- error -- t1.c1 -- error -- t2.col4 -- error -- tbl1.col4 -- error ; 3 多表JOIN，GROUP BY\nSELECT tbl1.c1 tbl1_c1 FROM t1 tbl1 JOIN t2 ON tbl1.c1 = t2.c1 GROUP BY tbl1.c1 -- tbl1_c1 --succeed ORDER BY tbl1.c1, tbl1_c1 ; SELECT tbl1.c2 tbl1_c2, tbl1.c2 FROM t1 tbl1 JOIN t2 ON tbl1.c1 = t2.c1 GROUP BY -- tbl1.c2 -- succeed tbl1_c2 ORDER BY tbl1.c2, tbl1_c2 ; 4 语法解析\n解析结果：\n方式二\n5 总结\n表别名强约束，列别名弱约束 多表查询时，列名无冲突时，可直接使用列名 别名处理顺序：FROM (alias) -\u0026gt; TARGET -\u0026gt; JOIN -\u0026gt; GROUP BY -\u0026gt; ORDER BY ORDER BY中别名约束，与TARGET中约束一致 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/2-7-alias/","summary":"\u003ch1 id=\"sql别名\"\u003eSQL.别名\u003c/h1\u003e\n\u003cp\u003e\u003cstrong\u003e摘要\u003c/strong\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e本文以实际使用为例，介绍SQL语法中别名的使用约束\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003e\u003cstrong\u003e目录\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#SQL-%E5%88%AB%E5%90%8D\"\u003eSQL.别名\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-%E4%BB%8B%E7%BB%8D\"\u003e1 介绍\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-%E7%A4%BA%E4%BE%8B\"\u003e2 示例\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-%E5%A4%8D%E6%9D%82%E5%9C%BA%E6%99%AF\"\u003e3 复杂场景\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"1-介绍\"\u003e1 介绍\u003c/h2\u003e\n\u003cp\u003e什么是别名：\u003c/p\u003e\n\u003cp\u003e别名语法:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e表名 | 列名 | 表名.列名 [AS] 别名\u003c/p\u003e\u003c/blockquote\u003e\n\u003ch2 id=\"2-示例\"\u003e2 示例\u003c/h2\u003e\n\u003cp\u003e0 建表\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-SQL\" data-lang=\"SQL\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003ec3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e1 [列] 别名：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-SQL\" data-lang=\"SQL\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecol1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e2 [表] 别名：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-SQL\" data-lang=\"SQL\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etbl1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e3 [表.列] 别名：\u003c/p\u003e","title":"PostgreSQL 2-6 Alias"},{"content":"1 介绍JOIN 分类 INNER JOIN LEFT JOIN RIGHT JOIN FULL JOIN SELF JOIN CROSS JOIN 2 使用JOIN CREATE TABLE t1 (a1 INT, b1 TEXT); INSERT INTO t1 VALUES (1, \u0026#39;u1\u0026#39;), (2, \u0026#39;u2\u0026#39;), (3, \u0026#39;u3\u0026#39;); CREATE TABLE t2 (b2 TEXT, c2 TEXT); INSERT INTO t2 VALUES (\u0026#39;u1\u0026#39;, \u0026#39;u1-1\u0026#39;), (\u0026#39;u1\u0026#39;, \u0026#39;u1-2\u0026#39;), (\u0026#39;u2\u0026#39;, \u0026#39;u2-1\u0026#39;), (\u0026#39;u4\u0026#39;, \u0026#39;u4-1\u0026#39;); -- INNER JOIN SELECT a1, b1, b2, c2 FROM t1 INNER JOIN t2 ON b1 = b2 ORDER BY a1, b1, c2; a1 | b1 | b2 | c2 ----+----+----+------ 1 | u1 | u1 | u1-1 1 | u1 | u1 | u1-2 2 | u2 | u2 | u2-1 -- LEFT JOIN SELECT a1, b1, b2, c2 FROM t1 LEFT JOIN t2 ON b1 = b2 ORDER BY a1, b1, c2; a1 | b1 | b2 | c2 ----+----+----+------ 1 | u1 | u1 | u1-1 1 | u1 | u1 | u1-2 2 | u2 | u2 | u2-1 3 | u3 | | -- RIGHT JOIN SELECT a1, b1, b2, c2 FROM t1 RIGHT JOIN t2 ON b1 = b2 ORDER BY a1, b1, c2; a1 | b1 | b2 | c2 ----+----+----+------ 1 | u1 | u1 | u1-1 1 | u1 | u1 | u1-2 2 | u2 | u2 | u2-1 | | u4 | u4-1 -- FULL JOIN SELECT a1, b1, b2, c2 FROM t1 FULL JOIN t2 ON b1 = b2 ORDER BY a1, b1, c2; a1 | b1 | b2 | c2 ----+----+----+------ 1 | u1 | u1 | u1-1 1 | u1 | u1 | u1-2 2 | u2 | u2 | u2-1 3 | u3 | | | | u4 | u4-1 -- SELF JOIN SELECT a1, b1, b2, c2 FROM t1 SELF JOIN t2 ON b1 = b2 ORDER BY a1, b1, c2; -- CROSS JOIN SELECT a1, b1, b2, c2 FROM t1 CROSS JOIN t2 -- can\u0026#39;t use \u0026#39;ON\u0026#39; ORDER BY a1, b1, c2; a1 | b1 | b2 | c2 ----+----+----+------ 1 | u1 | u1 | u1-1 1 | u1 | u1 | u1-2 1 | u1 | u2 | u2-1 1 | u1 | u4 | u4-1 2 | u2 | u1 | u1-1 2 | u2 | u1 | u1-2 2 | u2 | u2 | u2-1 2 | u2 | u4 | u4-1 3 | u3 | u1 | u1-1 3 | u3 | u1 | u1-2 3 | u3 | u2 | u2-1 3 | u3 | u4 | u4-1 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/2-8-join/","summary":"\u003ch1 id=\"1-介绍join\"\u003e1 介绍JOIN\u003c/h1\u003e\n\u003ch2 id=\"分类\"\u003e分类\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eINNER JOIN\u003c/li\u003e\n\u003cli\u003eLEFT JOIN\u003c/li\u003e\n\u003cli\u003eRIGHT JOIN\u003c/li\u003e\n\u003cli\u003eFULL JOIN\u003c/li\u003e\n\u003cli\u003eSELF JOIN\u003c/li\u003e\n\u003cli\u003eCROSS JOIN\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-使用join\"\u003e2 使用JOIN\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ea1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u3\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eb2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1-1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1-2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2-1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u4\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u4-1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- INNER JOIN\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINNER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eJOIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e----+----+----+------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- LEFT JOIN\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLEFT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eJOIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e----+----+----+------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- RIGHT JOIN\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eRIGHT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eJOIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e----+----+----+------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu4\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu4\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- FULL JOIN\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFULL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eJOIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e----+----+----+------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu4\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu4\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- SELF JOIN\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eJOIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb2\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-fallback\" data-lang=\"fallback\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e-- CROSS JOIN\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eSELECT a1, b1, b2, c2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eFROM t1 CROSS JOIN t2 -- can\u0026#39;t use \u0026#39;ON\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eORDER BY a1, b1, c2;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e a1 | b1 | b2 |  c2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e----+----+----+------\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  1 | u1 | u1 | u1-1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  1 | u1 | u1 | u1-2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  1 | u1 | u2 | u2-1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  1 | u1 | u4 | u4-1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  2 | u2 | u1 | u1-1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  2 | u2 | u1 | u1-2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  2 | u2 | u2 | u2-1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  2 | u2 | u4 | u4-1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  3 | u3 | u1 | u1-1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  3 | u3 | u1 | u1-2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  3 | u3 | u2 | u2-1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  3 | u3 | u4 | u4-1\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"PostgreSQL 2-8 join"},{"content":"@vb GaussDBThteadMain BackendRun PostgresMain PostgresInitializer::InitBackendWorker ::InitSession ::InitSysCache # 1 初始化缓存 RelationCacheInitializePhase2 if lsc: LocalTabDefCache::InitPhase2 Formrdesc(\u0026#34;vb_profiles“\u0026#34;) else: formrdesc(\u0026#34;vb_profiles“) InitCatalogCache ::CheckAuthentication PerformAuthentication ClientAuthentication ::InitUser InitializeSessionUserId ::SetDatabase ::SetDatabaseByName ::InitSessionDatabase ::LockDataBase ::LoadSysCache # 2 初始化缓存 RelationCacheInitializePhase3 if lsc: LocalTabDefCache::InitPhase3 LoadCriticalIndex else: load_critical_index(ProfileRelationId) InitDatabase FinishInit InitCatalogCache RelationCacheInitialize ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/2-9-cache/","summary":"\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nd\"\u003e@vb\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eGaussDBThteadMain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eBackendRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ePostgresMain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003ePostgresInitializer\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eInitBackendWorker\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eInitSession\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eInitSysCache\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 1 初始化缓存\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eRelationCacheInitializePhase2\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003elsc\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eLocalTabDefCache\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eInitPhase2\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                        \u003cspan class=\"n\"\u003eFormrdesc\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;vb_profiles“\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eformrdesc\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;vb_profiles“)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eInitCatalogCache\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eCheckAuthentication\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003ePerformAuthentication\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eClientAuthentication\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eInitUser\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eInitializeSessionUserId\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eSetDatabase\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eSetDatabaseByName\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eInitSessionDatabase\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eLockDataBase\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eLoadSysCache\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 2 初始化缓存\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eRelationCacheInitializePhase3\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003elsc\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eLocalTabDefCache\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eInitPhase3\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                        \u003cspan class=\"n\"\u003eLoadCriticalIndex\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eload_critical_index\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eProfileRelationId\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eInitDatabase\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eFinishInit\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eInitCatalogCache\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eRelationCacheInitialize\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"PostgreSQL 2-9 cache"},{"content":"exec_simple_query(\u0026#39;SELECT * FROM t1 WHERE c1 \u0026gt; 10\u0026#39;) pg_parse_query pg_analyze_and_rewrite parse_analyze transformStmt transformSelectStmt transformWhereClause transformExpr transformAExprOp oper oper_search # 查找操作符所有相关函数 enforce_generic_type_consistency # 根据已知数据类型，找到最符合的函数，自动调用隐式转换 make_op pg_plan_queries PortalRun ExecInterpExpr ExecEvalExprSwitchContext -- ciphera_gt / int4gt ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/2-10-func/","summary":"\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eexec_simple_query\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;SELECT * FROM t1 WHERE c1 \u0026gt; 10\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_parse_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_analyze_and_rewrite\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eparse_analyze\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003etransformStmt\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003etransformSelectStmt\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003etransformWhereClause\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003etransformExpr\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003etransformAExprOp\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003eoper\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eoper_search\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 查找操作符所有相关函数\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eenforce_generic_type_consistency\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 根据已知数据类型，找到最符合的函数，自动调用隐式转换\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003emake_op\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_plan_queries\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ePortalRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eExecInterpExpr\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eExecEvalExprSwitchContext\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"o\"\u003e--\u003c/span\u003e \u003cspan class=\"n\"\u003eciphera_gt\u003c/span\u003e \u003cspan class=\"o\"\u003e/\u003c/span\u003e \u003cspan class=\"n\"\u003eint4gt\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"PostgreSQL 2-10 function"},{"content":"1 需求背景 客户使用vb什么版本？ 2215 客户的要求： 2 需求分析 2.1 适配点 在使用vastbase的多个阶段，都可能涉及pg_hba.conf\n编译安装 初始化 升级 配置 gs_guc修改pg_hba 手动编辑pg_hba 启动 运维 pg_backup pg_rewind vb_ctl restart 2.2 代码流程 编译\n初始化\nmain # initdb.cpp canonicalize_path # PGDATA find_other_exec # 在gs_initdb bin目录下，查找gaussdb bin # 在$GAUSSHOME/share/postgrsql目录下，检查以下文件是否存在 check_input(\u0026#39;postgres.bki, postgres.description, pg_hba.conf.sample, postgresql.conf.sample, ..., system_views.sql, ...\u0026#39;) check_locale_encoding init_log gs_getenv_r(\u0026#39;GAUSSLOG\u0026#39;) canonicalize_path(\u0026#39;$PGDATA/PG_VERSION\u0026#39;) fprintf(PG_MAJORVERSION = \u0026#39;9.2\u0026#39;) setup_config readfile(\u0026#34;postgresql.conf.sample\u0026#34;) readfile(\u0026#34;pg_hba.sample\u0026#34;) writefile(\u0026#34;pg_hba.conf\u0026#34;) bootstrap_template1 write_version_file setup_auth get_set_pwd setup_depend load_plpgsql setup_sysviews 升级\n配置\n启动\npg_ctl 运行\nPostmasterMain # postmaster 线程 InitializeGUCOptions getopt_r load_hba # 加载hba ServerLoop ConnCreate StreamConnection BackendStartup PostgresMain # postgres 线程 InitBackendWorker InitSession CheckAuthentication PerformAuthentication port-\u0026gt;protocol_config-\u0026gt;fn_authenticate ClientAuthentication hba_getauthmethod check_hba g_instance.libpq_cxt_comm_parsed_hba_lines # 读取缓存的hba if init_user: get_default_auth_method else: check_hostname sendAuthRequest recv_and_check_password_packet # 接收客户端的password crypt_verify for (;;) ReadCommand exec_simple_query(\u0026#39;SQL\u0026#39;) SIGHUB_handler load_hba 运维\npg_backup pg_rewind 规避方案 password_encryption_type 0: md5 1: sha256+md5 2: sha256 3: sm3 4: scram-sha256 gs_guc set -D $GAUSSHOME/data -c \u0026#34;listen_addresses=\u0026#39;*\u0026#39;\u0026#34; gs_guc reload -D $GAUSSHOME/data -c \u0026#34;password_encryption_type=1\u0026#34; vsql -d postgres -U shenkun -W \u0026#39;vg@12345\u0026#39; -c \u0026#34;show password_encryption_type\u0026#34; vsql -d postgres -U shenkun -W \u0026#39;vg@12345\u0026#39; -c \u0026#34;DROP USER u1\u0026#34; vsql -d postgres -U shenkun -W \u0026#39;vg@12345\u0026#39; -c \u0026#34;CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39; \u0026#34; vsql -d postgres -U shenkun -W \u0026#39;vg@12345\u0026#39; -c \u0026#34;SELECT rolname, rolpassword FROM pg_authid WHERE rolname = \u0026#39;u1\u0026#39; \u0026#34; gs_guc reload -D $GAUSSHOME/data -h \u0026#34;host all all 0.0.0.0/0 sha256\u0026#34; tail $GAUSSHOME/data/pg_hba.conf vsql -h 172.16.100.134 -d postgres -U u1 -W \u0026#39;u1.password\u0026#39; -c \u0026#34;SELECT 1\u0026#34; ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/3-requirement-pg-hba-encrypt/","summary":"\u003ch1 id=\"1-需求背景\"\u003e1 需求背景\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e客户使用vb什么版本？ 2215\u003c/li\u003e\n\u003cli\u003e客户的要求：\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"2-需求分析\"\u003e2 需求分析\u003c/h1\u003e\n\u003ch2 id=\"21-适配点\"\u003e2.1 适配点\u003c/h2\u003e\n\u003cp\u003e在使用vastbase的多个阶段，都可能涉及pg_hba.conf\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e编译安装\u003c/li\u003e\n\u003cli\u003e初始化\u003c/li\u003e\n\u003cli\u003e升级\u003c/li\u003e\n\u003cli\u003e配置\n\u003cul\u003e\n\u003cli\u003egs_guc修改pg_hba\u003c/li\u003e\n\u003cli\u003e手动编辑pg_hba\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e启动\u003c/li\u003e\n\u003cli\u003e运维\n\u003cul\u003e\n\u003cli\u003epg_backup\u003c/li\u003e\n\u003cli\u003epg_rewind\u003c/li\u003e\n\u003cli\u003evb_ctl restart\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"22-代码流程\"\u003e2.2 代码流程\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e编译\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e初始化\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e \u003cspan class=\"c1\"\u003e# initdb.cpp\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ecanonicalize_path\u003c/span\u003e \u003cspan class=\"c1\"\u003e# PGDATA\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003efind_other_exec\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 在gs_initdb bin目录下，查找gaussdb bin\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 在$GAUSSHOME/share/postgrsql目录下，检查以下文件是否存在\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003echeck_input\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;postgres.bki, postgres.description, pg_hba.conf.sample, postgresql.conf.sample, ..., system_views.sql, ...\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003echeck_locale_encoding\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003einit_log\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003egs_getenv_r\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;GAUSSLOG\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ecanonicalize_path\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;$PGDATA/PG_VERSION\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003efprintf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ePG_MAJORVERSION\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;9.2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003esetup_config\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ereadfile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;postgresql.conf.sample\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ereadfile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;pg_hba.sample\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ewritefile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;pg_hba.conf\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ebootstrap_template1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ewrite_version_file\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003esetup_auth\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eget_set_pwd\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003esetup_depend\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eload_plpgsql\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003esetup_sysviews\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e升级\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e配置\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e启动\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003epg_ctl\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e运行\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ePostmasterMain\u003c/span\u003e \u003cspan class=\"c1\"\u003e# postmaster 线程\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eInitializeGUCOptions\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003egetopt_r\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eload_hba\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 加载hba\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eServerLoop\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eConnCreate\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eStreamConnection\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eBackendStartup\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003ePostgresMain\u003c/span\u003e \u003cspan class=\"c1\"\u003e# postgres 线程\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eInitBackendWorker\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eInitSession\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eCheckAuthentication\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003ePerformAuthentication\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003eport\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eprotocol_config\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003efn_authenticate\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eClientAuthentication\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                        \u003cspan class=\"n\"\u003ehba_getauthmethod\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"n\"\u003echeck_hba\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"n\"\u003eg_instance\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elibpq_cxt_comm_parsed_hba_lines\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 读取缓存的hba\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003einit_user\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"n\"\u003eget_default_auth_method\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"k\"\u003eelse\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"n\"\u003echeck_hostname\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                        \u003cspan class=\"n\"\u003esendAuthRequest\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                        \u003cspan class=\"n\"\u003erecv_and_check_password_packet\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 接收客户端的password\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"n\"\u003ecrypt_verify\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(;;)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eReadCommand\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eexec_simple_query\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;SQL\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eSIGHUB_handler\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eload_hba\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e运维\u003c/p\u003e","title":"海量 3 需求 pg_hba.conf加密"},{"content":"| -| -| -| -| -| -| -|\n| 1 | FAILED_LOGIN_ATTEMPTS | [1, max] unlimited | failed_login_attempts | [1,1000] | 认证类 | 登录数据库时，如果密码错误次数超过\u0026lt;本参数\u0026gt;，则账号会被锁定，短期内无法再登录 |\n| 2 | PASSWORD_LOCK_TIME | [1, max] unlimited | password_lock_time | [1,525600]min | 认证类 | 如果因密码错误次数过多，导致账号被锁，将锁定\u0026lt;本参数\u0026gt;的时间 |\n| 3 | PASSWORD_LIFE_TIME | [1, max] unlimited | password_effect_time | [30,36500]day | 认证类 | 设置或更新用户密码时，超过\u0026lt;本参数\u0026gt;的时间，密码会过期（oracle与vastase表现不同） |\n| 4 | PASSWORD_GRACE_TIME | - | - | - | 认证类 | 如果密码过期，在\u0026lt;本参数\u0026gt;的时间内，密码仍可使用 |\n| 5 | PASSWORD_REUSE_TIME | [1, max] unlimited | password_reuse_time | [30, 90]day | 认证类 | 用户设置密码时，如果密码在过去的\u0026lt;本参数\u0026gt;的时间内别用过，则密码不能复用，opengauss [0,3650] |\n| 6 | PASSWORD_REUSE_MAX | - | password_reuse_max | [1,100] | 认证类 | 用户设置密码时，如果密码已被重复使用过\u0026lt;本参数\u0026gt;的次数，则密码不能复用 |\n| 7 | INACTIVE_ACCONT_TIME | - | - | - | 认证类 | 如果一个账号在\u0026lt;本参数\u0026gt;的时间内，未登录过，则锁定账号 |\n| 8 | PASSWORD_VERIFY_FUNCTION | - | - | - | 认证类 | 用户设置密码时，调用\u0026lt;本参数\u0026gt;指定的函数，检查密码是否符合要求 |\n| 9 | PASSWORD_ROLLOVER_TIME | - | - | - | 认证类 | 新旧密码滚动更新天数 |\n| 10 | SESSIONS_PER_USER | - | - | - | 资源类 | 1个用户可建立的最大连接数 |\n| 11 | CPU_PER_SESSION | - | - | - | 资源类 | 1个连接可使用CPU时间数 |\n| 12 | CPU_PER_CALL | - | - | - | 资源类 | 1个调用（比如1个SQL）可使用CPU时间数 |\n| 13 | CONNECT_TIME | - | - | - | 资源类 | 1个连接可持续的时间 |\n| 14 | IDLE_TIME | [1, max] unlimited | session_timeout | [0,86400] | 资源类 | 1个连接空闲时间限制 |\n| 15 | LOGICAL_READS_PER_CALL | - | - | - | 资源类 | 1次调用（比如1个SQL）允许读写的page数量 |\n| 16 | LOGICAL_READS_PER_SESSION | - | - | - | 资源类 | 1个连接允许读取的page数量 |\n| 17 | PRIVATE_SGA | - | - | - | 资源类 | 1个连接可使用的共享内存空间大小 |\n| 18 | CONPOSITE_LIMIT | - | - | - | 资源类 | 1个连接可可使用的总资源：按cpu时间、连接时间、page读写数等加权求和 |\n一、友商分析：\noracle资源管理功能profile中，有9个用户级参数，需时间8个参数，我按自己理解，简单划分：\nCPU：1个连接可使用CPU时间，1个SQL可使用CPU时间 内存：1个连接使用内存大小 网络：1个用户最大连接数，1个连接可持续时间，1个连接空闲时间限制 磁盘：1个连接可读写page数，1个SQL可读写page数 综合：按cpu时间、连接时间、page读写数等加权求和\nmysql资源管理功能中，我按自己理解，简单划分： resource group：可使用CPU核白名单，线程优先级 create user .. resource：1小时可执行SQL数，1小时连接数，用户最大连接数 二、实现方案（仅对标oracle）：\nCPU：有方案 方案一（不可用）：基于系统调用。setrlimit函数，可以设置CPU最长运行时间，但是对整个进程生效。Oracle是多进程，Vb是多线程。 方案二：基于定时器+信号，理论上可行。设置定时器，定时触发信号 内存：有方案。这个简单 网络：有方案。定时器+信号，和控制CPU原理一样 磁盘：有方案。在ShareBuffer层限制 三、工作量：\n学习（1周）：对内核thread, resource这些模块，不太熟 开发（2周）：线程池、非线程池等都需要适配 自测（1周）：不能单纯使用SQL，测试麻烦一点点 https://mysql.net.cn/doc/refman/8.0/en/resource-groups.html#google_vignette\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/3-requirement-oracle-resource/","summary":"\u003cp\u003e| -| -| -| -| -| -| -|\u003cbr\u003e\n| 1 | FAILED_LOGIN_ATTEMPTS | [1, max] unlimited | failed_login_attempts | [1,1000] | 认证类 | 登录数据库时，如果密码错误次数超过\u0026lt;本参数\u0026gt;，则账号会被锁定，短期内无法再登录 |\u003cbr\u003e\n| 2 | PASSWORD_LOCK_TIME | [1, max] unlimited | password_lock_time | [1,525600]min | 认证类 | 如果因密码错误次数过多，导致账号被锁，将锁定\u0026lt;本参数\u0026gt;的时间 |\u003cbr\u003e\n| 3 | PASSWORD_LIFE_TIME | [1, max] unlimited | password_effect_time | [30,36500]day | 认证类 | 设置或更新用户密码时，超过\u0026lt;本参数\u0026gt;的时间，密码会过期（oracle与vastase表现不同） |\u003cbr\u003e\n| 4 | PASSWORD_GRACE_TIME | - | - | - | 认证类 | 如果密码过期，在\u0026lt;本参数\u0026gt;的时间内，密码仍可使用 |\u003cbr\u003e\n| 5 | PASSWORD_REUSE_TIME | [1, max] unlimited | password_reuse_time | [30, 90]day | 认证类 | 用户设置密码时，如果密码在过去的\u0026lt;本参数\u0026gt;的时间内别用过，则密码不能复用，opengauss [0,3650] |\u003cbr\u003e\n| 6 | PASSWORD_REUSE_MAX | - | password_reuse_max | [1,100] | 认证类 | 用户设置密码时，如果密码已被重复使用过\u0026lt;本参数\u0026gt;的次数，则密码不能复用 |\u003cbr\u003e\n| 7 | INACTIVE_ACCONT_TIME | - | - | - | 认证类 | 如果一个账号在\u0026lt;本参数\u0026gt;的时间内，未登录过，则锁定账号 |\u003cbr\u003e\n| 8 | PASSWORD_VERIFY_FUNCTION | - | - | - | 认证类 | 用户设置密码时，调用\u0026lt;本参数\u0026gt;指定的函数，检查密码是否符合要求 |\u003cbr\u003e\n| 9 | PASSWORD_ROLLOVER_TIME | - | - | - | 认证类 | 新旧密码滚动更新天数 |\u003cbr\u003e\n| 10 | SESSIONS_PER_USER | - | - | - | 资源类 | 1个用户可建立的最大连接数 |\u003cbr\u003e\n| 11 | CPU_PER_SESSION | - | - | - | 资源类 | 1个连接可使用CPU时间数 |\u003cbr\u003e\n| 12 | CPU_PER_CALL | - | - | - | 资源类 | 1个调用（比如1个SQL）可使用CPU时间数 |\u003cbr\u003e\n| 13 | CONNECT_TIME | - | - | - | 资源类 | 1个连接可持续的时间 |\u003cbr\u003e\n| 14 | IDLE_TIME | [1, max] unlimited | session_timeout | [0,86400] | 资源类 | 1个连接空闲时间限制 |\u003cbr\u003e\n| 15 | LOGICAL_READS_PER_CALL | - | - | - | 资源类 | 1次调用（比如1个SQL）允许读写的page数量 |\u003cbr\u003e\n| 16 | LOGICAL_READS_PER_SESSION | - | - | - | 资源类 | 1个连接允许读取的page数量 |\u003cbr\u003e\n| 17 | PRIVATE_SGA | - | - | - | 资源类 | 1个连接可使用的共享内存空间大小 |\u003cbr\u003e\n| 18 | CONPOSITE_LIMIT | - | - | - | 资源类 | 1个连接可可使用的总资源：按cpu时间、连接时间、page读写数等加权求和 |\u003c/p\u003e","title":"海量 3 需求 oracle resource"},{"content":"1 概述 1.1 衡量标准 1.2 分类 算法 思想 最好时间复杂度 最坏时间复杂度 时间复杂度 空间复杂度 稳定性 冒泡排序 比较、交换 O(n) O(n^2) O(n^2) O(1) 稳定，值相等不交换 插入排序 比较、移动 O(n) O(n^2) O(n^2) 选择排序 比较、交换 归并排序 快速排序 堆排序 桶排序 计数排序 基数排序 /* 冒泡排序 */ void sort_bubble(int *arr, int arrlen) { int end; int tmp; int i; end = arrlen - 1; for (end = arrlen - 1; end \u0026gt; 1; end--) { for (i = 0; i \u0026lt; end - 1; i++) { if (arr[i] \u0026lt; arr[i + 1]) { tmp = arr[i]; arr[i] = arr[i + 1]; arr[i + 1] = tmp; } } } } ","permalink":"https://my-blog.j8465383071.workers.dev/posts/algorithm/3-sorting/","summary":"\u003ch1 id=\"1-概述\"\u003e1 概述\u003c/h1\u003e\n\u003ch2 id=\"11-衡量标准\"\u003e1.1 衡量标准\u003c/h2\u003e\n\u003ch2 id=\"12-分类\"\u003e1.2 分类\u003c/h2\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e算法\u003c/th\u003e\n          \u003cth\u003e思想\u003c/th\u003e\n          \u003cth\u003e最好时间复杂度\u003c/th\u003e\n          \u003cth\u003e最坏时间复杂度\u003c/th\u003e\n          \u003cth\u003e时间复杂度\u003c/th\u003e\n          \u003cth\u003e空间复杂度\u003c/th\u003e\n          \u003cth\u003e稳定性\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e冒泡排序\u003c/td\u003e\n          \u003ctd\u003e比较、交换\u003c/td\u003e\n          \u003ctd\u003eO(n)\u003c/td\u003e\n          \u003ctd\u003eO(n^2)\u003c/td\u003e\n          \u003ctd\u003eO(n^2)\u003c/td\u003e\n          \u003ctd\u003eO(1)\u003c/td\u003e\n          \u003ctd\u003e稳定，值相等不交换\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e插入排序\u003c/td\u003e\n          \u003ctd\u003e比较、移动\u003c/td\u003e\n          \u003ctd\u003eO(n)\u003c/td\u003e\n          \u003ctd\u003eO(n^2)\u003c/td\u003e\n          \u003ctd\u003eO(n^2)\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e选择排序\u003c/td\u003e\n          \u003ctd\u003e比较、交换\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e归并排序\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e快速排序\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e堆排序\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e桶排序\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e计数排序\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e基数排序\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 冒泡排序 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003esort_bubble\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003earr\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003earrlen\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eend\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003etmp\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eend\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003earrlen\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eend\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003earrlen\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003eend\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003eend\u003c/span\u003e\u003cspan class=\"o\"\u003e--\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003eend\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003earr\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003earr\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e])\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003etmp\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003earr\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003earr\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003earr\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003earr\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003etmp\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"数据结构与算法 3 排序"},{"content":"1 Page的概念 1.1 前置概念 首先，简单介绍一些基本概念：\n关系 Relation：PostgreSQL是一款关系型数据库，在数据库中，1个表对应关系代数中的1个关系，即1个Relation。本博客中，将1个Relation指1个表 数据文件 RelFile：通过CREATE TABLE t1 (c1 INT, c2 TEXT)等语法创建1个表时，PostgreSQL会生成1个与表对应的数据文件，表中数据都将被存储至数据文件中 数据库页 Page：1个数据文件，由1个或多个大小为8192字节（即8k）的数据页组成 行 Row：在SQL语法INSERT INTO t1 VALUES (1, 'data1')中，(1, 'data1')是表中的1行数据 元组 Tuple：在PostgreSQL中，1个Tuple存储1行数据，数据越长，Tuple越长。1个Page可以存储多个Tuple 1.2 Page Page的格式如下：\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/3-2-page/","summary":"\u003ch1 id=\"1-page的概念\"\u003e1 Page的概念\u003c/h1\u003e\n\u003ch2 id=\"11-前置概念\"\u003e1.1 前置概念\u003c/h2\u003e\n\u003cp\u003e首先，简单介绍一些基本概念：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003e关系 Relation\u003c/strong\u003e：PostgreSQL是一款关系型数据库，在数据库中，1个表对应关系代数中的1个关系，即1个Relation。本博客中，将1个Relation指1个表\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e数据文件 RelFile\u003c/strong\u003e：通过\u003ccode\u003eCREATE TABLE t1 (c1 INT, c2 TEXT)\u003c/code\u003e等语法创建1个表时，PostgreSQL会生成1个与表对应的数据文件，表中数据都将被存储至数据文件中\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e数据库页 Page\u003c/strong\u003e：1个数据文件，由1个或多个大小为8192字节（即8k）的数据页组成\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e行 Row\u003c/strong\u003e：在SQL语法\u003ccode\u003eINSERT INTO t1 VALUES (1, 'data1')\u003c/code\u003e中，\u003ccode\u003e(1, 'data1')\u003c/code\u003e是表中的1行数据\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e元组 Tuple\u003c/strong\u003e：在PostgreSQL中，1个Tuple存储1行数据，数据越长，Tuple越长。1个Page可以存储多个Tuple\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"12-page\"\u003e1.2 Page\u003c/h2\u003e\n\u003cp\u003ePage的格式如下：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"page\" loading=\"lazy\" src=\"/images/PostgreSQL/3-2-page/page.png\"\u003e\u003c/p\u003e","title":"PostgreSQL 3-2 Page"},{"content":" 1 特性背景 2 实现方案 2.1 系统表 1. pg_key_info 密钥信息 2. pg_key_data 密钥数据 3. pg_encryption 加密对象 2.2 定义表 2.3 定义表加密 2.4 操作表 2.5 管理表加密 2.6 管理主密钥 2.7 管理数据密钥 2.8 管理加密定义 2.8 未来计划 一、功能补充 二、语法复用 3 关键设计 3.1 格式设计 3.2 流程设计 整体流程 加密粒度 加密时机 加密判断 密钥存储 解密时机 解密判断 密钥来源 3.3 其他设计 3.2 主备密钥同步 4 特性源码 4.1 功能概览 基本功能篇 高级功能篇 加强篇 4.2 新增系统表 pg_key_info 4.2 新增系统表 pg_key_data 4.3 新增语法 CREATE KEY 4.4 新增语法 CREATE TABLE .. (protect=$data_key) 4.5 对加密对象的数据进行加密 参考 1 特性背景 2 实现方案 2.1 系统表 1. pg_key_info 密钥信息 keyoid keyname type alrotithm storage access protect create_time round 1 mk_1 master_key any localkms path=./keyfile $pass1 2024/02/01 13:01:01 - 2 dk_1 date_key aes_256_cbc database m100.d100.b1.i2 mk1 2024/02/01 13:01:01 0 2. pg_key_data 密钥数据 oid keydata algorithm 3 abcd1234 aes_256 3. pg_encryption 加密对象 type name oid special protect oldest_round table t1 100 - dk_1 1 2.2 定义表 定义表\n定义表的语法与非加密表一致，我们通过单独的语法定义ENCRYPTION。\nCREATE TABLE t1 (c1 INT, c2 TEXT); 定义索引\nCREATE INDEX i1 ON t1 (c1); 2.3 定义表加密 定义主密钥\nCREATE KEY mk_1 (type=master_key, storage=localkms, access=\u0026#39;./keyfile\u0026#39;, protect=\u0026#39;$pass1\u0026#39;); 定义数据密钥\nCREATE KEY dk_1 (type=data_key, protect=mk_1, algorithm=aes_256_cbc); 定义表加密\n表上的索引默认不加密\nCREATE ENCRYPTION (protect=dk_1) ON TABLE t1; CREATE TABLE t1 (c1 INT, c2 TEXT);\nCREATE KEY mk_1 (type=master_key, storage=localkms, access=’./keyfile’, protect=’$pass1’);\nCREATE KEY dk_1 (type=data_key, protect=mk_1, algorithm=aes_256_cbc);\nCREATE ENCRYPTION (protect=dk_1) ON TABLE t1;\nSELECT * FROM pg_encryption;\n定义表上索引加密\nCREATE ENCRYPTION (protect=dk_1) ON TABLE t1 WITH (index=on); 定义表上xlog加密\nCREATE ENCRYPTION (protect=dk_1) ON TABLE t1 WITH (index=on, xlog=on); 定义索引加密\nCREATE ENCRYPTION (protect=dk_1) ON INDEX i1; 2.4 操作表 写入数据\nINSERT INTO t1 VALUES (1, \u0026#39;aaaaa\u0026#39;); 查询数据\nSELECT * FROM t1; 2.5 管理表加密 查看表加密\nSELECT * FROM pg_encryption; 修改表加密的密钥\nALTER ENCRYPTION (protect=dk_2) ON TABLE t1; 删除表加密\nDROP ENCRYPTION ON TABLE t1; 2.6 管理主密钥 查看主密钥信息\nSELECT * FROM pg_key_info WHERE type = \u0026#39;master_key\u0026#39;; 修改主密钥\nALTER KEY mk_1 SET (access=\u0026#39;./keyfile2\u0026#39;); 删除主密钥\nDROP KEY mk_1; 2.7 管理数据密钥 查看数据密钥信息\nSELECT * FROM pg_key_info WHERE type = \u0026#39;data_key\u0026#39;; 查看数据密钥密文\nSELECT * FROM pg_key_data; 轮转数据密钥\nROTATION KEY dk_1; 修改数据密钥\nALTER KEY dk_1 SET (protect=mk_2); 收集旧版本数据密钥信息\nVACUUM FULL t1; 回收旧版本数据密钥\nVACUUM KEY dk_1; 删除数据密钥\nDROP KEY dk_1; 2.8 管理加密定义 删除加密定义\nDROP ENCRYPTION ON TABLE t1; 2.8 未来计划 一、功能补充 在ENCRYPTION与KEY，KEY与KEY之间，添加DEPENDENCY约束 为ENCRYPTION和KEY添加ACL，控制访问权限 二、语法复用 定义列加密\n该种定义可用于全密态数据库\nCREATE ENCRYPTION (protect=dk_1) ON COLUMN t1(c1); 定义表空间加密\nCREATE ENCRYPTION (protect=dk_1) ON TABLESPACE spc1; 定义数据库加密\nCREATE ENCRYPTION (protect=dk_1) ON DATABASE spc1; 定义xlog加密\nCREATE ENCRYPTION (protect=dk_1) ON XLOG; 3 关键设计 3.1 格式设计 Page格式\n+---------------+ | PageHeader | 在Header中，标记Page属于加密表，并标记加密状态 | | | tuple .. | | tuple 2 | | tuple 1 | | PageSpecial | 在Special中，记录密钥信息 +---------------+ PageSpecial格式\ntypedef struct { uint8 version; uint8 algo; Tid datakeypos; uchar iv[16]; uchar mac[32]; } PageEncInfo; 3.2 流程设计 整体流程 @user create table t1 (.. dk_1) @user: insert into t1 (..abc) @kernel.postgres: heap_insert(t1, \u0026#39;abc\u0026#39;) page_init(t1.dk_1, page) memcpy(page, get_enc_info(t1.dk_1)) page_set_flag(page, tde_flag) page_add_item(page, \u0026#39;abc\u0026#39;) @kernel.checkpoint: smgrwrite(page) if (is_page_set_flag(page, tde_flag)) page_encrypt_date(page) 加密粒度 加密时机 加密判断 密钥存储 解密时机 解密判断 密钥来源 3.3 其他设计 3.2 主备密钥同步 # 主机 page_init(page, encinfo) memcpy(page, encinfo) 4 特性源码 4.1 功能概览 基本功能篇 新增系统表：pg_key_info 新增系统表：pg_key_data 新增语法：CREATE KEY 新增语法：CREATE TABLE .. (encrypt=xx) 加密判断与密钥存储 解密判断与密钥来源 高级功能篇 索引的加密判断与密钥存储\n加密Redo Log\n加强篇 新增视图 4.2 新增系统表 pg_key_info 查找oid\ncd $PGCODE/src/include/catalog chmod +x ./unused_oids ./unused_oids 4001\n新增头文件 pg_key_info.h\ntouch pg_key_info.h git add ./pg_key_info.h #ifndef 编译头文件\ncd $PGCODE/src/backend/catalog vi Makefile # add pg_key_info.h 添加缓存 skip now\ncd $PGCODE/src/include/catlog vi indexing.h DECLARE_UNIQUE_INDEX(pg_key_info_keyoid, 4002, on pg_key_info using btree(keyoid oid_ops)); #define KeyInfoKeyoidIndexId\t4002 编译、安装、启动\n验证\nSELECT * FROM pg_key_info; \\d pg_key_info 4.2 新增系统表 pg_key_data 流程和方法与新增pg_key_info一致，此处不再赘述\n4.3 新增语法 CREATE KEY 定义主密钥\nCREATE KEY mk_1 (type=master_key, storage=localkms, access=\u0026#39;./keyfile\u0026#39;, protect=\u0026#39;$pass1\u0026#39;); 定义数据密钥\nCREATE KEY dk_1 (type=data_key, protect=mk_1, algorithm=aes_256_cbc); 负向用例\n-- 1. 不设置密钥类型 CREATE KEY key1 (storage=localkms, access=\u0026#39;./keyfile\u0026#39;, protect=\u0026#39;$pass1\u0026#39;); -- 2. 主密钥 重名 CREATE KEY mk_1 (type=master_key, storage=localkms, access=\u0026#39;./keyfile\u0026#39;, protect=\u0026#39;$pass1\u0026#39;); -- 3. 主密钥 未设置必要参数：storage等 CREATE KEY mk_2 (type=master_key, access=\u0026#39;./keyfile\u0026#39;, protect=\u0026#39;$pass1\u0026#39;); -- 4. 主密钥 设置不支持的参数：keyoid, unkownpara CREATE KEY mk_2 (type=master_key, keyoid=1, torage=localkms, access=\u0026#39;./keyfile\u0026#39;, protect=\u0026#39;$pass1\u0026#39;); CREATE KEY mk_2 (type=master_key, unkownpara=1, torage=localkms, access=\u0026#39;./keyfile\u0026#39;, protect=\u0026#39;$pass1\u0026#39;); -- 5. 数据密钥 重名 CREATE KEY dk_1 (type=data_key, protect=mk_1, algorithm=aes_256_cbc); --6. 数据密钥 对应的主密钥不存在 CREATE KEY dk_2 (type=data_key, protect=mk_8, algorithm=aes_256_cbc); --7. 数据密钥 不支持的算法 CREATE KEY dk_2 (type=data_key, protect=mk_1, algorithm=rsa_2048); 4.4 新增语法 CREATE TABLE .. (protect=$data_key) 创建加密表\nCREATE TABLE t1 (c1 INT, c2 TEXT) WITH (protect=dk_1); 创建加密索引\nCREATE INDEX i1 ON t1 USING btree(c2) WITH (protect=dk_1); 负向用例\n-- 不设置参数 CREATE TABLE t2 (c1 INT, c2 TEXT) WITH (protect); -- 不存在的数据密钥 CREATE TABLE t2 (c1 INT, c2 TEXT) WITH (protect=dk_8); -- 密钥类型为主密钥 CREATE TABLE t2 (c1 INT, c2 TEXT) WITH (protect=mk_1); 4.5 对加密对象的数据进行加密 参考 新增系统表：https://blog.csdn.net/asmartkiller/article/details/120733642 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/3-2-postgresql-tde/","summary":"\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-%E7%89%B9%E6%80%A7%E8%83%8C%E6%99%AF\"\u003e1 特性背景\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-%E5%AE%9E%E7%8E%B0%E6%96%B9%E6%A1%88\"\u003e2 实现方案\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#2-1-%E7%B3%BB%E7%BB%9F%E8%A1%A8\"\u003e2.1 系统表\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-pg-key-info-%E5%AF%86%E9%92%A5%E4%BF%A1%E6%81%AF\"\u003e1. pg_key_info 密钥信息\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-pg-key-data-%E5%AF%86%E9%92%A5%E6%95%B0%E6%8D%AE\"\u003e2. pg_key_data 密钥数据\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-pg-encryption-%E5%8A%A0%E5%AF%86%E5%AF%B9%E8%B1%A1\"\u003e3. pg_encryption 加密对象\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-2-%E5%AE%9A%E4%B9%89%E8%A1%A8\"\u003e2.2 定义表\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-3-%E5%AE%9A%E4%B9%89%E8%A1%A8%E5%8A%A0%E5%AF%86\"\u003e2.3 定义表加密\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-4-%E6%93%8D%E4%BD%9C%E8%A1%A8\"\u003e2.4 操作表\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-5-%E7%AE%A1%E7%90%86%E8%A1%A8%E5%8A%A0%E5%AF%86\"\u003e2.5 管理表加密\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-6-%E7%AE%A1%E7%90%86%E4%B8%BB%E5%AF%86%E9%92%A5\"\u003e2.6 管理主密钥\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-7-%E7%AE%A1%E7%90%86%E6%95%B0%E6%8D%AE%E5%AF%86%E9%92%A5\"\u003e2.7 管理数据密钥\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-8-%E7%AE%A1%E7%90%86%E5%8A%A0%E5%AF%86%E5%AE%9A%E4%B9%89\"\u003e2.8 管理加密定义\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-8-%E6%9C%AA%E6%9D%A5%E8%AE%A1%E5%88%92\"\u003e2.8 未来计划\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%80%E3%80%81%E5%8A%9F%E8%83%BD%E8%A1%A5%E5%85%85\"\u003e一、功能补充\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BA%8C%E3%80%81%E8%AF%AD%E6%B3%95%E5%A4%8D%E7%94%A8\"\u003e二、语法复用\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-%E5%85%B3%E9%94%AE%E8%AE%BE%E8%AE%A1\"\u003e3 关键设计\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#3-1-%E6%A0%BC%E5%BC%8F%E8%AE%BE%E8%AE%A1\"\u003e3.1 格式设计\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-2-%E6%B5%81%E7%A8%8B%E8%AE%BE%E8%AE%A1\"\u003e3.2 流程设计\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E6%95%B4%E4%BD%93%E6%B5%81%E7%A8%8B\"\u003e整体流程\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%8A%A0%E5%AF%86%E7%B2%92%E5%BA%A6\"\u003e加密粒度\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%8A%A0%E5%AF%86%E6%97%B6%E6%9C%BA\"\u003e加密时机\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%8A%A0%E5%AF%86%E5%88%A4%E6%96%AD\"\u003e加密判断\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%AF%86%E9%92%A5%E5%AD%98%E5%82%A8\"\u003e密钥存储\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E8%A7%A3%E5%AF%86%E6%97%B6%E6%9C%BA\"\u003e解密时机\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E8%A7%A3%E5%AF%86%E5%88%A4%E6%96%AD\"\u003e解密判断\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%AF%86%E9%92%A5%E6%9D%A5%E6%BA%90\"\u003e密钥来源\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-3-%E5%85%B6%E4%BB%96%E8%AE%BE%E8%AE%A1\"\u003e3.3 其他设计\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-2-%E4%B8%BB%E5%A4%87%E5%AF%86%E9%92%A5%E5%90%8C%E6%AD%A5\"\u003e3.2 主备密钥同步\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-%E7%89%B9%E6%80%A7%E6%BA%90%E7%A0%81\"\u003e4 特性源码\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#4-1-%E5%8A%9F%E8%83%BD%E6%A6%82%E8%A7%88\"\u003e4.1 功能概览\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E5%9F%BA%E6%9C%AC%E5%8A%9F%E8%83%BD%E7%AF%87\"\u003e基本功能篇\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E9%AB%98%E7%BA%A7%E5%8A%9F%E8%83%BD%E7%AF%87\"\u003e高级功能篇\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%8A%A0%E5%BC%BA%E7%AF%87\"\u003e加强篇\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-2-%E6%96%B0%E5%A2%9E%E7%B3%BB%E7%BB%9F%E8%A1%A8-pg-key-info\"\u003e4.2 新增系统表 pg_key_info\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-2-%E6%96%B0%E5%A2%9E%E7%B3%BB%E7%BB%9F%E8%A1%A8-pg-key-data\"\u003e4.2 新增系统表 pg_key_data\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-3-%E6%96%B0%E5%A2%9E%E8%AF%AD%E6%B3%95-CREATE-KEY\"\u003e4.3 新增语法 CREATE KEY\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-4-%E6%96%B0%E5%A2%9E%E8%AF%AD%E6%B3%95-CREATE-TABLE-protect-x3D-data-key\"\u003e4.4 新增语法 CREATE TABLE .. (protect=$data_key)\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-5-%E5%AF%B9%E5%8A%A0%E5%AF%86%E5%AF%B9%E8%B1%A1%E7%9A%84%E6%95%B0%E6%8D%AE%E8%BF%9B%E8%A1%8C%E5%8A%A0%E5%AF%86\"\u003e4.5 对加密对象的数据进行加密\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%8F%82%E8%80%83\"\u003e参考\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"1-特性背景\"\u003e1 特性背景\u003c/h1\u003e\n\u003ch1 id=\"2-实现方案\"\u003e2 实现方案\u003c/h1\u003e\n\u003ch2 id=\"21-系统表\"\u003e2.1 系统表\u003c/h2\u003e\n\u003ch3 id=\"1-pg_key_info-密钥信息\"\u003e1. pg_key_info 密钥信息\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003ekeyoid\u003c/th\u003e\n          \u003cth\u003ekeyname\u003c/th\u003e\n          \u003cth\u003etype\u003c/th\u003e\n          \u003cth\u003ealrotithm\u003c/th\u003e\n          \u003cth\u003estorage\u003c/th\u003e\n          \u003cth\u003eaccess\u003c/th\u003e\n          \u003cth\u003eprotect\u003c/th\u003e\n          \u003cth\u003ecreate_time\u003c/th\u003e\n          \u003cth\u003eround\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e1\u003c/td\u003e\n          \u003ctd\u003emk_1\u003c/td\u003e\n          \u003ctd\u003emaster_key\u003c/td\u003e\n          \u003ctd\u003eany\u003c/td\u003e\n          \u003ctd\u003elocalkms\u003c/td\u003e\n          \u003ctd\u003epath=./keyfile\u003c/td\u003e\n          \u003ctd\u003e$pass1\u003c/td\u003e\n          \u003ctd\u003e2024/02/01 13:01:01\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e2\u003c/td\u003e\n          \u003ctd\u003edk_1\u003c/td\u003e\n          \u003ctd\u003edate_key\u003c/td\u003e\n          \u003ctd\u003eaes_256_cbc\u003c/td\u003e\n          \u003ctd\u003edatabase\u003c/td\u003e\n          \u003ctd\u003em100.d100.b1.i2\u003c/td\u003e\n          \u003ctd\u003emk1\u003c/td\u003e\n          \u003ctd\u003e2024/02/01 13:01:01\u003c/td\u003e\n          \u003ctd\u003e0\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"2-pg_key_data-密钥数据\"\u003e2. pg_key_data 密钥数据\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003eoid\u003c/th\u003e\n          \u003cth\u003ekeydata\u003c/th\u003e\n          \u003cth\u003ealgorithm\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e3\u003c/td\u003e\n          \u003ctd\u003eabcd1234\u003c/td\u003e\n          \u003ctd\u003eaes_256\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch3 id=\"3-pg_encryption-加密对象\"\u003e3. pg_encryption 加密对象\u003c/h3\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003etype\u003c/th\u003e\n          \u003cth\u003ename\u003c/th\u003e\n          \u003cth\u003eoid\u003c/th\u003e\n          \u003cth\u003especial\u003c/th\u003e\n          \u003cth\u003eprotect\u003c/th\u003e\n          \u003cth\u003eoldest_round\u003c/th\u003e\n          \u003cth\u003e\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003etable\u003c/td\u003e\n          \u003ctd\u003et1\u003c/td\u003e\n          \u003ctd\u003e100\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003edk_1\u003c/td\u003e\n          \u003ctd\u003e1\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"22-定义表\"\u003e2.2 定义表\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e定义表\u003cbr\u003e\n定义表的语法与非加密表一致，我们通过单独的语法定义ENCRYPTION。\u003c/p\u003e","title":"数据库安全 0 postgresql表级透明加密"},{"content":"接口\nvoid smgrcreate(SMgrRelation reln, ForkNumber forknum, bool isRedo); // 创建文件 void smgrdounlink(SMgrRelation reln, bool isRedo); SMgrRelation smgropen(RelFileNode rnode, BackendId backend); void smgrclose(SMgrRelation reln); void smgrwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync); void smgrread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer); void smgrextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer, bool skipFsync); 调用关系\n// 索引模块 btbuildempty() smgrwrite(metapage) _bt_blwritepage() smgrwrite() spgbuildempty() smgrwrite() |- FlushBuffer() ... |- FlushRelationBuffers() |- LocalBufferAlloc() smgrwrite() // FlushBuffer |- BufferAlloc() // readBuffer时，申请一个buffer，可能调用页面淘汰算法 |- FlushDatabaseBuffers() |- FlushRelationBuffers() |- FlushOneBuffer() FlushBuffer() // FlushOneBuffer XLogReadBufferForRedoExtended() FlushOneBuffer() // FlushRelationBuffers |- heap_sync() |- ATExecSetTableSpace() // ALTER TABLE SET TABLESPACE FlushRelationBuffers() // heap_sync when HEAP_INSERT_SKIP_WAL |- intorel_shutdown() |- CopyFrom() |- transientrel_shutdown() |- ATRewriteTable() heap_sync() // FlushDatabaseBuffers dbase_redo() FlushDatabaseBuffers() write时机：\nreadBuffer时，如果buffer不在内存，且共享缓冲池已满，调用页面置换算法进行刷盘 alter table set table space copy ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/3-3-smgr/","summary":"\u003cp\u003e接口\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003esmgrcreate\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSMgrRelation\u003c/span\u003e \u003cspan class=\"n\"\u003ereln\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eForkNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eforknum\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003eisRedo\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 创建文件\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003esmgrdounlink\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSMgrRelation\u003c/span\u003e \u003cspan class=\"n\"\u003ereln\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003eisRedo\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eSMgrRelation\u003c/span\u003e \u003cspan class=\"nf\"\u003esmgropen\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelFileNode\u003c/span\u003e \u003cspan class=\"n\"\u003ernode\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBackendId\u003c/span\u003e \u003cspan class=\"n\"\u003ebackend\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003esmgrclose\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSMgrRelation\u003c/span\u003e \u003cspan class=\"n\"\u003ereln\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003esmgrwrite\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSMgrRelation\u003c/span\u003e \u003cspan class=\"n\"\u003ereln\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eForkNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eforknum\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eblocknum\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003eskipFsync\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003esmgrread\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSMgrRelation\u003c/span\u003e \u003cspan class=\"n\"\u003ereln\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eForkNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eforknum\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eblocknum\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003esmgrextend\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSMgrRelation\u003c/span\u003e \u003cspan class=\"n\"\u003ereln\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eForkNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eforknum\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eblocknum\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003eskipFsync\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e调用关系\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 索引模块\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nf\"\u003ebtbuildempty\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003esmgrwrite\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emetapage\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003e_bt_blwritepage\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003esmgrwrite\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003espgbuildempty\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003esmgrwrite\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e|-\u003c/span\u003e \u003cspan class=\"nf\"\u003eFlushBuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"p\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e|-\u003c/span\u003e \u003cspan class=\"nf\"\u003eFlushRelationBuffers\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e|-\u003c/span\u003e \u003cspan class=\"nf\"\u003eLocalBufferAlloc\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003esmgrwrite\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// FlushBuffer\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e|-\u003c/span\u003e \u003cspan class=\"nf\"\u003eBufferAlloc\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"c1\"\u003e// readBuffer时，申请一个buffer，可能调用页面淘汰算法\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e|-\u003c/span\u003e \u003cspan class=\"nf\"\u003eFlushDatabaseBuffers\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e|-\u003c/span\u003e \u003cspan class=\"nf\"\u003eFlushRelationBuffers\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e|-\u003c/span\u003e \u003cspan class=\"nf\"\u003eFlushOneBuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eFlushBuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// FlushOneBuffer\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nf\"\u003eXLogReadBufferForRedoExtended\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eFlushOneBuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// FlushRelationBuffers\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e|-\u003c/span\u003e \u003cspan class=\"nf\"\u003eheap_sync\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e|-\u003c/span\u003e \u003cspan class=\"nf\"\u003eATExecSetTableSpace\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"c1\"\u003e// ALTER TABLE SET TABLESPACE\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e    \u003cspan class=\"nf\"\u003eFlushRelationBuffers\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// heap_sync when HEAP_INSERT_SKIP_WAL\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e|-\u003c/span\u003e \u003cspan class=\"nf\"\u003eintorel_shutdown\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e|-\u003c/span\u003e \u003cspan class=\"nf\"\u003eCopyFrom\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e|-\u003c/span\u003e \u003cspan class=\"nf\"\u003etransientrel_shutdown\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e|-\u003c/span\u003e \u003cspan class=\"nf\"\u003eATRewriteTable\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eheap_sync\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// FlushDatabaseBuffers\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"nf\"\u003edbase_redo\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eFlushDatabaseBuffers\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003ewrite时机：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ereadBuffer时，如果buffer不在内存，且共享缓冲池已满，调用页面置换算法进行刷盘\u003c/li\u003e\n\u003cli\u003ealter table set table space\u003c/li\u003e\n\u003cli\u003ecopy\u003c/li\u003e\n\u003c/ol\u003e","title":"PostgreSQL 3-6 Smgr"},{"content":"1 Buffer基本介绍 1.1 Buffer解决的问题 实际应用场景中，PostgreSQL可能需要1分钟处理数十万次事务，频繁读写Page。Buffer提供以下2个基本功能：\n加载Page至内存：PostgreSQL需要读写数时，都需先从磁盘中，将指定的Page加载至内存中，再在内存中操作Page 缓存常用Page：Page被加载至内存后，还会在内存停留一段时间，降低PostgreSQL直接从磁盘读写Page的频率 1.2 Buffer的基本功能 Buffer缓存Page时，需考虑以下几个场景：\n插入Page：大部分事务操作表的Page时，先从Buffer中查找Page，如果Page不在Buffer中，再从磁盘读取Page，将其放入Buffer中，再操作Buffer中的Page 查找Page：访问Page时，通过文件名和Page编号等信息可确定唯一Page 访问Page：所有事务均可访问Buffer，需考虑多事务并发读写同一Pape的场景 淘汰Page：Buffer能缓存的Page数量有限，在Page数量过多时，需淘汰一些Page 落盘Page：Buffer中通常缓存表数据文件的Page，前文提到，事务持久化的标志是WAL日志落盘，因此，Buffer中的Page无需实时落盘，仅需异步落盘即可 2 Buffer的基本原理 2.1 插入Page 插入Page主要由读Page操作触发，上层函数读取Page的主要流程如下：\n上层模块统一调用ReadBuffer()接口，读取指定表的指定Page ReadBuffer()中，先从Buffer查找Page，如果找到Page，则直接返回Buffer中的Page 如果未从Buffer找到Page，现在Buffer中预留存储Page的空间 之后，调用Smgr模块，从磁盘读取指定Page，并将其放入预留的空间内，再返回Buffer中的Page 函数调用关系大概如下图所示：\nReadBuffer(Relation, BlockNumber) # 1 ReadBufferExtended() ReadBuffer_common() BufferAlloc() # 2,3 查找Page，如找到，返回；如未找到，预留存储Page的空间 smgrread(.., BlockNumber) # 4 如果未找到Page，从磁盘将Page读入预留的Page空间内，返回 2.2 查找Page 上层函数读Page时，首先进入查找Page阶段。\n1.1 buffer池模型 模型：\n1.2 buffer池接口 缓冲区接口：\n/* bufmgr.h */ /* 1 buffer池管理 */ void InitBufferPool(void); void InitBufferPoolAccess(void); void InitBufferPoolBackend(void); /* 2 buffer管理 */ /* 2.1 读buffer */ Buffer ReadBuffer(Relation reln, BlockNumber blockNum); Buffer ReadBufferExtended(Relation reln, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy); Buffer ReadBufferWithoutRelcache(RelFileNode rnode, ForkNumber forkNum, BlockNumber blockNum,ReadBufferMode mode, BufferAccessStrategy strategy); /* 2.2 清理buffer */ oid ReleaseBuffer(Buffer buffer); void UnlockReleaseBuffer(Buffer buffer); void MarkBufferDirty(Buffer buffer); void IncrBufferRefCount(Buffer buffer); Buffer ReleaseAndReadBuffer(Buffer buffer, Relation relation, BlockNumber blockNum); /* 2.3 刷盘buffer */ void CheckPointBuffers(int flags); void FlushOneBuffer(Buffer buffer); void FlushRelationBuffers(Relation rel); void FlushDatabaseBuffers(Oid dbid); void BufmgrCommit(void); bool BgBufferSync(void); /* 2.4 删除关联buffer */ void DropRelFileNodeBuffers(RelFileNodeBackend rnode, ForkNumber forkNum, BlockNumber firstDelBlock); void DropRelFileNodesAllBuffers(RelFileNodeBackend *rnodes, int nnodes); void DropDatabaseBuffers(Oid dbid); /* 2.5 锁buffer */ void UnlockBuffers(void); void LockBuffer(Buffer buffer, int mode); bool ConditionalLockBuffer(Buffer buffer); void LockBufferForCleanup(Buffer buffer); bool ConditionalLockBufferForCleanup(Buffer buffer); bool HoldingBufferPinThatDelaysRecovery(void); 1.3 buffer调用 插入数据\nheap_insert() RelationGetBufferForTuple() /* 已有page，查找空闲的page */ GetPageWithFreeSpace() /* 读取page，放入缓冲池 */ ReadBufferBI() ReadBuffer() /* buffer接口 */ ReadBufferExtended() ReadBuffer_common() BufferAlloc() /* 遍历buffer池，查找 */ 查找页面\nBufferDesc BufferAlloc() BufTableHashCode(newtag) buf_id = BufTableLookup() if buf_id: buf_desc = GetBufferDescriptor(buf_id) PinBuffer(buf_desc) return buf_desc; for (;;) { buf_desc = StrategyGetBuffer() if buf_desc dirty : FlushBuffer(buf_desc) if buf_desc tab_valid: /* 旧buf有数据，但旧buf可用 */ /* partition lock ? */ buf_id = BufTableInsert(newtag, buf_desc-\u0026gt;buf_id) /* 可能失败，多进程一起申请同一page */ if buf_id: return buf_desc BufTableDelete(newtag) } BufTableDelete(oldtag) 2 实现 2.1 ReadBuffer Buffer ReadBuffer(Relation reln, BlockNumber blockNum) Buffer buf = ReadBufferExtended(reln, MAIN_FORKNUM, blockNum, RBM_NORMAL, NULL) /* 读场景 strategy = NULL */ Buffer buf = ReadBuffer_common(SMgrRelation smgr, char relpersistence, ForkNumber forkNum, BlockNumber blockNum, ReadBufferMode mode, BufferAccessStrategy strategy, bool *hit) { /* 1. 根据表类型判断，使用LocalBuffer还是共享Buffer */ bool isLocalBuf = SmgrIsTemp(smgr) if isLocalBuf: LocalBufferAlloc() else: /* 选择1个buffer槽，{fornNum, BlockNum}等信息写入buffer槽 */ BufferDesc *bufHdr = BufferAlloc(smgr, forkNum, blockNum, strategy, \u0026amp;found) { uint32 newHash = BufTableHashCode({smgr-\u0026gt;smgr_rnode.node, forkNum, blockNum}) /* 2. 根据blockNum等信息，从哈希表中查找buf_id */ int buf_id = BufTableLookup(\u0026amp;newTag, newHash) if buf_id \u0026gt;= 0: /* 如果找到（已在buffer池中） */ /* 3.1 根据buf_id，查找BufferDesc */ BufferDesc *buf = GetBufferDescriptor(buf_id) /* 3.2 根据BufferDesc，引用计数++，使用计数++ */ PinBuffer(BufferDesc *buf) buf-\u0026gt;refcount++ buf-\u0026gt;usage_count++ /* 异常处理 */ return buf for (;;) /* 如果没找到 */ BufferDesc *buf = StrategyGetBuffer(strategy) BufferDesc *buf = GetBufferFromRing() bgwprocno = StrategyControl-\u0026gt;bgwprocno /* 4.1 唤醒bg writer */ SetLatch(\u0026amp;ProcGlobal-\u0026gt;allProcs[bgwprocno].procLatch) /* 4.2 检查是否有空闲Buffer */ if StrategyControl-\u0026gt;firstFreeBuffer \u0026gt;= 0: buf = GetBufferDescriptor(StrategyControl-\u0026gt;firstFreeBuffer) StrategyControl-\u0026gt;firstFreeBuffer = buf-\u0026gt;freeNext /* 4.3 TODO */ /* 4.4 根据BufferDesc，引用计数++，使用计数++ */ if buf-\u0026gt;flags \u0026amp; BM_DIRTY: /* 4.5 将选中的Buffer落盘 */ FlushBuffer(buf) if buf-\u0026gt;flags \u0026amp; BM_TAG_VALID: oldTag = buf-\u0026gt;tag oldHash = BufTableHashCode(\u0026amp;oldTag) /* 4.6 将hash表中受害者Buffer对应的位置替换为即将写入的的BufferTag，-1表示成功，否则返回已存在的冲突的buffer id */ buf_id = BufTableInsert(\u0026amp;newTag, newHash, buf-\u0026gt;buf_id) /* 4.7 如果其他进程已经将新的buffer写入哈希表，直接返回即可 */ if buf_id \u0026gt;= 0: PinBuffer(buf) return buf /* 4.8 替换映射成功 */ LockBufHdr(buf) oldFlags = buf-\u0026gt;flags if buf-\u0026gt;refcount == 1 \u0026amp;\u0026amp; !(oldFlags \u0026amp; BM_DIRTY): /* 4.9 替换映射成功，且受害者buffer没有被重新写入数据 */ break; /* 4.10 受害者buffer又被重新写入新数据，需要重新进入循环选择新的受害者 */ BufTableDelete(\u0026amp;newTag, newHash) UnpinBuffer(buf, true) /* 将受害者buffer对用的信息替换为新page，并将buffer槽标记为VM_INVALID */ buf-\u0026gt;tag = newTag buf-\u0026gt;flags \u0026amp;= ~(BM_VALID | BM_DIRTY | BM_JUST_DIRTIED | BM_CHECKPOINT_NEEDED | BM_IO_ERROR | BM_PERMANENT) buf-\u0026gt;usage_count = 1 if oldFlags \u0026amp; BM_TAG_VALID: BufTableDelete(\u0026amp;oldTag, oldHash) return buf } /* 5. 如果page已在Buffer池中，直接返回即可 */ if found: *hit = true return BufferDescriptorGetBuffer(bufHdr) /* 6. 从磁盘读取page，并且直接读如buffer槽中 */ bufBlock = isLocalBuf ? LocalBufHdrGetBlock(bufHdr) : BufHdrGetBlock(bufHdr) smgrread(smgr, forkNum, blockNum, bufBlock) if !PageIsVerified(bufBlock): ereport ... /* 7. 在bufHdr中将buffer设置未BM_VALID */ TerminateBufferIO(bufHdr, false, BM_VALID) return BufferDescriptorGetBuffer(bufHdr) } ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/3-4-buffer/","summary":"\u003ch1 id=\"1-buffer基本介绍\"\u003e1 Buffer基本介绍\u003c/h1\u003e\n\u003ch2 id=\"11-buffer解决的问题\"\u003e1.1 Buffer解决的问题\u003c/h2\u003e\n\u003cp\u003e实际应用场景中，PostgreSQL可能需要1分钟处理数十万次事务，频繁读写Page。Buffer提供以下2个基本功能：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e加载Page至内存：PostgreSQL需要读写数时，都需先从磁盘中，将指定的Page加载至内存中，再在内存中操作Page\u003c/li\u003e\n\u003cli\u003e缓存常用Page：Page被加载至内存后，还会在内存停留一段时间，降低PostgreSQL直接从磁盘读写Page的频率\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"12-buffer的基本功能\"\u003e1.2 Buffer的基本功能\u003c/h2\u003e\n\u003cp\u003eBuffer缓存Page时，需考虑以下几个场景：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e插入Page：大部分事务操作表的Page时，先从Buffer中查找Page，如果Page不在Buffer中，再从磁盘读取Page，将其放入Buffer中，再操作Buffer中的Page\u003c/li\u003e\n\u003cli\u003e查找Page：访问Page时，通过文件名和Page编号等信息可确定唯一Page\u003c/li\u003e\n\u003cli\u003e访问Page：所有事务均可访问Buffer，需考虑多事务并发读写同一Pape的场景\u003c/li\u003e\n\u003cli\u003e淘汰Page：Buffer能缓存的Page数量有限，在Page数量过多时，需淘汰一些Page\u003c/li\u003e\n\u003cli\u003e落盘Page：Buffer中通常缓存表数据文件的Page，前文提到，事务持久化的标志是WAL日志落盘，因此，Buffer中的Page无需实时落盘，仅需异步落盘即可\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-buffer的基本原理\"\u003e2 Buffer的基本原理\u003c/h1\u003e\n\u003ch2 id=\"21-插入page\"\u003e2.1 插入Page\u003c/h2\u003e\n\u003cp\u003e插入Page主要由读Page操作触发，上层函数读取Page的主要流程如下：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e上层模块统一调用ReadBuffer()接口，读取指定表的指定Page\u003c/li\u003e\n\u003cli\u003eReadBuffer()中，先从Buffer查找Page，如果找到Page，则直接返回Buffer中的Page\u003c/li\u003e\n\u003cli\u003e如果未从Buffer找到Page，现在Buffer中预留存储Page的空间\u003c/li\u003e\n\u003cli\u003e之后，调用Smgr模块，从磁盘读取指定Page，并将其放入预留的空间内，再返回Buffer中的Page\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e函数调用关系大概如下图所示：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eReadBuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eReadBufferExtended\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eReadBuffer_common\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eBufferAlloc\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 2,3 查找Page，如找到，返回；如未找到，预留存储Page的空间\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003esmgrread\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e..\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 4 如果未找到Page，从磁盘将Page读入预留的Page空间内，返回\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"22-查找page\"\u003e2.2 查找Page\u003c/h2\u003e\n\u003cp\u003e上层函数读Page时，首先进入查找Page阶段。\u003c/p\u003e\n\u003ch2 id=\"11-buffer池模型\"\u003e1.1 buffer池模型\u003c/h2\u003e\n\u003cp\u003e模型：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"1\" loading=\"lazy\" src=\"/images/PostgreSQL/3-4-buffer/1.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"12-buffer池接口\"\u003e1.2 buffer池接口\u003c/h2\u003e\n\u003cp\u003e缓冲区接口：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* bufmgr.h */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 1 buffer池管理 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eInitBufferPool\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eInitBufferPoolAccess\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eInitBufferPoolBackend\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 2 buffer管理 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 2.1 读buffer */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"nf\"\u003eReadBuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003ereln\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eblockNum\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"nf\"\u003eReadBufferExtended\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003ereln\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eForkNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eforkNum\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eblockNum\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eReadBufferMode\u003c/span\u003e \u003cspan class=\"n\"\u003emode\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBufferAccessStrategy\u003c/span\u003e \u003cspan class=\"n\"\u003estrategy\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"nf\"\u003eReadBufferWithoutRelcache\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelFileNode\u003c/span\u003e \u003cspan class=\"n\"\u003ernode\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eForkNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eforkNum\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eblockNum\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eReadBufferMode\u003c/span\u003e \u003cspan class=\"n\"\u003emode\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBufferAccessStrategy\u003c/span\u003e \u003cspan class=\"n\"\u003estrategy\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 2.2 清理buffer */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eReleaseBuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eUnlockReleaseBuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eMarkBufferDirty\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eIncrBufferRefCount\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"nf\"\u003eReleaseAndReadBuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003erelation\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eblockNum\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 2.3 刷盘buffer */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eCheckPointBuffers\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eflags\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eFlushOneBuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eFlushRelationBuffers\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eFlushDatabaseBuffers\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eOid\u003c/span\u003e \u003cspan class=\"n\"\u003edbid\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eBufmgrCommit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nf\"\u003eBgBufferSync\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 2.4 删除关联buffer */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eDropRelFileNodeBuffers\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelFileNodeBackend\u003c/span\u003e \u003cspan class=\"n\"\u003ernode\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eForkNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eforkNum\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003efirstDelBlock\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eDropRelFileNodesAllBuffers\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelFileNodeBackend\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ernodes\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ennodes\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eDropDatabaseBuffers\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eOid\u003c/span\u003e \u003cspan class=\"n\"\u003edbid\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 2.5 锁buffer */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eUnlockBuffers\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eLockBuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003emode\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nf\"\u003eConditionalLockBuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eLockBufferForCleanup\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nf\"\u003eConditionalLockBufferForCleanup\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nf\"\u003eHoldingBufferPinThatDelaysRecovery\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"13-buffer调用\"\u003e1.3 buffer调用\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003e插入数据\u003c/strong\u003e\u003c/p\u003e","title":"PostgreSQL 3-3 Buffer"},{"content":"5 wal落盘 WalWriterMain for :: XLogBackgroundFlush LWLockAcquire(LW_EXCLUSIVE) XLogWrite LWLockRelease() CommitTransaction RecordTransactionCommit BufmgrCommit XactLogCommitRecord # xlog记录commit TransactionTreeSetCommitTsData XLogFlush(XactLastRecEnd) for :: WaitXLogInsertionsToFinish XLogWrite write ResourceOwnerRelease AtEOXact_Buffers AtEOXact_RelationCache ... 1 概述 1.1 背景 https://zhmin.github.io/posts/postgresql-wal-format/\nwal机制解决的问题：持久性、原子性、性能、数据同步、恢复\n持久性需求：\n执行一次事务/事务块，例如INSERT语句，除了要写数据文件，还需要更新系统表、索引文件、fsm文件、vm文件、事务提交文件等\n为避免故障导致数据丢失，产生的数据写入磁盘才算事务成功\n应用 数据库 磁盘 | 1. INSERT (5) --\u0026gt; | | 2. 读取数据页 \u0026lt;-- | | 3. 将数据写入数据页 | 4. 存储数据页 --\u0026gt; | | 5. 读取索引文件 --\u0026gt; | | 6... | 7. 读取fsm文件 --\u0026gt; | | 8... | 9. 读取vm文件 --\u0026gt; | | 10... | 11. INSERT 成功 \u0026lt;-- | 原子性需求：\n大量连续读写可能会失败，如果中途失败，无法恢复现场 性能需求：\n首先，执行一次事务或事务块，涉及大量IO操作，且都是随机读写 数据同步：\n主机和备机之间数据同步问题 恢复\n故障恢复 时间点恢复 1.2 解决方案 lsn\n-- 查看当前lsn SELECT pg_current_wal_lsn(); -- 查看当前lsn的文件名 SELECT pg_walfile_namae(pg_current_wal_lsn()); SELECT pg_walfile_name_offset(pg_current_wal_lsn()); -- 查看你page的lsn SELECT lsn FROM page_header(get_raw_page(\u0026#39;t1\u0026#39;, 0)); wal文件命令：24个字符，每个字符为16进制\n00000000 00000000 00000000 时间线 逻辑id 物理id http://dbaselife.com/doc/1955/\n1.1 格式 通用的xlog记录格式 (pg 9.5+)\n+---------------------------------+ | XLogRecord | +---------------------------------+ 设置对应flag则有BlockHeader，否则没有 | XlogRecordBlockHeader | 设置flag | XLogRecordBlockImageHeader | - if BKPBLOCK_HAS_IMAGE | XLogRecordBlockCompressHeader | - if BKPBLOCK_HAS_HOLE \u0026amp; BKPIMAGE_IS_COMPRESSED | RelFileNode | - if not BKPBLOCK_SAME_REL | XlogRecordBlockHeader | | ... | +---------------------------------+ | XlogRecordDataHeader | Short/Long (判断条件：长度 \u0026lt; 256 bytes) +---------------------------------+ | block data | | block data | | ... | | data | +---------------------------------+ 各字段结构体定义\n/* 1 */ typedef struct { uint32 xl_tot_len; /* 本条xlgo记录全部长度 */ TransactionId xl_xid; XLogRecPtr xl_prev; /* 上一条xlog记录的位置 */ uint8\txl_info; /* 资管管理器使用，判断调用哪个重放函数 */ RmgrId\txl_rmid; /* 资源管理器 */ pg_crc32c\txl_crc;\t/* 本条xlog记录的crc */ } XLogRecord; /* 2 */ typedef struct { uint8\tid;\t/* block reference id */ uint8\tfork_flags; uint16\tdata_length; /* 数据实际长度，不包括image */ /* If BKPBLOCK_HAS_IMAGE, an XLogRecordBlockImageHeader struct follows */ /* If BKPBLOCK_SAME_REL is not set, a RelFileNode follows */ /* BlockNumber follows */ } XLogRecordBlockHeader; /* 其中，根据fork_flags，判断是否有其他BlockHeader */ #define BKPBLOCK_HAS_IMAGE\t0x10\t/* block data is an XLogRecordBlockImage */ #define BKPBLOCK_HAS_DATA\t0x20 #define BKPBLOCK_WILL_INIT\t0x40\t/* redo will re-init the page */ #define BKPBLOCK_SAME_REL\t0x80\t/* RelFileNode omitted, same as previous */ typedef struct { uint16\tlength;\t/* number of page image bytes */ uint16\thole_offset;\t/* number of bytes before \u0026#34;hole\u0026#34; */ uint8\tbimg_info;\t/* flag bits, see below */ } XLogRecordBlockImageHeader; typedef struct { uint16\thole_length; /* number of bytes in \u0026#34;hole\u0026#34; : page中没有数据的tup就是孔 */ } XLogRecordBlockCompressHeader; /* 3 */ typedef struct { uint8\tid;\t/* XLR_BLOCK_ID_DATA_SHORT */ uint8\tdata_length;\t/* number of payload bytes */ } XLogRecordDataHeaderShort; typedef struct { uint8\tid;\t/* XLR_BLOCK_ID_DATA_LONG */ } XLogRecordDataHeaderLong; /* 其中，id的取值包括 */ #define XLR_MAX_BLOCK_ID\t32 #define XLR_BLOCK_ID_DATA_SHORT\t255 #define XLR_BLOCK_ID_DATA_LONG\t254 #define XLR_BLOCK_ID_ORIGIN\t253 1.2 插入顺序 XLogBeginInsert() /* 检查受否在故障恢复 */ XLogRegisterData(data, datasz) /* */ XLogRecPtr XLogInsert(RmgrId rmid, uint8 info) XLogFlush(XLogRecPtr record) heap_insert\n/* 结构体：输入 */ typedef struct { uint32 t_len; ItemPointerData t_self; Oid t_tableOid; HeapTupleHeader t_data; } HeapTuple; /* 输出 */ typedef struct { OffsetNumber offnum; uint8 flags; } xl_heap_insert; typedef struct { uint16 t_infomask2; uint16 t_infomask uint8 t_hoff; } xl_heap_header; /* 执行流程 */ HeapTuple tup; xl_heap_insert xlrec; xl_heap_header xlhdr; uint8 info = XLOG_HEAP_INSERT; int bufflags = 0; XLogRecPtr recptr; xlrec.offnum = tup.t_self.offset; xlrec.flag = 0; /* if page XLH_INSERT_ALL_VISIBLE_CLEARED XLH_INSERT_IS_SPECULATIVE */ xlhdr.t_infomask2 = tup-\u0026gt;t_data-\u0026gt;t_infomask2; xlhdr.t_infomask = tup-\u0026gt;t_data-\u0026gt;t_infomask; xlhdr.t_hoff = tup-\u0026gt;t_data-\u0026gt;t_hoff; XLogBeginInsert() /* put tup place */ XLogRegisterData(\u0026amp;xlrec, sizeof(xlrec)); /* put buffer where tup come from */ XLogRegisterBuffer(0, buffer, bufflags | REGBUF_STANDARD); /* put tup */ XLogRegisterBufData(0, \u0026amp;xlhdr, sizeof(xlhdr)); XLogRegisterBufData(0, tup-\u0026gt;t_data + sizeof(HeapTupleHeader), tup-\u0026gt;t_len - sizeof(HeapTupleHeader)); XLogIncludeOrigin(); recptr = XLogInsert(RM_HEAP_ID, info); PageSetLSN(page, recptr); 内部实现：\ntypedef struct XlogRecData { struct XlogRecData *next; char *data; uint32 len; } XLogRecData; /* 进程级全局变量： +-------------+-------------+-------------+ | XLogRecData | XLogRecData | ... | +-------------+-------------+-------------+ ^ last */ XLogRecData *rdatas; /* XLogRecData 数组, len = 20 */ int num_rdatas; int max_rdatas; XLogRecData *mainrdata_head; XLogRecData *mainrdata_last; uint32 mainrdata_len; /* chain中的数据总长度 */ XLogRegisterData(data, len) XLogRecData *rdata = rdatas[num_rdatas++]; /* global arr */ rdata-\u0026gt;data = data; rdata-\u0026gt;len = len; mainrdata_last-\u0026gt;next = rdata; mainrdata_last = rdata; mainrdata_len += len; typedef struct { bool in_use; uint8 flags; RelFileNode rnode; ForkNumber\tforkno; BlockNumber block; Page\tpage; uint32\trdata_len; /* total length of data in rdata chain */ XLogRecData *rdata_head; XLogRecData *rdata_tail; XLogRecData bkp_rdatas[2]; /* temporary rdatas */ char compressed_page[8192 + 4]; } registered_buffer; /* 进程级全局变量： +-------------------+-------------------+-------------+ | registered_buffer | registered_buffer | ... | +-------------------+-------------------+-------------+ |-\u0026gt; rdata -\u0026gt; rdata |-\u0026gt; ... */ registered_buffer *registered_buffers; /* len = 4 + 1, may realloc */ int max_registered_buffers; int max_registered_block_id = 4 + 1; XLogRegisterBuffer(block_id, buffer, flags) /* block_id = 0 */ max_registered_block_id += (block_id \u0026gt;= max_registered_block_id) ? 1 : 0; registered_buffer regbuf = \u0026amp;registered_buffers[block_id]; /* global arr */ BufferGetTag(buffer, \u0026amp;regbuf-\u0026gt;rnode, \u0026amp;regbuf-\u0026gt;forkno, \u0026amp;regbuf-\u0026gt;block); regbuf-\u0026gt;page = BufferGetPage(buffer); regbuf-\u0026gt;flags = flags; regbuf-\u0026gt;rdata_tail = (XLogRecData *) \u0026amp;regbuf-\u0026gt;rdata_head; regbuf-\u0026gt;rdata_len = 0; regbuf-\u0026gt;in_use = true; XLogRegisterBufData(block_id, data, len) XLogRecData *rdata = \u0026amp;rdatas[num_rdatas++]; /* global arr */ rdata-\u0026gt;data = data; rdata-\u0026gt;len = len; registered_buffer *regbuf = \u0026amp;registered_buffers[block_id]; /* global arr */ regbuf-\u0026gt;rdata_tail-\u0026gt;next = rdata; regbuf-\u0026gt;rdata_tail = rdata; regbuf-\u0026gt;rdata_len += len; typedef uint64 XLogRecPtr; /* 进程全局变量 */ XLogRecPtr RedoRecPtr; bool doPageWrites; /* 1 */ XLogInsert(rmid, info) XLogRecPtr\tfpw_lsn; XLogRecData rdt = XLogRecordAssemble(rmid, info, RedoRecPtr, doPageWrites, \u0026amp;fpw_lsn) /* 封装头部 */ XLogRecPtr EndPos = XLogInsertRecord(rdt, fpw_lsn); /* 封装数据 */ return EndPos; /* 即 page lsn */ XLogRecData hdr_rdt; /* 把所有buffer里和buffer外的所有list merge在一起 */ char *hdr_scratch = NULL; /* 把所有buffer里和buffer外的所有数据拼接在一起 */ /* 1.1 */ XLogRecData *XLogRecordAssemble(rmid, info, RedoRecPtr, doPageWrites, fpw_lsn) char\t*scratch = hdr_scratch; XLogRecord *rechdr = (XLogRecord)scratch; scratch += sizeof(XLogRecord); hdr_rdt.next = NULL; XLogRecData *rdt_datas_last = \u0026amp;hdr_rdt; hdr_rdt.data = hdr_scratch; /* 处理buffer */ registered_buffer *prev_regbuf = NULL; for (block_id = 0; block_id \u0026lt; max_registered_block_id; block_id++) { registered_buffer *regbuf = \u0026amp;registered_buffers[block_id] if !regbuf-\u0026gt;in_use: continue; if regbuf-\u0026gt;flags \u0026amp; REGBUF_FORCE_IMAGE： needs_backup = true else： XLogRecPtr\tpage_lsn = PageGetLSN(regbuf-\u0026gt;page); if *fpw_lsn == InvalidXLogRecPtr || page_lsn \u0026lt; *fpw_lsn: *fpw_lsn = page_lsn; if regbuf-\u0026gt;rdata_len == 0: needs_data = false; XLogRecordBlockHeader bkpb; bkpb.id = block_id; bkpb.fork_flags = regbuf-\u0026gt;forkno; bkpb.data_length = 0; if regbuf-\u0026gt;flags \u0026amp; REGBUF_WILL_INIT: bkpb.fork_flags |= BKPBLOCK_WILL_INIT; if needs_backup: TODO if needs_data: bkpb.fork_flags |= BKPBLOCK_HAS_DATA; bkpb.data_length = regbuf-\u0026gt;rdata_len; total_len += regbuf-\u0026gt;rdata_len; rdt_datas_last-\u0026gt;next = regbuf-\u0026gt;rdata_head; rdt_datas_last = regbuf-\u0026gt;rdata_tail; if prev_regbuf \u0026amp;\u0026amp; regbuf-\u0026gt;rnode == prev_regbuf-\u0026gt;rnode: samerel = true; bkpb.fork_flags |= BKPBLOCK_SAME_REL; else: samerel = false; prev_regbuf = regbuf; memcpy(scratch, \u0026amp;bkpb, sizeof(XLogRecordBlockHeader)); scratch += sizeof(XLogRecordBlockHeader); if (!samerel): memcpy(scratch, \u0026amp;regbuf-\u0026gt;rnode, sizeof(RelFileNode)); scratch += sizeof(RelFileNode); memcpy(scratch, \u0026amp;regbuf-\u0026gt;block, sizeof(BlockNumber)); scratch += sizeof(BlockNumber); } if (mainrdata_len \u0026gt; 0) if (mainrdata_len \u0026gt; 255) *(scratch++) = XLR_BLOCK_ID_DATA_LONG; /* 255 */ memcpy(scratch, \u0026amp;mainrdata_len, sizeof(uint32)); scratch += sizeof(uint32); else: *(scratch++) = XLR_BLOCK_ID_DATA_SHORT; /* 254 */ *(scratch++) = (uint8) mainrdata_len; rdt_datas_last-\u0026gt;next = mainrdata_head; rdt_datas_last = mainrdata_last; total_len += mainrdata_len; rdt_datas_last-\u0026gt;next = NULL; hdr_rdt.len = (scratch - hdr_scratch); total_len += hdr_rdt.len; COMP_CRC32C(rdata_crc, hdr_scratch + sizeof(XLogRecord), hdr_rdt.len - sizeof(XLogRecord)); for (rdt = hdr_rdt.next; rdt != NULL; rdt = rdt-\u0026gt;next) COMP_CRC32C(rdata_crc, rdt-\u0026gt;data, rdt-\u0026gt;len); rechdr-\u0026gt;xl_xid = GetCurrentTransactionIdIfAny(); rechdr-\u0026gt;xl_tot_len = total_len; rechdr-\u0026gt;xl_info = info; rechdr-\u0026gt;xl_rmid = rmid; rechdr-\u0026gt;xl_prev = InvalidXLogRecPtr; rechdr-\u0026gt;xl_crc = rdata_crc; return \u0026amp;hdr_rdt; /* 1.2 */ XLogRecPtr XLogInsertRecord(XLogRecData rdata, XLogRecPtr fpw_lsn) XLogCtlInsert *Insert = \u0026amp;XLogCtl-\u0026gt;Insert; XLogRecord *rechdr = (XLogRecord *) rdata-\u0026gt;data; isLogSwitch = rechdr-\u0026gt;xl_rmid == RM_XLOG_ID \u0026amp;\u0026amp; rechdr-\u0026gt;xl_info == XLOG_SWITCH if isLogSwitch: WALInsertLockAcquireExclusive() else: WALInsertLockAcquire() if RedoRecPtr != Insert-\u0026gt;RedoRecPtr: RedoRecPtr = Insert-\u0026gt;RedoRecPtr; doPageWrites = Insert-\u0026gt;fullPageWrites || Insert-\u0026gt;forcePageWrites; XLogRecPtr\tStartPos; XLogRecPtr\tEndPos; if isLogSwitch: insert = ReserveXLogSwitch(\u0026amp;StartPos, \u0026amp;EndPos, \u0026amp;rechdr-\u0026gt;xl_prev) else: ReserveXLogInsertLocation(rechdr-\u0026gt;xl_tot_len, \u0026amp;StartPos, \u0026amp;EndPos, \u0026amp;rechdr-\u0026gt;xl_prev) inserted = true if inserted: CopyXLogRecordToWAL(rechdr-\u0026gt;xl_tot_len, isLogSwitch, rdata, StartPos, EndPos) /* 封装实际数据 */ WALInsertLockRelease(); MarkCurrentTransactionIdLoggedIfAny(); /* Update shared LogwrtRqst.Write, if we crossed page boundary */ if StartPos / XLOG_BLCKSZ != EndPos / XLOG_BLCKSZ: if XLogCtl-\u0026gt;LogwrtRqst.Write \u0026lt; EndPos: XLogCtl-\u0026gt;LogwrtRqst.Write = EndPos; /* 更新所有进程的xlog写入位置 */ LogwrtResult = XLogCtl-\u0026gt;LogwrtResult; if isLogSwitch: XLogFlush(EndPos) TODO ProcLastRecPtr = StartPos; XactLastRecEnd = EndPos; /* 1.2.1 */ CopyXLogRecordToWAL(int write_len, XLogRecData *rdata, XLogRecPtr StartPos, XLogRecPtr EndPos) char *currpos = StartPos currpos = GetXLogBuffer(CurrPos) freespace = INSERT_FREESPACE(CurrPos) while (rdata != NULL) char *rdata_data = rdata-\u0026gt;data int rdata_len = rdata-\u0026gt;len while (rdata_len \u0026gt; freespace) memcpy(currpos, rdata_data, freespace) rdata_data += freespace rdata_len -= freespace written += freespace CurrPos += freespace currpos = GetXLogBuffer(CurrPos) ... memcpy(currpos, rdata_data, rdata_len) ... if isLogSwitch while (CurrPos \u0026lt; EndPos) WALInsertLockUpdateInsertingAt(CurrPos) AdvanceXLInsertBuffer(CurrPos) 1.4 log page log_newpage_buffer() 2 xlog重放 XLogReaderState *xlogreader = XLogReaderAllocate(); XLogRecord record = ReadRecord(xlogreader); do { RmgrTable[record-\u0026gt;xl_rmid].rm_redo(xlogreader); record = ReadRecord(xlogreader); } heap_redo(XLogReaderState *record) uint8 info = XLogRecGetInfo(record) \u0026amp; ~XLR_INFO_MASK; switch info \u0026amp; XLOG_HEAP_OPMASK: case XLOG_HEAP_INSERT: heap_xlog_insert(record) case XLOG_HEAP_DELETE: TODO heap_xlog_insert(XLogReaderState *record) XLogRecPtr\tlsn = record-\u0026gt;EndRecPtr; RelFileNode target_node; XLogRecGetBlockTag(record, 0, \u0026amp;target_node, NULL, \u0026amp;blkno); /* set tup\u0026#39;s offset */ ItemPointerData target_tid; ItemPointerSetBlockNumber(\u0026amp;target_tid, blkno); ItemPointerSetOffsetNumber(\u0026amp;target_tid, xlrec-\u0026gt;offnum); xl_heap_insert *xlrec = (xl_heap_insert *) XLogRecGetData(record); if XLogRecGetInfo(record) = XLOG_HEAP_INIT_PAGE buffer = XLogInitBufferForRedo(record) page = BufferGetPage(buffer) PageInit(page) else action = XLogReadBufferForRedo(record, \u0026amp;buffer) // 1 插入阶段 heap_insert() LogBeginInsert() XLogRegisterData(data, datasz) XLogRegisterBuffer(0, buffer, bufflags) XLogRegisterBufData0(0, data, datasz) XLogRegisterBufData(o, data, datasz) XLogIncludeOrigin() XLogRecPtr = XLogInsert(RM_HEAP_ID, XLOG_HEAP_INSERT | XLOG_HEAP_INIT_PAGE) // 2 组装阶段 - 调用assemble XLogInsert() XLogRecPtr RedoRecPtr XLogRecPtr fpw_lsn GetFullPageWriteInfo(\u0026amp;RedoRecPtr) XLogRecData *tdt = XLogRecordAssemble(rmid, info, doPageWrites, \u0026amp;fpw_lsn) XLogRecPtr EndPos = XLogInsertRecord(rdt, fpw_lsn) // assemble 返回值 typedef struct XLogRecData { struct XLogRecData *next; char *data; uint32 len; } XLogRecData; /* 物理xlog：header + main的list */ typedef uint64 XLogRecPtr; // 物理xlog的头部 typedef struct XLogRecord { uint32 xl_tot_len; TransactionId xl_xid; XLogRecPtr xl_prev; /* 前一条物理xlog */ uint8 xl_info; RmgrId xl_rmid; pg_crc32c xl_crc; } XLogRecord; // 2.1 assemble 组装 XLogRecData *XLogRecordAssemble(rmid, info, doPageWrites) /* RM_HEAP_ID, XLOG_HEAP_INSERT | XLOG_HEAP_INIT_PAGE */ for (block_id = 0; block_id \u0026lt; max_registered_block_id; block_id++) { // 1 依次获取 block / buffer registered_buffer *regbuf = \u0026amp;registered_buffers[block_id] // 2 判断是否写 full-page if : ... else: XLogRecPtr page_lsn = PageGetLSN(regbuf-\u0026gt;page) needs_backup = (page_lsn \u0026lt;= RedoRecPtr) // page的lsn小于xlog的lsn // 3 构造 BlockHeader XLogRecordBlockHeader bkpb bkpb.id = block_id bkpb.fork_flags = regbuf-\u0026gt;forkno if regbuf-\u0026gt;flags \u0026amp; REGBUF_WILL_INIT: bkpb.fork_flags |= BKPBLOCK_WILL_INIT // 4 拼接 page image if needs_backup: // header后紧跟page imge Page page = regbuf-\u0026gt;page if regbuf-\u0026gt;flags \u0026amp; REGBUF_STANDARD: // 计算孔洞 bimg.hole_offset = lower cbimg.hole_length = upper - lower if wal_compression: // 压缩page is_compressed = XLogCompressBackupBlock(page, bimg.hole_offset, cbimg.hole_length, regbuf-\u0026gt;compressed_page, \u0026amp;compressed_len) bkpb.fork_flags |= BKPBLOCK_HAS_IMAGE if is_compressed: // 物理数据 | XLogRecord--BlockNumber | regbuf-\u0026gt;compressed_page else: bimg.length = BLCKSZ - cbimg.hole_length if cbimg.hole_length == 0 // 物理数据 | XLogRecord--BlockNumber | regbuf-\u0026gt;page rdt_datas_last-\u0026gt;data = page rdt_datas_last-\u0026gt;len = BLCKSZ else: // page分成两部分存：page起始到hole起始，hole结束到page结束 // 物理数据 | XLogRecord--BlockNumber | regbuf-\u0026gt;page--hole_offset | regbuf-\u0026gt;page--hole_offset--hole_length | // 5 拼接 tuple data if needs_data: // // 物理数据 | XLogRecord--BlockNumber | regbuf-\u0026gt;page | data1 | data2 | ... | bkpb.fork_flags |= BKPBLOCK_HAS_DATA bkpb.data_length = regbuf-\u0026gt;rdata_len rdt_datas_last-\u0026gt;next = regbuf-\u0026gt;rdata_head rdt_datas_last = regbuf-\u0026gt;rdata_tail // 6 继续填充 BlockHeader if prev_regbuf \u0026amp;\u0026amp; RelFileNodeEquals(regbuf-\u0026gt;rnode, prev_regbuf-\u0026gt;rnode): samerel = true bkpb.fork_flags |= BKPBLOCK_SAME_REL prev_regbuf = regbuf // 物理数据：| XLogRecord XLogRecordBlockHeader | regbuf-\u0026gt;page | ... memcpy(scratch, \u0026amp;bkpb, sizeof(XLogRecordBlockHeader)) // 7 继续填充 if needs_backup: // 物理数据：| XLogRecord XLogRecordBlockHeader XLogRecordBlockImageHeader | regbuf-\u0026gt;page | ... memcpy(scratch, \u0026amp;bimg, sizeof(XLogRecordBlockImageHeader)) if cbimg.hole_length != 0 \u0026amp;\u0026amp; is_compressed: // 物理数据：| XLogRecord XLogRecordBlockHeader XLogRecordBlockImageHeader XLogRecordBlockCompressHeader | regbuf-\u0026gt;page | ... memcpy(scratch, \u0026amp;cbimg, sizeof(XLogRecordBlockCompressHeader)) if samerel: // 物理数据：| XLogRecord XLogRecordBlockHeader XLogRecordBlockImageHeader XLogRecordBlockCompressHeader RelFileNode | regbuf-\u0026gt;page | ... memcpy(scratch, \u0026amp;regbuf-\u0026gt;rnode, sizeof(RelFileNode)) /* * 物理数据：（list的第一个node） * | XLogRecord * | XLogRecordBlockHeader -----------+ 可能重复多次 * | XLogRecordBlockImageHeader | * | XLogRecordBlockCompressHeader | * | RelFileNode | * | BlockNumber ----------------------+ * | ... 重复 */ memcpy(scratch, \u0026amp;regbuf-\u0026gt;block, sizeof(BlockNumber)) } // 结束遍历 Block /* * 物理数据：（list的第一个node） * | XLogRecord * | XLogRecordBlockHeader -----------+ 可能重复多次 * | XLogRecordBlockImageHeader | * | XLogRecordBlockCompressHeader | * | RelFileNode | * | BlockNumber ----------------------+ * | ... 重复 * | XLR_BLOCK_ID_ORIGIN * | replorigin_session_origin (uint16) * | XLR_BLOCK_ID_DATA_SHORT * | mainrdata_len */ if include_origin \u0026amp;\u0026amp; replorigin_session_origin: *(scratch++) = XLR_BLOCK_ID_ORIGIN memcpy(scratch, \u0026amp;replorigin_session_origin, sizeof(replorigin_session_origin)) // 4 拼接 maindata /* * [XLogRecord-...-BlockNumber] -\u0026gt; [page1] -\u0026gt; [page2]-\u0026gt; [page1 data1] -\u0026gt; [page2 data2] -\u0026gt; [maindata] -\u0026gt; [maindata] -\u0026gt; [...] */ if mainrdata_len \u0026gt; 0 : *(scratch++) = XLR_BLOCK_ID_DATA_LONG / XLR_BLOCK_ID_DATA_SHORT memcpy(scratch, \u0026amp;mainrdata_len, sizeof(uint32)) rdt_datas_last-\u0026gt;next = mainrdata_head rdt_datas_last = mainrdata_last xlog完整格式\n# 物理xlog | list 节点 | 是否必选 描述 +-------------------------------+---+----------------------------------------------------------------- | XLogRecord | Y | | \u0026lt;\u0026lt; loop start \u0026gt;\u0026gt; | - | | XLogRecordBlockHeader | N | 有page时 {id, fork_flags, data_length} : INIT_PAGE HAS_IMAGE HAS_DATA | XLogRecordBlockImageHeader | N | 有page时，写入full-page镜像 | XLogRecordBlockCompressHeader | N | 有page时，写入full-page镜像，开启压缩 | RelFileNode | N | 有page时 | BlockNumber | N | 有page时 | \u0026lt;\u0026lt; loop end \u0026gt;\u0026gt; | - | | XLR_BLOCK_ID_ORIGIN | N | | replorigin_session_origin | N | | XLR_BLOCK_ID_DATA_SHORT/LONG | N | 有maindata时（可能有误） | mainrdata_len | N | 有maindata时 +-------------------------------|---|----------------------------------------------------------------- | page start -- hole start | N | 有page时，写入full-page镜像 +-------------------------------|---|----------------------------------------------------------------- | hole end -- page end | N | +-------------------------------|---|----------------------------------------------------------------- | block1_data1 | N | xl_heap_header {t_infomask2, t_infomask, t_hoff} : 记录tuple信息 +-------------------------------|---|----------------------------------------------------------------- | block1_data2 | N | tuple-\u0026gt;t_data : 记录tuple数据 +-------------------------------|---|----------------------------------------------------------------- | block2_data1 | N | +-------------------------------|---|----------------------------------------------------------------- | block... | N | +-------------------------------|---|----------------------------------------------------------------- | maindata1 | N | xl_heap_insert {OffsetNumber, flags} ： 记录tuple位置 +-------------------------------|---|----------------------------------------------------------------- | maindata2 | N | +-------------------------------|---|----------------------------------------------------------------- | maindata... | N | +-------------------------------|---|----------------------------------------------------------------- /* symbol name, textual name, redo, desc, identify, startup, cleanup */ PG_RMGR(RM_XLOG_ID, \u0026#34;XLOG\u0026#34;, xlog_redo, xlog_desc, xlog_identify, NULL, NULL) PG_RMGR(RM_XACT_ID, \u0026#34;Transaction\u0026#34;, xact_redo, xact_desc, xact_identify, NULL, NULL) PG_RMGR(RM_SMGR_ID, \u0026#34;Storage\u0026#34;, smgr_redo, smgr_desc, smgr_identify, NULL, NULL) PG_RMGR(RM_CLOG_ID, \u0026#34;CLOG\u0026#34;, clog_redo, clog_desc, clog_identify, NULL, NULL) PG_RMGR(RM_DBASE_ID, \u0026#34;Database\u0026#34;, dbase_redo, dbase_desc, dbase_identify, NULL, NULL) PG_RMGR(RM_TBLSPC_ID, \u0026#34;Tablespace\u0026#34;, tblspc_redo, tblspc_desc, tblspc_identify, NULL, NULL) PG_RMGR(RM_MULTIXACT_ID, \u0026#34;MultiXact\u0026#34;, multixact_redo, multixact_desc, multixact_identify, NULL, NULL) PG_RMGR(RM_RELMAP_ID, \u0026#34;RelMap\u0026#34;, relmap_redo, relmap_desc, relmap_identify, NULL, NULL) PG_RMGR(RM_STANDBY_ID, \u0026#34;Standby\u0026#34;, standby_redo, standby_desc, standby_identify, NULL, NULL) PG_RMGR(RM_HEAP2_ID, \u0026#34;Heap2\u0026#34;, heap2_redo, heap2_desc, heap2_identify, NULL, NULL) PG_RMGR(RM_HEAP_ID, \u0026#34;Heap\u0026#34;, heap_redo, heap_desc, heap_identify, NULL, NULL) PG_RMGR(RM_BTREE_ID, \u0026#34;Btree\u0026#34;, btree_redo, btree_desc, btree_identify, NULL, NULL) PG_RMGR(RM_HASH_ID, \u0026#34;Hash\u0026#34;, hash_redo, hash_desc, hash_identify, NULL, NULL) PG_RMGR(RM_GIN_ID, \u0026#34;Gin\u0026#34;, gin_redo, gin_desc, gin_identify, gin_xlog_startup, gin_xlog_cleanup) PG_RMGR(RM_GIST_ID, \u0026#34;Gist\u0026#34;, gist_redo, gist_desc, gist_identify, gist_xlog_startup, gist_xlog_cleanup) PG_RMGR(RM_SEQ_ID, \u0026#34;Sequence\u0026#34;, seq_redo, seq_desc, seq_identify, NULL, NULL) PG_RMGR(RM_SPGIST_ID, \u0026#34;SPGist\u0026#34;, spg_redo, spg_desc, spg_identify, spg_xlog_startup, spg_xlog_cleanup) PG_RMGR(RM_BRIN_ID, \u0026#34;BRIN\u0026#34;, brin_redo, brin_desc, brin_identify, NULL, NULL) PG_RMGR(RM_COMMIT_TS_ID, \u0026#34;CommitTs\u0026#34;, commit_ts_redo, commit_ts_desc, commit_ts_identify, NULL, NULL) PG_RMGR(RM_REPLORIGIN_ID, \u0026#34;ReplicationOrigin\u0026#34;, replorigin_redo, replorigin_desc, replorigin_identify, NULL, NULL) 2.1 HEAP #define XLOG_HEAP_INSERT\t0x00 #define XLOG_HEAP_DELETE\t0x10 #define XLOG_HEAP_UPDATE\t0x20 /* 0x030 is free, was XLOG_HEAP_MOVE */ #define XLOG_HEAP_HOT_UPDATE\t0x40 #define XLOG_HEAP_CONFIRM\t0x50 #define XLOG_HEAP_LOCK\t0x60 #define XLOG_HEAP_INPLACE\t0x70 #define XLOG_HEAP_OPMASK\t0x70 #define XLOG_HEAP_INIT_PAGE\t0x80 2.2 HEAP2 #define XLOG_HEAP2_REWRITE\t0x00 #define XLOG_HEAP2_CLEAN\t0x10 #define XLOG_HEAP2_FREEZE_PAGE\t0x20 #define XLOG_HEAP2_CLEANUP_INFO 0x30 #define XLOG_HEAP2_VISIBLE\t0x40 #define XLOG_HEAP2_MULTI_INSERT 0x50 #define XLOG_HEAP2_LOCK_UPDATED 0x60 #define XLOG_HEAP2_NEW_CID\t0x70 2.3 XLOG #define XLOG_CHECKPOINT_SHUTDOWN\t0x00 #define XLOG_CHECKPOINT_ONLINE\t0x10 #define XLOG_NOOP\t0x20 #define XLOG_NEXTOID\t0x30 #define XLOG_SWITCH\t0x40 #define XLOG_BACKUP_END\t0x50 #define XLOG_PARAMETER_CHANGE\t0x60 #define XLOG_RESTORE_POINT\t0x70 #define XLOG_FPW_CHANGE\t0x80 #define XLOG_END_OF_RECOVERY\t0x90 #define XLOG_FPI_FOR_HINT\t0xA0 #define XLOG_FPI\t0xB0 2.4 RM_SMGR_ID ```c\n#define XLOG_SMGR_CREATE 0x10\n#define XLOG_SMGR_TRUNCATE 0x20\n``\n2.5 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/3-5-wal/","summary":"\u003ch1 id=\"5-wal落盘\"\u003e5 wal落盘\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eWalWriterMain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e::\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eXLogBackgroundFlush\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eLWLockAcquire\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eLW_EXCLUSIVE\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eXLogWrite\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eLWLockRelease\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eCommitTransaction\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eRecordTransactionCommit\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eBufmgrCommit\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eXactLogCommitRecord\u003c/span\u003e \u003cspan class=\"c1\"\u003e# xlog记录commit\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eTransactionTreeSetCommitTsData\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eXLogFlush\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eXactLastRecEnd\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e::\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eWaitXLogInsertionsToFinish\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eXLogWrite\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003ewrite\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eResourceOwnerRelease\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eAtEOXact_Buffers\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eAtEOXact_RelationCache\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"o\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"1-概述\"\u003e1 概述\u003c/h1\u003e\n\u003ch2 id=\"11-背景\"\u003e1.1 背景\u003c/h2\u003e\n\u003cp\u003e\u003ca href=\"https://zhmin.github.io/posts/postgresql-wal-format/\"\u003ehttps://zhmin.github.io/posts/postgresql-wal-format/\u003c/a\u003e\u003cbr\u003e\nwal机制解决的问题：持久性、原子性、性能、数据同步、恢复\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e持久性需求：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e执行一次事务/事务块，例如INSERT语句，除了要写数据文件，还需要更新系统表、索引文件、fsm文件、vm文件、事务提交文件等\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e为避免故障导致数据丢失，产生的数据写入磁盘才算事务成功\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e应用                    数据库                  磁盘\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 1. INSERT \u003cspan class=\"o\"\u003e(\u003c/span\u003e5\u003cspan class=\"o\"\u003e)\u003c/span\u003e --\u0026gt;     \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e 2. 读取数据页 \u0026lt;--     \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e 3. 将数据写入数据页\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e 4. 存储数据页  --\u0026gt;    \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e 5. 读取索引文件 --\u0026gt;   \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e 6...\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e 7. 读取fsm文件 --\u0026gt;    \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e 8...\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e 9. 读取vm文件 --\u0026gt;     \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e 10...\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 11. INSERT 成功   \u0026lt;-- \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e原子性需求：\u003c/p\u003e","title":"PostgreSQL 3-7 Xlog"},{"content":"概述 假如，2个会话，并发写入数据：\nBEGIN; INSERT INTO t1 VALUES(1, \u0026#39;data1\u0026#39;); COMMIT; BEGIN; INSERT INTO t1 VALUES(1, \u0026#39;data2\u0026#39;); COMMIT; 加锁逻辑：\nexec_simple_query pg_parse_query pg_analyze_and_rewrite pg_plan_queries PortalStart PortalRun PortalRunMulti ProcessQuery ExecutorStart standard_ExecutorStart InitPlan ExecInitNode ExecInitModifyTable ExecInitResultRelation ExecGetRangeTableRelation table_open(relation, \u0026#39;RowExclusiveLock\u0026#39;) # 8级锁，行级排他锁 relation_open LockRelationOid LockAcquire ExecutorRun standard_ExecutorRun ExecutePlan ... ExecInsert table_tuple_insert heapam_tuple_insert heap_insert RelationGetBufferForTuple LockBuffer LWLockAcquire(buffer, \u0026#39;LW_EXCLUSIVE\u0026#39;) # 读写锁 RelationPutHeapTuple log_heap_insert 锁\nHWLock\n8级 relation, index, buffer 死锁检测 LWLocks buffer SpinLock\nPresicateLock\nHWLock 锁 取值 操作 AccessShareLock 1 SELECT RowShareLock 2 SELECT FOR UPDATE/SHARE RowExclusiveLock 3 INSERT/UPDATE/DELETE ShareUpdateExclusiveLock 4 VACUUM/ANALYZE/CRATE INDEX CONCURRENTLY ShareLock 5 CREATE INDEX ShareRowExclusiveLock 6 row share ExclusiveLock 7 block ROW SHARE/SELECT FOR UPDATE AccessExclusiveLock 8 ALTER TABLE/DROP TABLE/VACUUM FULL LockRelationOid LockAcquireExtended hash_search 所有进程共享\nLWLocks 类似信号量\nLW_SHARED LW_EXCLUSIVE LWLockAcquire 目标 工具/方法 查看当前所有 heavyweight locks SELECT * FROM pg_locks; 查看 LWLock 等待统计 SELECT * FROM pg_stat_activity WHERE wait_event_type = 'LWLock'; 查看 LWLock 累计统计 SELECT * FROM pg_stat_lwlocks; (PG16 新增) 跟踪锁获取/释放 GDB 断点 LockAcquireExtended, LWLockAcquire 分析死锁 日志 deadlock detected + pg_locks 快照 观察 SSI 谓词锁 debug_parallel_query = off + GDB PredicateLockTuple ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/3-6-tans-ai/","summary":"\u003ch1 id=\"概述\"\u003e概述\u003c/h1\u003e\n\u003cp\u003e假如，2个会话，并发写入数据：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;data1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCOMMIT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;data2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCOMMIT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e加锁逻辑：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eexec_simple_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_parse_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_analyze_and_rewrite\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_plan_queries\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ePortalStart\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ePortalRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ePortalRunMulti\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eProcessQuery\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eExecutorStart\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003estandard_ExecutorStart\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eInitPlan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eExecInitNode\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003eExecInitModifyTable\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eExecInitResultRelation\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                        \u003cspan class=\"n\"\u003eExecGetRangeTableRelation\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"n\"\u003etable_open\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelation\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;RowExclusiveLock\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 8级锁，行级排他锁\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"n\"\u003erelation_open\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"n\"\u003eLockRelationOid\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                        \u003cspan class=\"n\"\u003eLockAcquire\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eExecutorRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003estandard_ExecutorRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eExecutePlan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"o\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003eExecInsert\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003etable_tuple_insert\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                        \u003cspan class=\"n\"\u003eheapam_tuple_insert\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"n\"\u003eheap_insert\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"n\"\u003eRelationGetBufferForTuple\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"n\"\u003eLockBuffer\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                        \u003cspan class=\"n\"\u003eLWLockAcquire\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;LW_EXCLUSIVE\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 读写锁\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"n\"\u003eRelationPutHeapTuple\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"n\"\u003elog_heap_insert\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e锁\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eHWLock\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e8级\u003c/li\u003e\n\u003cli\u003erelation, index, buffer\u003c/li\u003e\n\u003cli\u003e死锁检测\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003ch2 id=\"lwlocks\"\u003eLWLocks\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003ebuffer\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eSpinLock\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ePresicateLock\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"hwlock\"\u003eHWLock\u003c/h2\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e锁\u003c/th\u003e\n          \u003cth\u003e取值\u003c/th\u003e\n          \u003cth\u003e操作\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eAccessShareLock\u003c/td\u003e\n          \u003ctd\u003e1\u003c/td\u003e\n          \u003ctd\u003eSELECT\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eRowShareLock\u003c/td\u003e\n          \u003ctd\u003e2\u003c/td\u003e\n          \u003ctd\u003eSELECT FOR UPDATE/SHARE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eRowExclusiveLock\u003c/td\u003e\n          \u003ctd\u003e3\u003c/td\u003e\n          \u003ctd\u003eINSERT/UPDATE/DELETE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eShareUpdateExclusiveLock\u003c/td\u003e\n          \u003ctd\u003e4\u003c/td\u003e\n          \u003ctd\u003eVACUUM/ANALYZE/CRATE INDEX CONCURRENTLY\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eShareLock\u003c/td\u003e\n          \u003ctd\u003e5\u003c/td\u003e\n          \u003ctd\u003eCREATE INDEX\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eShareRowExclusiveLock\u003c/td\u003e\n          \u003ctd\u003e6\u003c/td\u003e\n          \u003ctd\u003erow share\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eExclusiveLock\u003c/td\u003e\n          \u003ctd\u003e7\u003c/td\u003e\n          \u003ctd\u003eblock ROW SHARE/SELECT FOR UPDATE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eAccessExclusiveLock\u003c/td\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003eALTER TABLE/DROP TABLE/VACUUM FULL\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eLockRelationOid\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    LockAcquireExtended\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        hash_search\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e所有进程共享\u003c/p\u003e","title":"PostgreSQL 3-2 Transation (v2)"},{"content":"1 事务的概念 1.1 事务的基本特性 事务的4个特性：\n原子性 Automicity 一致性 Consistency 隔离性 Isolation 持久性 Durability 1.2 事务的隔离性 不同隔离级别下，可能出现的异常如下：（T 表示可能）\n异常 读未提交 读已提交 可重复读 可串行化 解释 脏读 T . . . 读其他事务未提交数据 不可重复读 T T . . 2次读取数据不一致 幻读 T T T . 2次读取数据条数不一致 postgresql默认的隔离级别是读已提交\n-- 查看默认事务隔离级别 show default_transaction_isolation; default_transaction_isolation ------------------------------- read committed -- 查询当前的事务快照 pg 10 SELECT txid_current_snapshot(); txid_current_snapshot ----------------------- 1081:1081: -- 查询所有正在活跃的进程 SELECT * FROM pg_stat_activity; -- 1.3 事务的实现 为实现事务，有3种并发控制机制：\nMVCC: Multi-Version Concurrency Control, 多版本并发控制 S2PL: Strict 2-Phase Lock OCC: Optimistic Concurrency Control 1.4 PostgreSQL的MVCC机制 PostgreSQL对数据的关键操作：\n新增数据：INSERT 修改数据：DELETE、UPDATE 查询数据：SELECT postgresql使用MVCC机制，主要原理如下：\n新增数据 为每个事务分配一个递增的ID 事务生成tuple时，tuple携带事务ID 删除数据 生成事务快照 根据事务快照，判断待删除数据是否可见 事务删除tuple时，tuple携带事务ID 查询数据 生成事务快照 根据tuple时携带的ID，从快照中查询对应事务的提交状态，判断tuple是否可见 | 操作 | 获取快照次数 | 使用快照次数 | 获取事务id次数 |\n|-|-|-|\n| INSERT | 2 | 0 | 1 |\n| UPDATE | 2 | 1 | 1 |\n| DELETE | 2 | 1 | 1 |\n| SELECT | 2 | 1 | 0 |\n# 1 生成事务快照 GetTransactionSnapshot heap_insert GetCurrentTransactionId # 申请事务id heap_delete GetCurrentTransactionId HeapTupleSatisfiesUpdate # 查询提交日志 heap_update GetCurrentTransactionId HeapTupleSatisfiesUpdate # 查询提交日志 heapgettup HeapTupleSatisfiesVisibility # 查询事务快照 HeapTupleSatisfiesMVCC 1.5 判断元组可见性 本博客已2个事务，并发INSERT和DELETE为例，介绍元组可见性判断。\n场景一\n| Time| Trancation 1 (xid=1) | Trancation 2 (xid=2) | tuple state +-----+---------------------------+-----------------------+-------------- | 1 | BEGIN | - | | 2 | INSERT INTO t1 VALUES (1) | - | | 3 | COMMIT | - | | 4 | - | BEGIN | | 5 | - | DELETE FROM t1 | | 6 | - | COMMIT | +-----+---------------------------+-----------------------+-------------- | 1 | BEGIN | - | | 2 | INSERT INTO t1 VALUES (1) | - | | 3 | ROLLBACK | - | | 4 | - | BEGIN | | 5 | - | DELETE FROM t1 | | 6 | - | COMMIT | +-----+---------------------------+-----------------------+-------------- | 1 | BEGIN | - | | 2 | INSERT INTO t1 VALUES (1) | - | | 3 | DELETE FROM t1 | - | | 3 | COMMIT | - | | 4 | - | BEGIN | | 5 | - | DELETE FROM t1 | | 6 | - | COMMIT | +-----+---------------------------+-----------------------+-------------- | 1 | BEGIN | - | | 2 | INSERT INTO t1 VALUES (1) | - | | 3 | DELETE FROM t1 | - | | 3 | COMMIT | - | | 4 | - | BEGIN | | 5 | - | DELETE FROM t1 | | 6 | - | COMMIT | +-----+---------------------------+-----------------------+-------------- | 1 | BEGIN | - | | 2 | INSERT INTO t1 VALUES (1) | - | | 3 | - | BEGIN | | 4 | - | DELETE FROM t1 | | 5 | COMMIT | - | | 6 | - | COMMIT | +-----+---------------------------+-----------------------+-------------- | 1 | BEGIN | - | | 2 | INSERT INTO t1 VALUES (1) | - | | 3 | - | BEGIN | | 4 | - | DELETE FROM t1 | | 5 | COMMIT | - | | 6 | - | COMMIT | 生成新tuple\ntuple xmin = xid xmax = 0 cid = cid infomask = HEAP_XMAX_INVALID 删除Tuple\ntuple cid = cid xmax = xid xmin：写入tup的事务 xmax：删除tup的事务 cid：如果xmax无效，则表示写入tup的SQL语句在事务中的编号。否则，则表示删除tup的SQL语句在事务中的编号。 检查tup可见性，主要从3个方便判断：\n检查xmin，即检查写入tup的事务的状态。xmin事务共有3种状态：已提交、未提交、已回滚或已故障 检查xmax，即检查删除tup的事务的状态。只有xmin事务已提交，才需进一步检查xmax事务。xmax事务共有3种状态：已提交、未提交、已回滚或已故障或不存在（即未有事务尝试删除过） 检查cid，即检查同一事务内修改tup的顺序。只有xmin或xmax事务是本事务，才需要检查cid 所以，检查tup可见性的大致逻辑是：\n先检查xmin事务的状态 如果xmin事务已提交，再检查xmax事务状态 其中，如果xmin事务或xmax事务是本事务，需额外检查cid 检查tup可见性的详细逻辑如下：\nxmin 本事务 已提交 cid小于本command cid大于本command [HeapTupleInvisible] 未提交 已回滚或故障 非本事务 已提交 xmax 本事务 cid小于本command cid大于本command 非本事务 已提交 未提交 已回滚或已故障或不存在 未提交 [HeapTupleInvisible] 已回滚或故障 判断事务的3种状态的方法：\n判断事务未提交： 判断事务已提交： 判断事务已回滚或已故障： 上述描述中，如果每次操作tup时，都需检查commit log来判断事务是否已提交，开销较大。如果操作tup的事务已提交，可以在tup中设置一些标记，下次再检查时，根据标记即可获取事务状态，无需频繁访问commit log。\n以下是我整理的简洁版的tup可见性判断：\n# 阶段一、获取tup状态，先检查tup是否被成功修改 # 如果tup未被成功修改，阶段二再检查本事务是否可见tup if tup.xmin = my.xid: if tup.cid \u0026gt;= my.cid: return HeapTupleInvisible else: if tup.xmin != my.xid return HeapTupleMayBeUpdated else: if tup.cid \u0026gt;= my.cid: # related to scan, remain, not understand return HeapTupleSelfUpdated else: return HeapTupleInvisible else: if tup.xmin.stat = uncommit: # check all process return HeapTupleInvisible elif tup.xmin.stat = commit: # check commit log if tup.xmax = my.xid: if tup.cid \u0026gt;= my.cid: return HeapTupleSelfUpdated else: return HeapTupleInvisible else: if tup.xmax.stat = uncommit: return HeapTupleBeingUpdated else: if tup.xmax.stat = rollback: return HeapTupleMayBeUpdated # tup未被修改，无事务修改tup，或修改的事务已回滚 else: # tup.xmax.stat = commit return HeapTupleUpdated # tup被修改，修改事务已提交 else tup.xmin.stat = rollback: return HeapTupleInvisible # 阶段二，根据tup状态，如果tup未被成功修改， if tup.stat = HeapTupleInvisible: error elif tup.stat = HeapTupleBeingUpdated: if tup.xmax != my.xid: XactLockTableWait 等锁释放 if tup.infomask = HEAP_XMAX_INVALID: tup.stat = HeapTupleMayBeUpdated else: tup.stat = HeapTupleUpdated else: if tup.infomask = HEAP_XMAX_INVALID: tup.stat = HeapTupleMayBeUpdated else: tup.stat = HeapTupleUpdated if tup.stat = HeapTupleMayBeUpdated: if ! check visibility tup, snapshot: tup.stat = HeapTupleUpdated if tup.stat != HeapTupleMayBeUpdated: return tup.cmax = my.xid 检查tuple可见性的几种返回值 HTSU_Result\nHeapTupleMayBeUpdated tup可见，可被更新，没有事务修改过它 HeapTupleInvisible tup 不可见 HeapTupleSelfUpdated tup可见，当前事务已修改过tup HeapTupleUpdated tup可见，修改tup的事务已提交 HeapTupleBeingUpdated tup可见，有事务修改tup，修改它的事务没提交，需等其他事务提交 HeapTupleWouldBlock 如果对元组加锁，当前事务可能会被阻塞 以下是完整版的tup可见性判断：\nHeapTupleSatisfiesUpdate # 阶段一、检查Tuple的写入事务 if !HeapTupleHeaderXminCommitted(tuple): # （快速判断）not tuple-\u0026gt;infomask \u0026amp; HEAP_XMIN_COMMITTED if HeapTupleHeaderXminInvalid: # tuple-\u0026gt;infomask \u0026amp; [HEAP_XMIN_COMMITTED | HEAP_XMIN_INVALID] = HEAP_XMIN_INVALID return HeapTupleInvisible if TransactionIdIsCurrentTransactionId(tuple-\u0026gt;xmin): # Tuple-\u0026gt;xmin 的写入事务 是 本事务 if tuple-\u0026gt;cid \u0026gt;= curcid: # 根据cid判断可见性 return HeapTupleInvisible # 省略，看不懂 elif TransactionIdIsInProgress(tuple-\u0026gt;xmin): # Tuple的写入事务 未提交 return HeapTupleInvisible elif TransactionIdDidCommit(tuple-\u0026gt;xmin): # Tuple的写入事务 已提交（慢速判断，查询事务日志） tuple-\u0026gt;infomask \u0026amp; HEAP_XMIN_COMMITTED else: tuple-\u0026gt;infomask \u0026amp; HEAP_XMIN_INVALID # 未找到Tuple的写入事务的提交日志 return HeapTupleInvisible else: # Tuple的写入事务 已提交 # 阶段二、检查Tuple的删除事务 if tuple-\u0026gt;t_infomask \u0026amp; HEAP_XMAX_INVALID: # 初始状态，并没有事务尝试删除Tuple，INSERT时，t_infomask初始值为HEAP_XMAX_INVALID return HeapTupleMayBeUpdated else: if tuple-\u0026gt;t_infomask \u0026amp; HEAP_XMAX_COMMITTED： # （快速判断）Tuple的删除事务，已提交 return HeapTupleUpdated if tuple-\u0026gt;t_infomask \u0026amp; HEAP_XMAX_IS_MULTI # 暂时忽略 ... if TransactionIdIsCurrentTransactionId(tuple-\u0026gt;xmax): # Tuple的删除事务，是本事务 if tuple-\u0026gt;cid \u0026gt;= curcid: return HeapTupleSelfUpdated # 自己未来删除？ else: return HeapTupleInvisible else; if TransactionIdIsInProgress(tuple-\u0026gt;xmax): # Tuple的删除事务，未提交，（遍历所有正在运行中的线程，判断事务状态） return HeapTupleBeingUpdated else: # 删除Tuple的事务，已提交或发生异常 if not TransactionIdDidCommit(tuple-\u0026gt;xmax)：# Tuple的删除事务，未提交（遍历事务提交日志） tuple-\u0026gt;infomask \u0026amp; HEAP_XMAX_INVALID # 删除Tuple的事务，发生异常了 return HeapTupleMayBeUpdated else: # Tuple的删除事务，已提交 tuple-\u0026gt;infomask \u0026amp; HEAP_XMAX_COMMITTED return HeapTupleUpdated 2 PostgreSQL事务的实现 2.1 INSERT 插入数据时，获取2次快照，获取1次事务id。未用上快照\nexec_simple_query # 1. 简单的初始化 start_xact_command # 2. 对于INSERT/SELECT/UPDATE/DELETE语句，在语义分析之前，都会调用一次GetTransactionSnapshot，来生成一次快照 # 此处的快照，用于语义分析、计划初始化 if analyze_requires_snapshot GetTransactionSnapshot pg_analyze_and_rewrite pg_plan_queries PortalStart PortalRun if PORTAL_MULTI_QUERY: PortalRunMulti # 3. 对于INSERT/DELETE/UPDATE等语法，重新获取最新快照 GetTransactionSnapshot ProcessQuery ExecutorRun ExecutePlan ExecProcNode ExecModifyTable ExecInsert # 4. 调用存储统一接口 heap_insert GetCurrentTransactionId # 5. 获取当前事务的id heap_prepare_insert # 6. 将事务id写入Tuple ... # 7. 继续其他heap_insert操作 2.2 DELETE 插入数据时，获取2次快照，获取1次事务id\nexec_simple_query # 1. 简单的初始化 start_xact_command # 2. 对于INSERT/SELECT/UPDATE/DELETE语句，在语义分析之前，都会调用一次GetTransactionSnapshot，来生成一次快照 # 此处的快照，用于语义分析、计划初始化 if analyze_requires_snapshot GetTransactionSnapshot pg_analyze_and_rewrite pg_plan_queries PortalStart PortalRun if PORTAL_MULTI_QUERY: PortalRunMulti # 3. 对于INSERT/DELETE/UPDATE等语法，重新获取最新快照 GetTransactionSnapshot ProcessQuery ExecutorRun ExecutePlan ExecProcNode ExecModifyTable ExecDelete # 4. 调用存储统一接口 heap_delete GetCurrentTransactionId # 5. 获取当前事务的id # 6 根据提交日志，检查事务可见性 HeapTupleSatisfiesUpdate 2.3 UPDATE 更新数据时，获取2次快照，获取1次事务id\nexec_simple_query # 1. 简单的初始化 start_xact_command # 2. 对于INSERT/SELECT/UPDATE/DELETE语句，在语义分析之前，都会调用一次GetTransactionSnapshot，来生成一次快照 # 此处的快照，用于语义分析、计划初始化 if analyze_requires_snapshot GetTransactionSnapshot pg_analyze_and_rewrite pg_plan_queries PortalStart PortalRun if PORTAL_MULTI_QUERY: PortalRunMulti # 3. 对于INSERT/DELETE/UPDATE等语法，重新获取最新快照 GetTransactionSnapshot ProcessQuery ExecutorRun ExecutePlan ExecProcNode ExecModifyTable ExecUpdate # 4. 调用存储统一接口 heap_update GetCurrentTransactionId # 5. 获取当前事务的id 2.4 SELECT 插入数据时，获取2次快照，未获取事务id\nexec_simple_query # 1. 简单的初始化 start_xact_command # 2. 对于INSERT/SELECT/UPDATE/DELETE语句，在语义分析之前，都会调用一次GetTransactionSnapshot，来生成一次快照 # 此处的快照，用于语义分析、计划初始化 if analyze_requires_snapshot GetTransactionSnapshot pg_analyze_and_rewrite pg_plan_queries # 3. 获取快照 PortalStart GetTransactionSnapshot PortalRun if PORTAL_ONE_SELECT: PortalRunSelect ExecutorRun standard_ExecutorRun ExecutePlan ExecProcNode ExecSeqScan SeqNext # 3. 在heapam层，使用快照 heap_getnext heapgettup HeapTupleSatisfiesVisibility HeapTupleSatisfiesMVCC if !HeapTupleHeaderXminCommitted: XidInMVCCSnapshot(HeapTupleHeaderGetRawXmin(tuple), HeapScanDesc-\u0026gt;rs_snapshot) # tuple 不可见 2.1 分配事务ID 事务ID类型：postgresql使用TransactionId表示事务ID，类型为uint32，简写为xid\n事务Id分配时机：\n场景一：执行INSERT等语句，在写入数据时，才分配事务ID，分配时机如下：\nexec_simple_query PortalRun ProcessQuery ExecutorRun standard_ExecutorRun ExecutePlan ExecProcNode ExecModifyTable ExecInsert heap_insert GetCurrentTransactionId AssignTransactionId TopTransactionStateData-\u0026gt;transactionId GetNewTransactionId /* 获取事务ID */ ExtendCLOG /* 记录事务状态 */ ExtendCommitTs ExtendSUBTRANS XLogInsert(RM_XACT_ID, XLOG_XACT_ASSIGNMENT) 场景二：执行SELECT语句，无需生成事务ID。只需在执行语句时，获取一次所有事务的状态即可（快照），将来的事务不在事务状态内。根据快照判断tuple可读性即可。\n场景三：执行BEGIN语句，并不会立刻分配事务ID，在事务中执行SELECT等也不会分配事务ID。\nexec_simple_query PortalRun PortalRunMulti PortalRunUtility ProcessUtility standard_ProcessUtility BeginTransactionBlock /* do nothing */ 事务ID持久化：在分配事务ID时，会生成xlog记录分配事务ID的操作\n2.2 保存事务状态 事务状态分为2部分：快照记录了所有进程当前处理的事务ID，提交日志记录了所有事务的状态\n2.2.1 事务ID 全局事务ID\nallProcs allPgXact # 记录xid +--------+ +--------+ | PGPROC | --- | PGXACT | +--------+ +--------+ | PGPROC | --- | PGXACT | +--------+ +--------+ | PGPROC | --- | PGXACT | +--------+ +--------+ | ... | --- | ... | +--------+ +--------+ struct PGPROC { ... int pgprocno; ... }; struct PGXACT { TransactionId xid; TransactionId xmin; /* 开始事务时，最小的xid */ ... }; 2.2.2 事务快照 查看当前的事务快照：\nSELECT txid_current_snapshot(); 一、快照的内容\n获取事务快照的函数是GetSnapshotData，该函数会获取所有进程中当前事务的xid\nGetSnapshotData snapshot-\u0026gt;xmax = ShmemVariableCache-\u0026gt;latestCompletedXid for idx in procArray: # 遍历 allPgXact，获取所有xid pgprocno = procArray[idx] PGXACT *pgxact = \u0026amp;allPgXact[pgprocno] xid = pgxact-\u0026gt;xid snapshot-\u0026gt;xip[count++] = xid xin = MIN(xid, xin) snapshot-\u0026gt;xcnt = count snapshot-\u0026gt;xin = xin 二、获取快照的时机\n每执行一条SQL时，都会获取一次快照。获取快照的函数为：GetTransactionSnapshot。\n如果是\nexec_simple_query start_xact_command # 1. 简单的初始化 StartTransactionCommand StartTransaction if analyze_requires_snapshot # 2. 如果分析 INSERT/SELECT/UPDATE/DELETE，需要快照 PushActiveSnapshot(GetTransactionSnapshot) if IsolationUsesXactSnapshot： # XactIsoLevel \u0026gt;= XACT_REPEATABLE_READ return CurrentSnapshot # 3. 如果是可重复读级别及以上，获取旧快照 GetSnapshotData # 4. 如果是读已提交，则获取新快照 xmax for pgprocno in procArray: xip[count++] = allPgXact[pgprocno]-\u0026gt;xid xmin pg_analyze_and_rewrite pg_plan_queries PopActiveSnapshot # 3. 生成计划后，删除分析阶段的快照 PortalStart if PORTAL_ONE_SELECT: PushActiveSnapshot(GetTransactionSnapshot) # 4. 如果是SELECT语句，执行计划初始化阶段，生成快照，并将快照保存在执行计划中 CreateQueryDesc QueryDesc-\u0026gt;snapshot = RegisterSnapshot(GetActiveSnapshot) ExecutorStart standard_ExecutorStart RegisterSnapshot(QueryDesc-\u0026gt;snapshot) PopActiveSnapshot PortalRun if PORTAL_ONE_SELECT: # 5. SELECT语句无需重新获取快照，Scan使用的快照，是第4步生成的 if PORTAL_MULTI_QUERY: PortalRunMulti GetTransactionSnapshot #6. 对于INSERT/DELETE/UPDATE等语法，在执行阶段才获取快照 ProcessQuery 三、使用快照的时机\nexec_simple_query start_xact_command pg_analyze_and_rewrite pg_plan_queries PortalStart if PORTAL_ONE_SELECT: PushActiveSnapshot(GetTransactionSnapshot) # 4. 如果是SELECT语句，执行计划初始化阶段，生成快照，并将快照保存在执行计划中 RegisterSnapshot(GetActiveSnapshot) PopActiveSnapshot PortalRun if PORTAL_ONE_SELECT: PortalRunSelect PushActiveSnapshot(QueryDesc-\u0026gt;snapshot) # 5. SELECT语句无需重新获取快照，Scan使用的快照，是第4步生成的 ExecutorRun standard_ExecutorRun ExecutePlan ExecProcNode ExecSeqScan SeqNext heap_getnext heapgettup HeapTupleSatisfiesVisibility HeapTupleSatisfiesMVCC if !HeapTupleHeaderXminCommitted: XidInMVCCSnapshot(HeapTupleHeaderGetRawXmin(tuple), HeapScanDesc-\u0026gt;rs_snapshot) # tuple 不可见 PopActiveSnapshot() if PORTAL_MULTI_QUERY: PortalRunMulti GetTransactionSnapshot #6. 对于INSERT/DELETE/UPDATE等语法，在执行阶段才获取快照 RegisterSnapshot PushCopiedSnapshot ProcessQuery ExecutorStart ExecutorRun ExecutePlan ExecProcNode ExecModifyTable ExecInsert heap_insert # INSERT 好像用不到快照 ExecUpdate heap_update HeapTupleSatisfiesUpdate TransactionIdIsInProgress(HeapTupleHeaderGetRawXmin(tuple)) HeapTupleSatisfiesVisibility HeapTupleHeaderAdjustCmax ExecDelete heap_delete HeapTupleSatisfiesUpdate HeapTupleSatisfiesVisibility HeapTupleHeaderAdjustCmax PortalDrop finish_xact_command 2.2.3 提交日志 一、提交日志\n事务的提交日志中，记录了所有事务的状态：是否在运行、是否已提交等\n由于事务ID是从1开始递增，可用位图表示所有事务的状态，位图的索引即事务ID\n提交日志也需持久化，位图被划分存储在Page中，Page存储在提交日志文件中\n内存中也会缓存一些Page，使用LRU缓存Page\nClogCtlData / ClogCtl +------+------+------+------+ | Page | Page | Page | Page | +------+------+------+------+ XidStatus #define TRANSACTION_STATUS_IN_PROGRESS\t0x00 #define TRANSACTION_STATUS_COMMITTED\t0x01 #define TRANSACTION_STATUS_ABORTED\t0x02 #define TRANSACTION_STATUS_SUB_COMMITTED\t0x03 二、更新提交日志\n在分析或执行阶段，首次获取事务ID时，会扩展提交日志。在执行结束后，会根据事务状态更新提交日志。\nexec_simple_query start_xact_command # 执行解析、分析、执行等步骤 PortalRun ... heap_insert GetNewTransactionId /* 获取事务ID */ ExtendCLOG /* 记录事务状态 */ finish_xact_command CommitTransactionCommand # autovacuum / walsender等都会调用 s = CurrentTransactionState if TBLOCK_STARTED: CommitTransaction ProcArrayEndTransaction # 清理进程当前处理的xid pgxact = \u0026amp;allPgXact[pgprocno] ProcArrayEndTransactionInternal pgxact-\u0026gt;xid = InvalidTransactionId; pgxact-\u0026gt;xmin = InvalidTransactionId RecordTransactionCommit / xact_redo_commit # 更新提交日志 XactLogCommitRecord XLogInsert(RM_XACT_ID, info) # 生成xlog，记录事务已提交 TransactionIdCommitTree TransactionIdSetTreeStatus(TRANSACTION_STATUS_COMMITTED) if TBLOCK_BEGIN: 不提交事务 s-\u0026gt;blockState = TBLOCK_INPROGRESS if TBLOCK_INPROGRESS: CommandCounterIncrement # 其他更新事务状态的场景，不额外介绍 TransactionIdAsyncCommitTree TransactionIdSetTreeStatus(TRANSACTION_STATUS_COMMITTED) TransactionIdAbortTree TransactionIdSetTreeStatus(TRANSACTION_STATUS_ABORTED) 三、使用提交日志\n在更新或删除一条tuple前，会先检查是否有事务删除tuple，如果有则检查事务是已提交。判断是否已提交便是根据提交日志判断。下文会继续介绍判断逻辑\nheap_update HeapTupleSatisfiesUpdate TransactionIdDidCommit TransactionLogFetch UpdateXmaxHintBits XidStatus = TransactionIdDidCommit return xidstatus == TRANSACTION_STATUS_COMMITTED heap_delete UpdateXmaxHintBits TransactionIdDidCommit 2.3 Tuple携带事务ID 以下是tuple的结构：\ntypedef struct { /* ignore Union */ TransactionId t_xmin; /* 生成tuple的事务ID */ TransactionId t_xmax; /* 删除tuple的事务ID，默认为0 */ CommandId\tt_cid; ItemPointerData t_ctid; /* 更新tuple时，新数据的事务ID，默认为0 */ uint16 t_infomask2; uint16 t_infomask; uint8 t_hoff; bits8 t_bits[FLEXIBLE_ARRAY_MEMBER]; /* tuple data */ } HeapTupleHeader; 2.4 判断Tuple可见性 内容太多，学得头大，下次继续\nheap_insert(rel, tup, cid) # CommandId xid = get_cur_trans_id() heap_prepare_insert(rel, tup, xid, cid) heap_tup_set_xmin(tup, xid) heap_tup_set_cmin(tup, cid) buf = rel_get_buf_for_tup(rel, tup.len) blkno = get_page_with_free_space(rel, tlen) fsm_search(rel, tlen) fsm_search_avail(rel, tlen) read_buffer_bi(rel, blkno) read_buf(rel, blkno) read_buf_extend(rel, blkno) read_buf_comm(rel, blkno) bufhdr = buf_alloc(rel, blkno) lwlock_acquire(bufhdr, LW_EXCLUSIVE) visibilitymap_pin(rel, vmbuf) vm_readbuf() vm_extend() read_buf_extend() lock_buffer(BUFFER_LOCK_EXCLUSIVE) ... needlock = not rel_is_local(rel) if needlock: LockRelationForExtension(rel, ExclusiveLock) LockAcquire(rel, ExclusiveLock) LockAcquireExtended(rel, ExclusiveLock) LockAcquireExtended(relid, mode) locallock = hash_search(LockMethodLocalHash, relid, enter) typedef struct { LOCKTAG tag; SHM_QUEUE proLocks; /* 持有锁的进程：PROCLOCK */ PROC_QUEUE waitProcs; /* PGPROC */ int granted[MAX_LOCKMODES]; /* 锁上加锁次数，会同时持有多种锁 */ } LOCK; typedef struct { PROCLOCKTAG tag; PGPROC *groupLeader; SHM_QUEUE lockLink; /* LOCK */ SHM_QUEUE proLink; /* PGPROC */ } PROCLOCK; 每个后端进程维护正持有的锁和等待加的锁。\ntypedef struct { LOCALLOCKTAG tag; LOCK lock; PROCLOCK *proclock; int64 nLocks; /* 持有锁数量 */ } LOCALLOCK; 加锁：LockAcquire()\n查找进程持有锁，如果存在，返回锁，granted++ 通过fastpath找锁 在哈希表中加锁：先创建LOCK，PROLOCK if 加锁与等锁冲突：等待，if 加锁失败：等待 if dontwait: 返回加锁失败，否则，进入等待队列，进程休眠 放锁：\n查找进程持有锁，如果存在，if –ResourceOwner = 0: 释放锁。granted– 从fastpath找锁 从哈希表找锁 释放锁，唤醒其他等锁进程 锁 取值 操作 AccessShareLock 1 SELECT RowShareLock 2 SELECT FOR UPDATE/SHARE RowExclusiveLock 3 INSERT/UPDATE/DELETE ShareUpdateExclusiveLock 4 VACUUM/ANALYZE/CRATE INDEX CONCURRENTLY ShareLock 5 CREATE INDEX ShareRowExclusiveLock 6 row share ExclusiveLock 7 block ROW SHARE/SELECT FOR UPDATE AccessExclusiveLock 8 ALTER TABLE/DROP TABLE/VACUUM FULL - heap_open(relid lockmode) # not index - relation_open(relid, lockmode) # any rel LockRelationOid(relid, lockmode) LockAcquire(tag, lockmode) RelationIdGetRelation(relid) if RelationIdCacheLookup(relationId, rd) -\u0026gt; hash_search(RelationIdCache) RelationIncrementReferenceCount(rel) else RelationBuildDesc(relid) RelationIncrementReferenceCount(rel) - heap_close(relid, lockmode) - relation_close(rel, lockmode) RelationClose(rel) RelationDecrementReferenceCount() UnlockRelationId(lockmode) heap_insert(rel, tup, cid) xid = GetCurrentTransactionId() tup = heap_prepare_insert() # set [ insert xid | delete xid | cmd id | ... ] buf = RelationGetBufferForTuple(rel, tup.len) LockRelationForExtension(rel, ExclusiveLock) ReadBuffer(rel, blkno) # LWLockAcquire(bufhdr, LW_EXCLUSIVE), LockBuffer(buffer, BUFFER_LOCK_EXCLUSIVE) UnlockRelationForExtension(rel, ExclusiveLock) RelationPutHeapTuple(rel, buf, tup) # PageAddItem /* xlog */ UnlockReleaseBuffer(buf) LockBuffer(buf, BUFFER_LOCK_UNLOCK) ReleaseBuffer(buf) heap_delete(rel, tid, cid, snapshot) xid = GetCurrentTransactionId() buf = ReadBuffer(rel, ItemPointerGetBlockNumber(tid)) LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE) ... 复杂 heap_acquire_tuplock(rel, tup, LockTupleExclusive, LockWaitBlock) ... UnlockTupleTuplock(rel, tup, LockTupleExclusive) heap_update(rel, okdtid, newtup, cid, snapshot, lockmode) relation锁： buffer锁： call LWLockAcquire(LW_SHARED / LW_EXCLUSIVE) #define BUFFER_LOCK_UNLOCK\t0 #define BUFFER_LOCK_SHARE\t1 #define BUFFER_LOCK_EXCLUSIVE\t2 tuple锁： typedef enum { LockTupleKeyShare, /* SELECT FOR KEY SHARE */ LockTupleShare, /* SELECT FOR SHARE */ LockTupleNoKeyExclusive, /* SELECT FOR NO KEY UPDATE, and UPDATEs that don\u0026#39;t modify key columns */ LockTupleExclusive, /* SELECT FOR UPDATE, UPDATEs that modify key columns, and DELETE */ } LockTupleMode; 映射到reguler锁 LockMode { {AccessShareLock, MultiXactStatusForKeyShare, -1}, {RowShareLock, MultiXactStatusForShare, -1}, {ExclusiveLock, MultiXactStatusForNoKeyUpdate, MultiXactStatusNoKeyUpdate,}, {AccessExclusiveLock, MultiXactStatusForUpdate, MultiXactStatusUpdate} } LockTupleTuplock(rel, tid, lockmode) LockTuple(rel, tup, tupleLockExtraInfo[lockmode]) LockAcquire(tag, lockmode) typedef enum { MultiXactStatusForKeyShare = 0x00, MultiXactStatusForShare = 0x01, MultiXactStatusForNoKeyUpdate = 0x02, MultiXactStatusForUpdate = 0x03, /* an update that doesn\u0026#39;t touch \u0026#34;key\u0026#34; columns */ MultiXactStatusNoKeyUpdate = 0x04, /* other updates, and delete */ MultiXactStatusUpdate = 0x05 } MultiXactStatus; ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/3-6-transaction/","summary":"\u003ch1 id=\"1-事务的概念\"\u003e1 事务的概念\u003c/h1\u003e\n\u003ch2 id=\"11-事务的基本特性\"\u003e1.1 事务的基本特性\u003c/h2\u003e\n\u003cp\u003e事务的4个特性：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e原子性 Automicity\u003c/li\u003e\n\u003cli\u003e一致性 Consistency\u003c/li\u003e\n\u003cli\u003e隔离性 Isolation\u003c/li\u003e\n\u003cli\u003e持久性 Durability\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"12-事务的隔离性\"\u003e1.2 事务的隔离性\u003c/h2\u003e\n\u003cp\u003e不同隔离级别下，可能出现的异常如下：（T 表示可能）\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e异常\u003c/th\u003e\n          \u003cth\u003e读未提交\u003c/th\u003e\n          \u003cth\u003e读已提交\u003c/th\u003e\n          \u003cth\u003e可重复读\u003c/th\u003e\n          \u003cth\u003e可串行化\u003c/th\u003e\n          \u003cth\u003e解释\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e脏读\u003c/td\u003e\n          \u003ctd\u003eT\u003c/td\u003e\n          \u003ctd\u003e.\u003c/td\u003e\n          \u003ctd\u003e.\u003c/td\u003e\n          \u003ctd\u003e.\u003c/td\u003e\n          \u003ctd\u003e读其他事务未提交数据\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e不可重复读\u003c/td\u003e\n          \u003ctd\u003eT\u003c/td\u003e\n          \u003ctd\u003eT\u003c/td\u003e\n          \u003ctd\u003e.\u003c/td\u003e\n          \u003ctd\u003e.\u003c/td\u003e\n          \u003ctd\u003e2次读取数据不一致\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e幻读\u003c/td\u003e\n          \u003ctd\u003eT\u003c/td\u003e\n          \u003ctd\u003eT\u003c/td\u003e\n          \u003ctd\u003eT\u003c/td\u003e\n          \u003ctd\u003e.\u003c/td\u003e\n          \u003ctd\u003e2次读取数据条数不一致\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003epostgresql默认的隔离级别是读已提交\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 查看默认事务隔离级别\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eshow\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edefault_transaction_isolation\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edefault_transaction_isolation\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eread\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecommitted\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 查询当前的事务快照 pg 10\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etxid_current_snapshot\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etxid_current_snapshot\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-----------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1081\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"mi\"\u003e1081\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 查询所有正在活跃的进程\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_stat_activity\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e--\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"13-事务的实现\"\u003e1.3 事务的实现\u003c/h2\u003e\n\u003cp\u003e为实现事务，有3种并发控制机制：\u003c/p\u003e","title":"PostgreSQL 3-2 Transation"},{"content":"1 概述 1.1 思想 fsm结构\n用数组表示完全二叉树\n| 8 | | 4 | 8 | | 4 | 2 | 1 | 8 | 1.2 FSM涉及 物理页号\n+-------+-------+-------+-------+-------+ FSMFile | 8k | 8k | 8k | 8k | ... | +-------+-------+-------+-------+-------+ FSMBlock | 0 | 1 | 2 | 3 | ... | +-------+-------+-------+-------+-------+ 逻辑页号\n第2层：1个FSMBlock\n第1层：4069个FSMBlock\n第0层：4069 * 4069个FSMBlock，每个FSM可映射4069个DataBlock\nFSMAddress: [层次，页号]，页号即FSMBlock号\n每个表最大容量是32T，只需3层也页面即可管理整个表的空闲空间\n# [FSMAddress.level, FSMAddress.logpageno, FSMBlockNum（1个page即1个FSMBlock）] [2,0,0] | +---------------------------+---------------------------+ | | | [1,0,1] [1,1,1*4070+1] ... [1,4069,4069*4070+1] 本层共4069个FSMBlock | +----------+------------+ | | | [2,0,1+1] [2,1,1+2] ... [2,2,1+4069] ...... 本层共4069*4069个FSMBlock | （映射DataBlock 0 ~ 4065） 整体架构\n3层FSMBlock\n[8] [8 0] [8 0 0 0] [...] [8 0 0 0 0 ...] [8] [8 0] [8 0 0 0] [...] [8 0 0 0 0 ...] [8] [8 0] [8 0 0 0] [...] [8 0 0 0 0 ...] 测试\nCREATE TABLE t1(c1 INT, c2 TEXT); INSERT INTO t1 VALUES(1, \u0026#39;aaaaa\u0026#39;); CHECKPOINT; VACUUM t1; SELECT pg_relation_filepath(\u0026#39;t1\u0026#39;); SELECT * FROM pg_stat_file(\u0026#39;base/12926/16387_fsm\u0026#39;); -- output: size = 24576 第一个page的内容，且与第二个与第三个page内容一致\n00000000 00 00 00 00 00 00 00 00 00 00 00 00 18 00 00 20 |............... | 00000010 00 20 04 20 00 00 00 00 00 00 00 00 fd fd 00 fd |. . ............| # 00 20是special位置，fd开始为完全二叉树 00000020 00 00 00 fd 00 00 00 00 00 00 00 fd 00 00 00 00 |................| 00000030 00 00 00 00 00 00 00 00 00 00 00 fd 00 00 00 00 |................| 00000040 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 00000050 00 00 00 00 00 00 00 00 00 00 00 fd 00 00 00 00 |................| 00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000090 00 00 00 00 00 00 00 00 00 00 00 fd 00 00 00 00 |................| 000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000110 00 00 00 00 00 00 00 00 00 00 00 fd 00 00 00 00 |................| 00000120 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000210 00 00 00 00 00 00 00 00 00 00 00 fd 00 00 00 00 |................| 00000220 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000410 00 00 00 00 00 00 00 00 00 00 00 fd 00 00 00 00 |................| 00000420 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00000810 00 00 00 00 00 00 00 00 00 00 00 fd 00 00 00 00 |................| 00000820 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * 00001010 00 00 00 00 00 00 00 00 00 00 00 fd 00 00 00 00 |................| 00001020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| * /* FSMBlock 逻辑地址 */ typedef struct { int level; int logpageno; /* 当前层内的块号 */ } FSMAddress; typedef struct { int fp_next_slot; uint8 fp_nodes[FLEXIBLE_ARRAY_MEMBER]; } FSMPage; /* 每个FSMBlock中的节点数 8192 - 24 - 4 = 8164 */ #define NodesPerPage (BLCKSZ - MAXALIGN(SizeOfPageHeaderData) - offsetof(FSMPageData, fp_nodes)) /* 每个FSMBlock中的非叶子节点数 8192/2 - 1 = 4095 */ #define NonLeafNodesPerPage (BLCKSZ / 2 - 1) /* 每个FSMBlock中的叶子节点数 8164 - 4095 = 4069 */ #define LeafNodesPerPage (NodesPerPage - NonLeafNodesPerPage) /* 每个FSMBlock中slot数 4069 */ #define SlotsPerFSMPage LeafNodesPerPage /* 根节点所在层号 0 */ #define FSM_ROOT_LEVEL (FSM_TREE_DEPTH - 1) /* 叶子节点所在的层号 0 */ #define FSM_BOTTOM_LEVEL 0 叶子节点取值\n用1个字节表示对应DataBlock的空闲空间级别\n每个级别表示32字节空闲空间\n级别 对应data page的空闲空间 0 0 ~ 31 1 31 ~ 63 3 64 ~ 92 … … 255 8164 ~ 8192 /* FSM空闲空间级别 */ #define FSM_CATEGORIES 256 /* FSM空闲空间级别的步长 8192/256 = 32 */ #define FSM_CAT_STEP (BLCKSZ / FSM_CATEGORIES) 2 需求 2.1 模块对外接口 BlockNumber GetPageWithFreeSpace(Relation rel, Size spaceNeeded); BlockNumber RecordAndGetPageWithFreeSpace(Relation rel, BlockNumber oldPage, Size oldSpaceAvail, Size spaceNeeded) Size GetRecordedFreeSpace(Relation rel, BlockNumber heapBlk); void RecordPageWithFreeSpace(Relation rel, BlockNumber heapBlk, Size spaceAvail); void XLogRecordPageWithFreeSpace(RelFileNode rnode, BlockNumber heapBlk, Size spaceAvail); void FreeSpaceMapVacuum(Relation rel); void UpdateFreeSpaceMap(Relation rel, BlockNumber startBlkNum, BlockNumber endBlkNum, Size freespace); Size GetRecordedFreeSpace(Relation rel, BlockNumber heapBlk) uint16 slog; FSMAddress\taddr = fsm_get_location(heapBlk, \u0026amp;slot) Buffer buf = fsm_readbuf(rel, addr, false) unint8 cat = fsm_get_avail(BufferGetPage(buf), slot) return fsm_space_cat_to_avail(cat) 2.2 其他接口 Size PageGetHeapFreeSpace(Page page) Size space = PageGetFreeSpace(page) { space = page-\u0026gt;pd_upper - page-\u0026gt;pd_lower if space \u0026lt; sizeof(ItemIdData): return 0; space -= sizeof(ItemIdData) /* 留1个td */ } if space \u0026lt;= 0: return space OffsetNumber nline = PageGetMaxOffsetNumber(page) { (page-\u0026gt;pd_lower - SizeOfPageHeaderData) / sizeof(ItemIdData) } if nline \u0026gt;= MaxHeapTuplesPerPage： ... return space 2.2 调用点 /* 查找空闲空间 GetPageWithFreeSpace, RecordAndGetPageWithFreeSpace */ RelationGetBufferForTuple() /* 首先，通过FSM，获取1个DataBlock */ targetBlock = GetPageWithFreeSpace() while targetBlock != InvalidBlockNumber: /* 不信任fsm，判断DataBlock的空闲空闲空间是否足够 */ pageFreeSpace = PageGetHeapFreeSpace(page) if len + saveFreeSpace \u0026gt; pageFreeSpace: return buffer /* 重新通过FSM，获取1个DataBlock */ targetBlock = RecordAndGetPageWithFreeSpace(relation, targetBlock, pageFreeSpace, len + saveFreeSpace) GetFreeIndexPage() BlockNumber blkno = GetPageWithFreeSpace(BLCKSZ / 2) /* 设置空闲空间 RecordPageWithFreeSpace */ lazy_scan_heap() freespace = PageGetHeapFreeSpace(page) RecordPageWithFreeSpace(onerel, blkno, freespace) lazy_vacuum_heap(Relation onerel, LVRelStats *vacrelstats) freespace = PageGetHeapFreeSpace(page) RecordPageWithFreeSpace(onerel, tblk, freespace) RecordFreeIndexPage() RecordPageWithFreeSpace(rel, freeBlock, BLCKSZ - 1) RecordUsedIndexPage(Relation rel, BlockNumber usedBlock) RecordPageWithFreeSpace(rel, usedBlock, 0); /* 设置空闲空间（xlog重放场景）XLogRecordPageWithFreeSpace */ heap_xlog_clean(XLogReaderState *record) XLogRecordPageWithFreeSpace(rnode, blkno, freespace) heap_xlog_insert(XLogReaderState *record) XLogRecordPageWithFreeSpace(target_node, blkno, freespace) heap_xlog_multi_insert(XLogReaderState *record) XLogRecordPageWithFreeSpace(rnode, blkno, freespace) heap_xlog_update(XLogReaderState *record, bool hot_update) XLogRecordPageWithFreeSpace(rnode, newblk, freespace) /* 更新FSM树 FreeSpaceMapVacuum */ 2 函数 2.1 FSMBlock树 定位 FSMAddress fsm_get_location(BlockNumber heapblk, uint16 *slot) FSMAddress addr addr.level = FSM_BOTTOM_LEVEL addr.logpageno = heapblk / SlotsPerFSMPage slot = heapblk % SlotsPerFSMPage return addr BlockNumber fsm_get_heap_blk(FSMAddress addr, uint16 slot) Assert(addr.level == FSM_BOTTOM_LEVEL) return ((unsigned int)addr.logpageno) * SlotsPerFSMPage + slot BlockNumber fsm_logical_to_physical(FSMAddress addr) int leafno = addr.logpageno for (l = 0; l \u0026lt; addr.level; l++) leafno *= SlotsPerFSMPage /* e.g [1,1] = 1 * 4069 */ BlockNumber pages = 0 for (l = 0; l \u0026lt; FSM_TREE_DEPTH; l++) pages += leafno + 1 /* e.g [1,1] -\u0026gt; 4069 -\u0026gt; 4069 + 1 */ leafno /= SlotsPerFSMPage pages -= addr.level return pages - 1 FSMAddress fsm_get_child(FSMAddress parent, uint16 slot) /* slog为块内地址 */ FSMAddress child child.level = parent.level - 1 child.logpageno = parent.logpageno * SlotsPerFSMPage + slot return child FSMAddress fsm_get_parent(FSMAddress child, uint16 *slot) SMAddress parent parent.level = child.level + 1 parent.logpageno = child.logpageno / SlotsPerFSMPage *slot = child.logpageno % SlotsPerFSMPage /* FSMBlock树查找 */ BlockNumber fsm_search(Relation rel, uint8 min_cat) FSMAddress addr = FSM_ROOT_ADDRESS uinit8 max_avail = 0 for (;;): Buffer buf = fsm_readbuf(addr) if BufferIsValid(buf): LockBuffer(buf, BUFFER_LOCK_SHARE) /* 进行当前FSMBlock块内搜索 */ slot = fsm_search_avail(buf, min_cat, (addr.level == FSM_BOTTOM_LEVEL)) if slog == -1: max_avail = fsm_get_max_avail(BufferGetPage(buf)) /* 如果当前FSMBlock已找到合适的节点 */ if slot != -1: if addr.level == FSM_BOTTOM_LEVEL： /* 符合条件，直接返回 */ return fsm_get_heap_blk(addr, slot) else: /* 当前FSMBlock为0层或1层非叶子FSMBlock，从子节点中继续搜索 */ addr = fsm_get_child(addr, slot) /* 0层FSMBlock无合适节点，直接返回 */ else if addr.level == FSM_ROOT_LEVEL: return InvalidBlockNumber /* 0层满足，说明1层中至少1个FSMBlock满足，2层中至少1个叶子FSMBlock满足 */ else: /* 如果在1层和2层都无满足条件的节点，说明1层或2层FSMBlock中的最大值被用了，重新返回根节点开始扫描 */ uint16 parentslot FSMAddress parent = fsm_get_parent(addr, \u0026amp;parentslot) fsm_set_and_search(rel, parent, parentslot, max_avail) if restarts++ \u0026gt; 1000: return InvalidBlockNumber addr = FSM_ROOT_ADDRESS 2.2 FSMBlock读写 /* 初始化fsm page */ fsm_extend(Relation rel) PageInit(page) fsm_nblocks_now = smgrnblocks(rel-\u0026gt;rd_smgr, FSM_FORKNUM) smgrextend(rel-\u0026gt;rd_smgr, FSM_FORKNUM, fsm_nblocks_now) /* 读取fsm page */ Buffer fsm_readbuf(Relation rel, FSMAddress addr) lockNumber blkno = fsm_logical_to_physical(addr) buf = ReadBufferExtended(rel, FSM_FORKNUM) if PageIsNew(BufferGetPage(buf)) PageInit(BufferGetPage(buf)) return buf 2.3 FSMBlock内定位 /* 完全二叉树 */ #define leftchild(x) (2 * (x) + 1) #define rightchild(x) (2 * (x) + 2) #define parentof(x) (((x) - 1) / 2) int fsm_search_avail(Buffer buf, uint8 min_cat, bool advancenext, bool exclusive_lock_held); uint8 fsm_get_avail(Page page, int slot); uint8 fsm_get_max_avail(Page page); bool fsm_set_avail(Page page, int slot, uint8 value); bool fsm_truncate_avail(Page page, int nslots); bool fsm_rebuild_page(Page page); /* FSMBlock内查找，FSMBlock是大根对 */ int fsm_search_avail(Buffer buf, uint8 minvalue, bool advancenext, bool exclusive_lock_held) restart: /* 先判断根节点，如果本Block内的空闲空间较小，直接返回 */ if fsmpage-\u0026gt;fp_nodes[0] \u0026lt; minvalue: return -1; /* 从上一次查找的叶子节点开始查找 */ FSMPage\tfsmpage = (FSMPage)PageGetContents(BufferGetPage(buf)) int target = fsmpage-\u0026gt;fp_next_slot if target \u0026lt; 0 || target \u0026gt;= LeafNodesPerPage: target = 0 target += NonLeafNodesPerPage /* 从子节点上升至满足条件的父节点 */ int nodeno = target while nodeno \u0026gt; 0: if fsmpage-\u0026gt;fp_nodes[nodeno] \u0026gt;= minvalue: break; nodeno = parentof(rightneighbor(nodeno)) /* 从满足条件的父节点开始查找子节点 */ while nodeno \u0026lt; NonLeafNodesPerPage: /* 先判断左孩子 */ int childnodeno = leftchild(nodeno) if childnodeno \u0026lt; NodesPerPage \u0026amp;\u0026amp; fsmpage-\u0026gt;fp_nodes[childnodeno] \u0026gt;= minvalue: nodeno = childnodeno continue /* 再判断右孩子 */ childnodeno++ if childnodeno \u0026lt; NodesPerPage \u0026amp;\u0026amp; fsmpage-\u0026gt;fp_nodes[childnodeno] \u0026gt;= minvalue: nodeno = childnodeno else: /* 左右孩子都不满足，可能写FSMBlock时发生奔溃，需重建FSMBlock */ RelFileNode rnode ForkNumber forknum BlockNumber blknum BufferGetTag(buf, \u0026amp;rnode, \u0026amp;forknum, \u0026amp;blknum) LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE) fsm_rebuild_page(page) MarkBufferDirtyHint(buf, false) goto restart /* 找到叶子节点，返回叶子节点索引 */ slot = nodeno - NonLeafNodesPerPage fsmpage-\u0026gt;fp_next_slot = slot + (advancenext ? 1 : 0) /* 大部分场景下，返回的DataBlock会被插入多条数据，下一次查找FSM时，直接从下一个FSMBlock查找即可 */ return slot https://www.jianshu.com/p/4064dbb72414 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/3-7-fsm/","summary":"\u003ch1 id=\"1-概述\"\u003e1 概述\u003c/h1\u003e\n\u003ch2 id=\"11-思想\"\u003e1.1 思想\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003efsm结构\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e用数组表示完全二叉树\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e      \u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"m\"\u003e8\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"m\"\u003e4\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"m\"\u003e8\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"m\"\u003e4\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"m\"\u003e2\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e  \u003cspan class=\"m\"\u003e8\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"12-fsm涉及\"\u003e1.2 FSM涉及\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003e物理页号\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            +-------+-------+-------+-------+-------+\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eFSMFile     \u003cspan class=\"p\"\u003e|\u003c/span\u003e 8k     \u003cspan class=\"p\"\u003e|\u003c/span\u003e 8k   \u003cspan class=\"p\"\u003e|\u003c/span\u003e 8k    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 8k    \u003cspan class=\"p\"\u003e|\u003c/span\u003e ...   \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            +-------+-------+-------+-------+-------+\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eFSMBlock    \u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e     \u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"m\"\u003e1\u003c/span\u003e     \u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"m\"\u003e2\u003c/span\u003e     \u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"m\"\u003e3\u003c/span\u003e     \u003cspan class=\"p\"\u003e|\u003c/span\u003e ...   \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            +-------+-------+-------+-------+-------+\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003cstrong\u003e逻辑页号\u003c/strong\u003e\u003cbr\u003e\n第2层：1个FSMBlock\u003cbr\u003e\n第1层：4069个FSMBlock\u003cbr\u003e\n第0层：4069 * 4069个FSMBlock，每个FSM可映射4069个DataBlock\u003cbr\u003e\nFSMAddress: [层次，页号]，页号即FSMBlock号\u003cbr\u003e\n每个表最大容量是32T，只需3层也页面即可管理整个表的空闲空间\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# [FSMAddress.level, FSMAddress.logpageno, FSMBlockNum（1个page即1个FSMBlock）]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                             \u003cspan class=\"o\"\u003e[\u003c/span\u003e2,0,0\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    +---------------------------+---------------------------+\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e                           \u003cspan class=\"p\"\u003e|\u003c/span\u003e                           \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"o\"\u003e[\u003c/span\u003e1,0,1\u003cspan class=\"o\"\u003e]\u003c/span\u003e                 \u003cspan class=\"o\"\u003e[\u003c/span\u003e1,1,1*4070+1\u003cspan class=\"o\"\u003e]\u003c/span\u003e  ...  \u003cspan class=\"o\"\u003e[\u003c/span\u003e1,4069,4069*4070+1\u003cspan class=\"o\"\u003e]\u003c/span\u003e  本层共4069个FSMBlock\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e         +----------+------------+\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e         \u003cspan class=\"p\"\u003e|\u003c/span\u003e          \u003cspan class=\"p\"\u003e|\u003c/span\u003e            \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"o\"\u003e[\u003c/span\u003e2,0,1+1\u003cspan class=\"o\"\u003e]\u003c/span\u003e  \u003cspan class=\"o\"\u003e[\u003c/span\u003e2,1,1+2\u003cspan class=\"o\"\u003e]\u003c/span\u003e ... \u003cspan class=\"o\"\u003e[\u003c/span\u003e2,2,1+4069\u003cspan class=\"o\"\u003e]\u003c/span\u003e     ......                                本层共4069*4069个FSMBlock\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e         \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e（映射DataBlock \u003cspan class=\"m\"\u003e0\u003c/span\u003e ~ 4065）\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003cstrong\u003e整体架构\u003c/strong\u003e\u003cbr\u003e\n3层FSMBlock\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"o\"\u003e[\u003c/span\u003e8\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"o\"\u003e[\u003c/span\u003e\u003cspan class=\"m\"\u003e8\u003c/span\u003e 0\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"o\"\u003e[\u003c/span\u003e\u003cspan class=\"m\"\u003e8\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e 0\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"o\"\u003e[\u003c/span\u003e...\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"o\"\u003e[\u003c/span\u003e\u003cspan class=\"m\"\u003e8\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e ...\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"o\"\u003e[\u003c/span\u003e8\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"o\"\u003e[\u003c/span\u003e\u003cspan class=\"m\"\u003e8\u003c/span\u003e 0\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"o\"\u003e[\u003c/span\u003e\u003cspan class=\"m\"\u003e8\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e 0\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"o\"\u003e[\u003c/span\u003e...\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"o\"\u003e[\u003c/span\u003e\u003cspan class=\"m\"\u003e8\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e ...\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e[\u003c/span\u003e8\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e[\u003c/span\u003e\u003cspan class=\"m\"\u003e8\u003c/span\u003e 0\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e[\u003c/span\u003e\u003cspan class=\"m\"\u003e8\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e 0\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e[\u003c/span\u003e...\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e[\u003c/span\u003e\u003cspan class=\"m\"\u003e8\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003e ...\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e测试\u003c/p\u003e","title":"PostgreSQL 3-5 FSM"},{"content":"1 概述 1.1 vm接口调用点 heap_insert() buffer = RelationGetBufferForTuple() RelationPutHeapTuple(buffer, heaptup) if PageIsAllVisible(buffer): PageClearAllVisible(buffer) visibilitymap_clear(ItemPointerGetBlockNumber(heaptup), vmbuffer) MarkBufferDirty(buffer) #define PageIsAllVisible(page) ((page)-\u0026gt;pd_flags \u0026amp; PD_ALL_VISIBLE) 1.2 vm模块对外接口 visibilitymap_clear(Relation rel, BlockNumber heapBlk, Buffer buf, uint8 flags) int mapByte = HEAPBLK_TO_MAPBYTE(heapBlk) LockBuffer(buf, BUFFER_LOCK_EXCLUSIVE) char *map = PageGetContents(buf) if map[mapByte] 1.3 vmmap结构与定位 /* 8192 - 24 = 8168 */ #define MAPSIZE (BLCKSZ - MAXALIGN(SizeOfPageHeaderData)) /* 1字节 2bit表示1页 : | 00 00 00 00 | */ #define BITS_PER_BYTE 8 #define BITS_PER_HEAPBLOCK 2 /* 1字节 可映射4个heapblock */ #define HEAPBLOCKS_PER_BYTE (BITS_PER_BYTE / BITS_PER_HEAPBLOCK) /* 计算heapblock对应的vmblock, vmbyte, vmoffset的位置 */ /* 1vmblock可映射4 * 8168个datablock */ #define HEAPBLOCKS_PER_PAGE (MAPSIZE * HEAPBLOCKS_PER_BYTE) #define HEAPBLK_TO_MAPBLOCK(x) ((x) / HEAPBLOCKS_PER_PAGE) #define HEAPBLK_TO_MAPBYTE(x) (((x) % HEAPBLOCKS_PER_PAGE) / HEAPBLOCKS_PER_BYTE) #define HEAPBLK_TO_OFFSET(x) (((x) % HEAPBLOCKS_PER_BYTE) * BITS_PER_HEAPBLOCK) #define VISIBILITYMAP_ALL_VISIBLE\t0x01 #define VISIBILITYMAP_ALL_FROZEN\t0x02 #define VISIBILITYMAP_VALID_BITS\t0x03 1.4 vmblock读写 vm_extend(Relation rel, BlockNumber vm_nblocks) PGAlignedBlock pg PageInit((Page) pg.data, BLCKSZ, 0) LockRelationForExtension(rel, ExclusiveLock) BlockNumber vm_nblocks_now = smgrnblocks（rel-\u0026gt;rd_smgr, VISIBILITYMAP_FORKNUM） while vm_nblocks_now \u0026lt; vm_nblocks： PageSetChecksumInplace((Page) pg.data, vm_nblocks_now) smgrextend(rel-\u0026gt;rd_smgr, VISIBILITYMAP_FORKNUM, vm_nblocks_now, pg.data, false) vm_nblocks_now++ /* 让其他postgres进程smgrclose(rel) */ CacheInvalidateSmgr(rel-\u0026gt;rd_smgr-\u0026gt;smgr_rnode) { SharedInvalidationMessage msg msg.sm.id = SHAREDINVALSMGR_ID; msg.sm.backend_hi = rnode.backend \u0026gt;\u0026gt; 16; msg.sm.backend_lo = rnode.backend \u0026amp; 0xffff; msg.sm.rnode = rnode.node; VALGRIND_MAKE_MEM_DEFINED(\u0026amp;msg, sizeof(msg)) SendSharedInvalidMessages(\u0026amp;msg, 1) } rel-\u0026gt;rd_smgr-\u0026gt;smgr_vm_nblocks = vm_nblocks_now UnlockRelationForExtension(rel, ExclusiveLock) Buffer vm_readbuf(Relation rel, BlockNumber blkno, bool extend) RelationOpenSmgr(rel) if blkno \u0026gt;= rel-\u0026gt;rd_smgr-\u0026gt;smgr_vm_nblocks: if extend: vm_extend(rel, blkno + 1) buf = ReadBufferExtended(rel , VISIBILITYMAP_FORKNUM, blkno,RBM_ZERO_ON_ERROR) if PageIsNew(buf): PageInit(buf, BLKSZ, 0) return buf 1.5 vm模块对外接口 void visibilitymap_set(Relation rel, BlockNumber heapBlk, Buffer heapBuf, XLogRecPtr recptr, Buffer vmBuf, TransactionId cutoff_xid, uint8 flags) uint8 visibilitymap_get_status(Relation rel, BlockNumber heapBlk, Buffer *vmbuf) bool visibilitymap_clear(Relation rel, BlockNumber heapBlk, Buffer vmbuf, uint8 flags) /* 每个heapblock有3种状态 */ uint8 visibilitymap_get_status(Relation rel, BlockNumber heapBlk, Buffer *buf) BlockNumber mapBlock = HEAPBLK_TO_MAPBLOCK(heapBlk) uint32 mapByte = HEAPBLK_TO_MAPBYTE(heapBlk) uint8 mapOffset = HEAPBLK_TO_OFFSET(heapBlk) /* 比较传入的buf和计算的mapblock是否为同一个 */ if BufferIsValid(*buf): if BufferGetBlockNumber(*buf) != mapBlock: *buf = InvalidBuffer if !BufferIsValid(*buf): *buf = vm_readbuf(rel, mapBlock, false) map = PageGetContents(BufferGetPage(*buf)) /* 每个heapbuf有01 10 11共3种状态 */ unit8 result = ((map[mapByte] \u0026gt;\u0026gt; mapOffset) \u0026amp; VISIBILITYMAP_VALID_BITS) return uint8 void visibilitymap_set(Relation rel, BlockNumber heapBlk, Buffer heapBuf, XLogRecPtr recptr, Buffer vmBuf, TransactionId cutoff_xid, uint8 flags) ... ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/3-9-vm/","summary":"\u003ch1 id=\"1-概述\"\u003e1 概述\u003c/h1\u003e\n\u003ch2 id=\"11-vm接口调用点\"\u003e1.1 vm接口调用点\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eheap_insert\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eRelationGetBufferForTuple\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eRelationPutHeapTuple\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eheaptup\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"nf\"\u003ePageIsAllVisible\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003ePageClearAllVisible\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003evisibilitymap_clear\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nf\"\u003eItemPointerGetBlockNumber\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eheaptup\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e \u003cspan class=\"n\"\u003evmbuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eMarkBufferDirty\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ebuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define PageIsAllVisible(page) ((page)-\u0026gt;pd_flags \u0026amp; PD_ALL_VISIBLE)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"12-vm模块对外接口\"\u003e1.2 vm模块对外接口\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003evisibilitymap_clear\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eheapBlk\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"n\"\u003ebuf\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003euint8\u003c/span\u003e \u003cspan class=\"n\"\u003eflags\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003emapByte\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eHEAPBLK_TO_MAPBYTE\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eheapBlk\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eLockBuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ebuf\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBUFFER_LOCK_EXCLUSIVE\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003emap\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003ePageGetContents\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ebuf\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003emap\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003emapByte\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"13-vmmap结构与定位\"\u003e1.3 vmmap结构与定位\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 8192 - 24 = 8168 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define MAPSIZE (BLCKSZ - MAXALIGN(SizeOfPageHeaderData))\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 1字节 2bit表示1页 : | 00 00 00 00 | */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define BITS_PER_BYTE 8\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define BITS_PER_HEAPBLOCK 2\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\u003cspan class=\"cm\"\u003e/* 1字节 可映射4个heapblock */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define HEAPBLOCKS_PER_BYTE (BITS_PER_BYTE / BITS_PER_HEAPBLOCK)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 计算heapblock对应的vmblock, vmbyte, vmoffset的位置 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 1vmblock可映射4 * 8168个datablock */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define HEAPBLOCKS_PER_PAGE (MAPSIZE * HEAPBLOCKS_PER_BYTE)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define HEAPBLK_TO_MAPBLOCK(x) ((x) / HEAPBLOCKS_PER_PAGE)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define HEAPBLK_TO_MAPBYTE(x) (((x) % HEAPBLOCKS_PER_PAGE) / HEAPBLOCKS_PER_BYTE)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define HEAPBLK_TO_OFFSET(x) (((x) % HEAPBLOCKS_PER_BYTE) * BITS_PER_HEAPBLOCK)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define VISIBILITYMAP_ALL_VISIBLE\t0x01\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define VISIBILITYMAP_ALL_FROZEN\t0x02\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define VISIBILITYMAP_VALID_BITS\t0x03\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"14-vmblock读写\"\u003e1.4 vmblock读写\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003evm_extend\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003evm_nblocks\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ePGAlignedBlock\u003c/span\u003e \u003cspan class=\"n\"\u003epg\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003ePageInit\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003ePage\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003epg\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBLCKSZ\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eLockRelationForExtension\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eExclusiveLock\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003evm_nblocks_now\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003esmgrnblocks\u003c/span\u003e\u003cspan class=\"err\"\u003e（\u003c/span\u003e\u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003erd_smgr\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eVISIBILITYMAP_FORKNUM\u003c/span\u003e\u003cspan class=\"err\"\u003e）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"n\"\u003evm_nblocks_now\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003evm_nblocks\u003c/span\u003e\u003cspan class=\"err\"\u003e：\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003ePageSetChecksumInplace\u003c/span\u003e\u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003ePage\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003epg\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003evm_nblocks_now\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003esmgrextend\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003erd_smgr\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eVISIBILITYMAP_FORKNUM\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003evm_nblocks_now\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\t\t\t   \u003cspan class=\"n\"\u003epg\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003evm_nblocks_now\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* 让其他postgres进程smgrclose(rel) */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eCacheInvalidateSmgr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003erd_smgr\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003esmgr_rnode\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eSharedInvalidationMessage\u003c/span\u003e \u003cspan class=\"n\"\u003emsg\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003emsg\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esm\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eSHAREDINVALSMGR_ID\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003emsg\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esm\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebackend_hi\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ernode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebackend\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e16\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003emsg\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esm\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebackend_lo\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ernode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ebackend\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e \u003cspan class=\"mh\"\u003e0xffff\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003emsg\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esm\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ernode\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ernode\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003enode\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003eVALGRIND_MAKE_MEM_DEFINED\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003emsg\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"k\"\u003esizeof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003emsg\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003eSendSharedInvalidMessages\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003emsg\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003erd_smgr\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003esmgr_vm_nblocks\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003evm_nblocks_now\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eUnlockRelationForExtension\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eExclusiveLock\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003evm_readbuf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eblkno\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003eextend\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eRelationOpenSmgr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003eblkno\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;=\u003c/span\u003e \u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003erd_smgr\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"nl\"\u003esmgr_vm_nblocks\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"nl\"\u003eextend\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nf\"\u003evm_extend\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eblkno\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ebuf\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eReadBufferExtended\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erel\u003c/span\u003e \u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eVISIBILITYMAP_FORKNUM\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eblkno\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eRBM_ZERO_ON_ERROR\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"nf\"\u003ePageIsNew\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ebuf\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003ePageInit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ebuf\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBLKSZ\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ebuf\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"15-vm模块对外接口\"\u003e1.5 vm模块对外接口\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003evisibilitymap_set\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eheapBlk\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"n\"\u003eheapBuf\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eXLogRecPtr\u003c/span\u003e \u003cspan class=\"n\"\u003erecptr\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"n\"\u003evmBuf\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTransactionId\u003c/span\u003e \u003cspan class=\"n\"\u003ecutoff_xid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003euint8\u003c/span\u003e \u003cspan class=\"n\"\u003eflags\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003euint8\u003c/span\u003e \u003cspan class=\"nf\"\u003evisibilitymap_get_status\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eheapBlk\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003evmbuf\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"nf\"\u003evisibilitymap_clear\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eheapBlk\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"n\"\u003evmbuf\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003euint8\u003c/span\u003e \u003cspan class=\"n\"\u003eflags\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 每个heapblock有3种状态 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003euint8\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003evisibilitymap_get_status\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eheapBlk\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ebuf\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003emapBlock\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eHEAPBLK_TO_MAPBLOCK\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eheapBlk\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003euint32\u003c/span\u003e \u003cspan class=\"n\"\u003emapByte\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eHEAPBLK_TO_MAPBYTE\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eheapBlk\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"n\"\u003euint8\u003c/span\u003e \u003cspan class=\"n\"\u003emapOffset\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eHEAPBLK_TO_OFFSET\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eheapBlk\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* 比较传入的buf和计算的mapblock是否为同一个 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"nf\"\u003eBufferIsValid\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ebuf\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"nf\"\u003eBufferGetBlockNumber\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ebuf\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"nl\"\u003emapBlock\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ebuf\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eInvalidBuffer\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"nf\"\u003eBufferIsValid\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ebuf\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ebuf\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003evm_readbuf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003emapBlock\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003emap\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003ePageGetContents\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nf\"\u003eBufferGetPage\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ebuf\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* 每个heapbuf有01 10 11共3种状态 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eunit8\u003c/span\u003e \u003cspan class=\"n\"\u003eresult\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e((\u003c/span\u003e\u003cspan class=\"n\"\u003emap\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003emapByte\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003emapOffset\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003eVISIBILITYMAP_VALID_BITS\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003euint8\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003evisibilitymap_set\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003erel\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBlockNumber\u003c/span\u003e \u003cspan class=\"n\"\u003eheapBlk\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"n\"\u003eheapBuf\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eXLogRecPtr\u003c/span\u003e \u003cspan class=\"n\"\u003erecptr\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eBuffer\u003c/span\u003e \u003cspan class=\"n\"\u003evmBuf\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eTransactionId\u003c/span\u003e \u003cspan class=\"n\"\u003ecutoff_xid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003euint8\u003c/span\u003e \u003cspan class=\"n\"\u003eflags\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"PostgreSQL 3-10 VM"},{"content":"1 heamp的简介 前置知识：Relation的基本概念，Tuple的基本概念\n1.1 heapam接口的功能 heapam是存储模块对上层提供的数据读写接口，这些接口通常是操作1个relation中的1个或多个tuple。\n本文介绍以下4个最常用的接口，即如何向1个relation中写入、删除、更新、读取1个Tuple，接口定义如下：\n/* 向relatiion中写入1条tuple */ heap_insert(Relation relation, HeapTuple tup, ...) /* 从relation中删除1条tuple */ heap_delete(Relation relation, ItemPointer tid, ...) /* 在relation中，将旧tuple标记删除，并写入1个新tuple */ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup, ...) /* 从relation中读取数据，每次读取1条数据 */ HeapScanDesc heap_beginscan(Relation relation, ...) HeapTuple heap_getnext(HeapScanDesc scan) 1.2 调用heapam接口 /* * 此处，以4个常见的SQL为例，介绍数据库如何调用heapam接口 * 1. INSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;); * 2. SELECT * FROM t1; * 3. DELETE FROM t1 WHERE c1 = 1; * 4. UPDATE t1 SET c2 = \u0026#39;data2\u0026#39; WHERE c1 = 1; */ exec_simple_query(\u0026#34;SQL语句\u0026#34;) /* 该函数是所有SQL语句的统一处理入口 */ PortalRun() PortalRunMulti() ProcessQuery() ExecutorRun() standard_ExecutorRun() ExecutePlan() ExecProcNode() /* 从这里开始分叉，不同类型的SQL语句，由不同函数处理 */ ExecModifyTable() ExecInsert() /* 处理：INSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;) */ heap_insert(relation, tuple, ..) 1.3 heapam接口的使用场景 实际应用场景中，数据库的存储模块需满足以下关键需求：\n操作多：1个表需要支持数据写入、查询、更新、删除等操作 数据多：1个表可能存储亿级以上的数据 并发高：短时间内，可能上百个连接同时读写1个表 可靠性高：突然发生断电等特殊情况，数据不会发生错乱 性能高：使用一些机制，优化数据访问的速度，比如：缓存、锁等 明确存储接口该解决哪些问题后，了解heapam接口时，可大概清楚每一步的目的。\n2 Heapam工作流程 2.1 heap_insert接口 heap_insert的工作流程分为4个阶段：\nheap_insert GetCurrentTransactionId heap_prepare_insert # 1. 获取当前事务id，并为Tuple设置事务信息 RelationGetBufferForTuple # 2. 读取1个合适的Page，用于存放Tuple，对Page加排他锁 RelationPutHeapTuple # 3. 将Tuple存至Page XLogBeginInsert # 4. 生成WAL日志，并将WAL日志写入WAL Buffer中 XLogInsert UnlockReleaseBuffer # 解锁Page 各阶段中，详细流程如下：\n获取当前事务id，并为Tuple设置事务信息\nGetCurrentTransactionId heap_prepare_insert HeapTupleHeaderSetXmin HeapTupleHeaderSetCmin HeapTupleHeaderSetXmax 从Buffer中，查找1个合适的Page\nheap_insert RelationGetBufferForTuple GetPageWithFreeSpace # 1 首先，根据Tuple的大小，查找fsm，选择合适的Page fsm_search LOOP: ReadBufferBI # 2 从Buffer中，查找指定Page ReadBuffer ReadBufferExtended ReadBuffer_common ... LockBuffer(BUFFER_LOCK_EXCLUSIVE) # 3 对Page加排他锁 if pageFreeSpace \u0026lt; PageGetHeapFreeSpace # 4 对Page加锁后，检查Page的空闲空间，Page空闲空间够，则返回 return else: # 5 如果在1-3步中，其他进程页操作了Page，导致Page容量变小，则解锁Page，重新查找新Page LockBuffer(BUFFER_LOCK_UNLOCK) RecordAndGetPageWithFreeSpace # 6 记录当前Page的空闲空间，然后查找fms，选择合适的Page，循环到步骤2 fsm_set_and_search fsm_search # 7 在循环中，未找到合适的Page，则初始化1个新的Page LockRelationForExtension(ExclusiveLock) ReadBufferBI(P_NEW) ReadBuffer PageInit 将Tuple存至Page（详见Page模块）\nRelationPutHeapTuple PageAddItem 生成WAL日志，并将WAL日志写入WAL Buffer中（详见WAL模块）\n2.2 heap_delete接口 heap_delete的工作流程分为4个阶段：\nheap_delete GetCurrentTransactionId # 1. 获取当前事务的id ReadBuffer # 2. 找到待删除Tuple所在的Page PageGetItemId HeapTupleSatisfiesUpdate # 3. 判断Tuple是否可见 3 otherBuffer：update场景，包含旧数据 targetBuffer：插入的页面，默认从上次插入的页面接着插入 Oid heap_insert(Relation relation, HeapTuple tup, CommandId cid, int options, BulkInsertState bistate) HeapTuple heaptup = heap_prepare_insert(relation, tup, xid, cid, options) Buffer buffer = RelationGetBufferForTuple(relation, heaptup-\u0026gt;t_len,InvalidBuffer, options, bistate, \u0026amp;vmbuffer, NULL) RelationPutHeapTuple(relation, buffer, heaptup) if PageIsAllVisible(BufferGetPage(buffer)): visibilitymap_clear(relation, ItemPointerGetBlockNumber(\u0026amp;(heaptup-\u0026gt;t_self)), vmbuffer) MarkBufferDirty(buffer) if !(options \u0026amp; HEAP_INSERT_SKIP_WAL) \u0026amp;\u0026amp; RelationNeedsWAL(relation): /* 如果是系统表 */ if RelationIsAccessibleInLogicalDecoding(relation): log_heap_new_cid(relation, heaptup) ... XLogInsert(RM_HEAP2_ID, XLOG_HEAP2_NEW_CID) if ItemPointerGetOffsetNumber(\u0026amp;(heaptup-\u0026gt;t_self)) == FirstOffsetNumber: info |= XLOG_HEAP_INIT_PAGE bufflags |= REGBUF_WILL_INIT XLogBeginInsert() XLogRegisterData((char *) \u0026amp;xlrec, SizeOfHeapInsert) XLogRegisterBuffer(0, buffer, REGBUF_STANDARD | bufflags) XLogRegisterBufData(0, (char *) \u0026amp;xlhdr, SizeOfHeapHeader) XLogRegisterBufData(0, heaptup-\u0026gt;t_data + SizeofHeapTupleHeader, heaptup-\u0026gt;t_len - SizeofHeapTupleHeader) XLogIncludeOrigin() recptr = XLogInsert(RM_HEAP_ID, info) PageSetLSN(page, recptr) CacheInvalidateHeapTuple(relation, heaptup, NULL) return HeapTupleGetOid(tup) init page时机 一共3处：\nheap_insert() ... Buffer buffer = RelationGetBufferForTuple() ... RelationPutHeapTuple(relation, buffer, heaptup) ... if ItemPointerGetOffsetNumber(\u0026amp;(heaptup-\u0026gt;t_self)) == FirstOffsetNumber: info |= XLOG_HEAP_INIT_PAGE heap_xlog_insert() if XLogRecGetInfo(record) \u0026amp; XLOG_HEAP_INIT_PAGE: buffer = XLogInitBufferForRedo(record, 0) XLogReadBufferForRedoExtended(RBM_ZERO_AND_LOCK) if XLogRecHasBlockImage(record, block_id): *buf = XLogReadBufferExtended() page = BufferGetPage(*buf) RestoreBlockImage(record, block_id, page) MarkBufferDirty(*buf) else: *buf = XLogReadBufferExtended() page = BufferGetPage(buffer) PageInit(page, BufferGetPageSize(buffer), 0) else: XLogReadBufferForRedo(record, 0, \u0026amp;buffer) data = XLogRecGetBlockData(record, 0, \u0026amp;datalen) htup = \u0026amp;tbuf.hdr htup-\u0026gt;t_infomask2 = xlhdr.t_infomask2 htup ... = ... PageAddItem(page, (Item) htup, newlen, xlrec-\u0026gt;offnum) MarkBufferDirty(buffer) heap_multi_insert(HeapTuple *tuples, int ntuples) ... while (ndone \u0026lt; ntuples) buffer = RelationGetBufferForTuple() RelationPutHeapTuple() for (nthispage = 1; ndone + nthispage \u0026lt; ntuples; nthispage++) RelationPutHeapTuple() log_heap_new_cid(relation, heaptup) MarkBufferDirty(buffer) init = (ItemPointerGetOffsetNumber(\u0026amp;(heaptuples[ndone]-\u0026gt;t_self)) == FirstOffsetNumber \u0026amp;\u0026amp; PageGetMaxOffsetNumber(page) == FirstOffsetNumber + nthispage - 1) if init: info |= XLOG_HEAP_INIT_PAGE ... ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/3-10-heapam/","summary":"\u003ch1 id=\"1-heamp的简介\"\u003e1 heamp的简介\u003c/h1\u003e\n\u003cp\u003e前置知识：Relation的基本概念，Tuple的基本概念\u003c/p\u003e\n\u003ch2 id=\"11-heapam接口的功能\"\u003e1.1 heapam接口的功能\u003c/h2\u003e\n\u003cp\u003eheapam是存储模块对上层提供的数据读写接口，这些接口通常是操作1个relation中的1个或多个tuple。\u003cbr\u003e\n本文介绍以下4个最常用的接口，即如何向1个relation中写入、删除、更新、读取1个Tuple，接口定义如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 向relatiion中写入1条tuple */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eheap_insert\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003erelation\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eHeapTuple\u003c/span\u003e \u003cspan class=\"n\"\u003etup\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e...)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 从relation中删除1条tuple */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eheap_delete\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003erelation\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eItemPointer\u003c/span\u003e \u003cspan class=\"n\"\u003etid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e...)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 在relation中，将旧tuple标记删除，并写入1个新tuple */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eheap_update\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003erelation\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eItemPointer\u003c/span\u003e \u003cspan class=\"n\"\u003eotid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eHeapTuple\u003c/span\u003e \u003cspan class=\"n\"\u003enewtup\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e...)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 从relation中读取数据，每次读取1条数据 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eHeapScanDesc\u003c/span\u003e \u003cspan class=\"nf\"\u003eheap_beginscan\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelation\u003c/span\u003e \u003cspan class=\"n\"\u003erelation\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e...)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eHeapTuple\u003c/span\u003e \u003cspan class=\"nf\"\u003eheap_getnext\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eHeapScanDesc\u003c/span\u003e \u003cspan class=\"n\"\u003escan\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"12-调用heapam接口\"\u003e1.2 调用heapam接口\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/*\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * 此处，以4个常见的SQL为例，介绍数据库如何调用heapam接口\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *  1. INSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;);\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *  2. SELECT * FROM t1;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *  3. DELETE FROM t1 WHERE c1 = 1;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *  4. UPDATE t1 SET c2 = \u0026#39;data2\u0026#39; WHERE c1 = 1;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eexec_simple_query\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;SQL语句\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 该函数是所有SQL语句的统一处理入口  */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003ePortalRun\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003ePortalRunMulti\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nf\"\u003eProcessQuery\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nf\"\u003eExecutorRun\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003estandard_ExecutorRun\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"nf\"\u003eExecutePlan\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"nf\"\u003eExecProcNode\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 从这里开始分叉，不同类型的SQL语句，由不同函数处理 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"nf\"\u003eExecModifyTable\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"nf\"\u003eExecInsert\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 处理：INSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;) */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                        \u003cspan class=\"nf\"\u003eheap_insert\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelation\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003etuple\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"p\"\u003e..)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"13-heapam接口的使用场景\"\u003e1.3 heapam接口的使用场景\u003c/h2\u003e\n\u003cp\u003e实际应用场景中，数据库的存储模块需满足以下关键需求：\u003c/p\u003e","title":"PostgreSQL 3-1 Heapam"},{"content":" 1 背景 1.1 数据检索 1 索引概述 1.1 概述 1.2 索引函数 1.2.1 调用索引函数 1.2.2 索引函数 2 索引实现 2.1 创建索引 ambuild 一、build整体流程 二、build插入tuple 2.2 索引写入数据 aminsert 3 operate 1 背景 1.1 数据检索 通常，应用会使用数据库存储大量数据，比如，单个表存储上百万、甚至上百亿条数据。此时，对表中数据进行某些查询时，将变得非常困难，比如等值查询、范围查询、模糊查询等。\n1 索引概述 1.1 概述 索引方式：postgresql共有5种索引\n唯一索引：不能出现重复的值\n主键索引：主键自动创建唯一索引\n多属性索引：多个列（最多32列）\n部分索引：WHERE过滤索引\n-- 示例 CREATE INDEX .. WHERE (c1 \u0026gt; 10); 表达式索引：和部分索引没太大区别，都是额外调用1个函数\n-- 示例 CREATE INDEX .. WHERE (c1 = 10); 索引分类：postgresql有多种索引，本文见介绍以下4种\nbtree hash gist gin 索引系统表\npg_am：存储所有索引的方法\nSELECT * FROM pg_am; amname | amhandler | amtype -------+-------------+-------- btree | bthandler | i hash | hashhandler | i gist | gisthandler | i gin | ginhandler | i spgist | spghandler | i brin | brinhandler | i pg_index：存储所有索引，索引列的下标\nSELECT indexrelid,indrelid,indnatts,indkey FROM pg_index; indexrelid | indrelid | indnatts | indkey -----------+----------+----------+---------- 2831 | 2830 | 2 | 1 2 1.2 索引函数 1.2.1 调用索引函数 # 1 创建索引 DefineIndex() index_create() # 向系统表中写入tuple index_open() index_build() ambuild -\u0026gt; OidFunctionCall3() index_close() validate_index() # 2 索引写入数据 ExecInsert() heap_insert() ExecInsertIndexTuples() index_insert() aminsert -\u0026gt; FunctionCall6() # 3 索引扫描数据 ExecIndexScan() IndexNext() index_getnext() index_getnext_tid() amgettuple -\u0026gt; FunctionCall2() index_fetch_heap() # 4 更新索引数据 ExecUpdate() heap_update() ExecInsertIndexTuples() index_insert() # 5 删除索引 ExecDelete() heap_delete() 1.2.2 索引函数 pg_am系统表存储统一接口\n类型 btree hash gist gin spgist brin aminsert btinsert ambeginscan btbeginscan amgettuple btgettuple amgetbitmap btgetbitmap amrescan btrescan amendscan btendscan ammarkpos btmarkpos ambuild btbuild ambuildempty btbuildempty ambulkdelete btbulkdelete amvacuumcleanup btvacuumcleanup amcanreturn btcanreturn amcostestimate btcostestimate amoptions btoptions 2 索引实现 2.1 创建索引 ambuild 创建索引的关键流程如下：\n扫描所有数据，排序 自底向上构建B-Link树，Root节点不断变化 每个节点存储High-Key，存储右兄弟 一、build整体流程 btbuild _bt_spoolinit # 1 初始化spool _bt_spoolinit # 如果是唯一索引，再初始化一个spool2，存储被标记删除的tuple IndexBuildHeapScan # 2 扫描基表所有tuple IndexBuildHeapRangeScan heap_beginscan_strat heap_getnext btbuildCallback \u0026lt;- callback # 3 将基表tuple存spool _bt_spool tuplesort_putindextuplevalues index_form_tuple puttuple_common heap_endscan _bt_leafbuild tuplesort_performsort # 3 排序所有tuple _bt_load # 如果是唯一索引，归并spool和spool2，再建索引 tuplesort_getindextuple # 4 遍历获取spool中所有tuple _bt_buildadd # 5 构建b+树 （详细逻辑如下） _bt_uppershutdown smgrimmedsync _bt_spooldestroy 二、build插入tuple b+树的每个节点都是1个page，为让build的流程更直观一点，用以下格式表示1个page\n# 假设每个page能存储4个tuple # 每个page的内容如下 Pageno BTPageOpaque (pre, next) +---+----------------+---------+-----+ | - | - - - - - | - - - - | - - | +---+----------------+---------+-----+ ItemPointer ItemData 在每个page中，有以下约定：\n第1个ItemPointer为highkey，存储本page的最大值，只有page满时，才会设置highkey 第2个ItemPointer为firstkey，存储本page的最小值 每个page的最大值，会存在3个地方：本page highkey，下一page firstkey，父母节点 _bt_buildadd 构建b+树的函数有如下2个场景：\n场景1 有空闲空间，直接插入Page\n# input: | 1 | - - - - - | - - - - | - - | _bt_buildadd(1) if PageGetFreeSpace \u0026lt; itupsz: ... _bt_sortaddtup PageAddItem # output: | 1 | - p1 - - - | - - - 1 | - - | 场景2 无空闲空间，分裂\n自底向上构建二叉树，root-page是会不断改变的\n# input: | 1 | - p1 p3 p5 p7 | 7 5 3 1 | - - | _bt_buildadd(9) if PageGetFreeSpace \u0026lt; itupsz: # 无空闲空间 # 生成new-page，预留high-key位置 newpage = _bt_blnewpage # | 2 | - - - - - | - - - - | - - | newpage # 将old-page的最大值，写入new-page的第一个位置 _bt_sortaddtup(newpage, PageGetItem(last_off)) # | 2 | - p7 - - - | - - - 7 | - - | newpage # 把最大指移入high-key的位置 *(oldpage, P_HIKEY) = *(oldpage, last_off) # | 1 | p7 p1 p3 p5 p7 | 7 5 3 1 | - - | oldpage # 删除old-page中的重复指针 oldpage-\u0026gt;pd_lower -= sizeof(ItemIdData) # | 1 | p7 p1 p3 p5 | 7 5 3 1 | - - | oldpage # 从栈中，找到parent-page，如果无parent-page，则创建parent-page if state-\u0026gt;btps_next is NULL: state-\u0026gt;btps_next = _bt_pagestate _bt_blnewpage # | 3 | - - - - - | - - - - | - - | parent-page # 调用_bt_buildadd，将oldpage中的最大值，插入到parent-page _bt_buildadd(btps_next, (oldpage, P_HIKEY)) # | 3 | - p7 - - - | - - - 7 | - - | parent-page # 注意：此处parent-page中，item-data存储的是子page的blockno和high-key，即此处的7 = {(1, 1), 7} oldpage-\u0026gt;next = newpage # | 1 | p7 p1 p3 p5 | 7 5 3 1 | - 2 | oldpage newpage-\u0026gt;prev = oldpage # | 2 | - p7 - - - | - - - 7 | 1 - | newpage # old-page 不会再修改，将old-page写入磁盘 _bt_blwritepage # 记录写入位置为新page的first last_off = P_FIRSTKEY # 将tuple写入new-page _bt_sortaddtup PageAddItem # | 2 | - p7 p9 - - | - - 9 7 | 1 - | newpage # 更新栈信息 state-\u0026gt;btps_page = npage; state-\u0026gt;btps_lastoff = last_off state-\u0026gt;btps_minkey: now is min of npage # output: # | 3 | - p7 - - - | - - - 7 | - - | # / # / # | 1 | p7 p1 p3 p5 | 7 5 3 1 | - 2 | ----\u0026gt; | 2 | - p7 p9 - - | - - 9 7 | 1 - | 2.2 索引写入数据 aminsert btinsert index_form_tuple _bt_doinsert _bt_mkscankey _bt_search # 1 遍历B+树，查找tuple应插入的叶子page _bt_getroot # 获取root-page for: _bt_moveright # 并发场景中，判断Page是否分裂 BTPageOpaque(page) if P_ISLEAF(BTPageOpaque): # 如果是叶子page，返回 break _bt_binsrch # 在中间page中，获取tuple blkno = PageGetItem-\u0026gt;itup-\u0026gt;t_tid # 从tuple中，获取子节点的blkno _bt_relandgetbuf(blkno) # 读取子节点 _bt_moveright # 2 并发场景中，如果page发生分裂，获取右边的page _bt_binsrch # 3 在page中，通过二分查找法，找到插入点 _bt_check_unique if TransactionIdIsValid: _bt_relbuf # 如果拿锁失败，从第1步开始重新遍历 _bt_freestack _bt_findinsertloc # 4 获取插入位置 _bt_insertonpg # 5 插入tuple _bt_freestack _bt_freeskey # input: # | 3 | - p7 - - - | - - - 7 | - - | # / # / # | 1 | p7 p1 p3 p5 | 7 5 3 1 | - 2 | ----\u0026gt; | 2 | - p7 p9 - - | - - 9 7 | 1 - | _bt_findinsertloc(6) # 已选中page为 page[1] lpage = page[1] while PageGetFreeSpace(page) \u0026lt; itemsz: # 如果当前page无空间，尽量回收当前page的空间 if P_HAS_GARBAGE(lpage): _bt_vacuum_one_page # 如果tuple的值等于highkey，可以考虑将highkey写入右边的page，否则中止循环，后面的函数进行分裂 if _bt_compare(P_HIKEY) != 0: break # 向右查找page，仅限于特殊场景 rblkno = lpage-\u0026gt;next rbuf = _bt_relandgetbuf(rblkno) # 使用二分查找，获取插入位置 _bt_binsrch # | 1 | p7 p1 p3 p5 | 7 5 3 1 | - 2 | # ^ 场景一：需要分裂\n_bt_insertonpg(6) lpage = page[1] if PageGetFreeSpace(page) \u0026lt; itemsz: # 在lpage中查找分裂的位置 _bt_findsplitloc # 判断分裂后新tuple在left还是right page # | 1 | p7 p1 p3 p5 | 7 5 3 1 | - 2 | for offnum in (firstkey, maxoff): if offnum \u0026gt; newitemoff: _bt_checksplitloc elif offnum \u0026lt; newitemoff: _bt_checksplitloc else: _bt_checksplitloc _bt_checksplitloc # 分裂 rbuf = _bt_split # 生成新的righe page rbuf = _bt_getbuf(P_NEW) # | 4 | - - - - - | - - - - | - - | righepage (new) # 将原始的leftpage中的数据，分到新的page中 origpage = lpage = page[1] # | 1 | p7 p1 p3 p5 | 7 5 3 1 | - 2 | leftpage = PageGetTempPage(origpage) # | - | - - - - - | - - - - | - - | rightpage = rbuf # | 4 | - - - - - | - - - - | - - | _bt_pageinit(leftpage) for i in (FIRST_KEY(origpage), maxoff): if i \u0026lt; firstright: # | - | p7 p1 p3 p5 - | - 5 3 1 | - 2 | _bt_pgaddtup(leftpage) elif i == newitemoff: # | 4 | - p6 p6 - - | - - 7 6 | - - | if newitemonleft: _bt_pgaddtup(leftpage) else: _bt_pgaddtup(rightpage) else: _bt_pgaddtup(rightpage) # 更新原始的right的prev指针为新的right sbuf = _bt_getbuf(origpage-\u0026gt;next) sbuf-\u0026gt;prev = rightpage # | 2 | - p7 p9 - - | - - 9 7 | 4 - | # 将临时的leftpage，覆盖原始的leftpage PageRestoreTempPage # | 1 | p7 p1 p3 p5 - | - 5 3 1 | - - | # 记录分裂的xlog XLogRegisterBuffer(buf) XLogRegisterBuffer(rbuf) XLogRegisterBuffer(sbuf) XLogInsert(RM_BTREE_ID) # 将lbuf和rbuf的值，更新到父母节点 _bt_insert_parent # 从栈中，获取parrent-page pbuf = _bt_getstackbuf # todo：如何为新的page设置highkey # 将新的highkey插入parrent-page _bt_insertonpg() # output: todo 场景二：无需分裂\n_bt_insertonpg(6) _bt_pgaddtup XLogInsert(RM_BTREE_ID) 3 operate operator： 1个操作，例如大于 或 小于等 pg_operator pg_amop - 操作符 pg_amproc - 操作符对应的函数 op class: 1套操作，包括大于、小于、等于等 pg_opclass op falmily: 跨类型操作，多个op class互相操作 pg_opfamily pg_am (btree) │ ├─ pg_opfamily \u0026#34;integer_ops\u0026#34; (支持不同类型之间运算) │ ├─ pg_amop : int4 \u0026lt; int4 │ ├─ pg_amop : int4 \u0026lt; int8 │ ├─ pg_amop : int8 \u0026lt; int4 │ └─ pg_amproc : btint4cmp │ └─ pg_opclass \u0026#34;int4_ops\u0026#34; (同一类型的预算) opcfamily → integer_ops opcintype → int4 opcdefault = true -- 1. 核心比较函数 CREATE OR REPLACE FUNCTION int_cmp(a int, b int) RETURNS int AS $$ SELECT a - b; $$ LANGUAGE sql IMMUTABLE PARALLEL SAFE; -- 2. 自定义运算符 CREATE OPERATOR ~\u0026gt; (LEFTARG=int, RIGHTARG=int, PROCEDURE=int_cmp); -- 类比 \u0026gt; CREATE OPERATOR ~\u0026lt; (LEFTARG=int, RIGHTARG=int, PROCEDURE=int_cmp); -- 类比 \u0026lt; -- 3. CREATE OPERATOR FAMILY int_min_ops USING btree; ALTER OPERATOR FAMILY int_min_ops USING btree ADD OPERATOR 1 ~\u0026lt; (int, int), -- 报错点：ADD处语法问题（顺序+类型缩写+多运算符） ADD OPERATOR 3 = (int, int), ADD OPERATOR 5 ~\u0026gt; (int, int); ALTER OPERATOR FAMILY int_min_ops USING btree ADD FUNCTION 1 int_cmp(int, int); -- 4. 运算符类（类型缩写可能存在兼容问题） CREATE OPERATOR CLASS int_min_opclass FOR TYPE int USING btree AS FAMILY = int_min_ops, OPERATOR 1 ~\u0026lt;, OPERATOR 3 =, OPERATOR 5 ~\u0026gt;, FUNCTION 1 int_cmp; -- 验证语句 CREATE TABLE t (x int); INSERT INTO t VALUES (1),(3),(5); CREATE INDEX idx_t_x ON t USING btree (x int_min_opclass); EXPLAIN ANALYZE SELECT * FROM t WHERE x ~\u0026gt; 2; -- 清理语句 DROP INDEX idx_t_x; DROP TABLE t; DROP OPERATOR CLASS int_min_opclass USING btree; DROP OPERATOR FAMILY int_min_ops USING btree; DROP OPERATOR ~\u0026gt; (int,int); DROP OPERATOR ~\u0026lt; (int,int); DROP FUNCTION int_cmp(int,int); ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/3-11-index/","summary":"\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-%E8%83%8C%E6%99%AF\"\u003e1 背景\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-1-%E6%95%B0%E6%8D%AE%E6%A3%80%E7%B4%A2\"\u003e1.1 数据检索\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-%E7%B4%A2%E5%BC%95%E6%A6%82%E8%BF%B0\"\u003e1 索引概述\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-1-%E6%A6%82%E8%BF%B0\"\u003e1.1 概述\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-%E7%B4%A2%E5%BC%95%E5%87%BD%E6%95%B0\"\u003e1.2 索引函数\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-2-1-%E8%B0%83%E7%94%A8%E7%B4%A2%E5%BC%95%E5%87%BD%E6%95%B0\"\u003e1.2.1 调用索引函数\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-2-%E7%B4%A2%E5%BC%95%E5%87%BD%E6%95%B0\"\u003e1.2.2 索引函数\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-%E7%B4%A2%E5%BC%95%E5%AE%9E%E7%8E%B0\"\u003e2 索引实现\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#2-1-%E5%88%9B%E5%BB%BA%E7%B4%A2%E5%BC%95-ambuild\"\u003e2.1 创建索引 ambuild\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%80%E3%80%81build%E6%95%B4%E4%BD%93%E6%B5%81%E7%A8%8B\"\u003e一、build整体流程\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BA%8C%E3%80%81build%E6%8F%92%E5%85%A5tuple\"\u003e二、build插入tuple\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-2-%E7%B4%A2%E5%BC%95%E5%86%99%E5%85%A5%E6%95%B0%E6%8D%AE-aminsert\"\u003e2.2 索引写入数据 aminsert\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-operate\"\u003e3 operate\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"1-背景\"\u003e1 背景\u003c/h1\u003e\n\u003ch1 id=\"11-数据检索\"\u003e1.1 数据检索\u003c/h1\u003e\n\u003cp\u003e通常，应用会使用数据库存储大量数据，比如，单个表存储上百万、甚至上百亿条数据。此时，对表中数据进行某些查询时，将变得非常困难，比如等值查询、范围查询、模糊查询等。\u003c/p\u003e\n\u003ch1 id=\"1-索引概述\"\u003e1 索引概述\u003c/h1\u003e\n\u003ch2 id=\"11-概述\"\u003e1.1 概述\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e索引方式：postgresql共有5种索引\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e唯一索引：不能出现重复的值\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e主键索引：主键自动创建唯一索引\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e多属性索引：多个列（最多32列）\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e部分索引：WHERE过滤索引\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 示例\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINDEX\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e表达式索引：和部分索引没太大区别，都是额外调用1个函数\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 示例\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINDEX\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e索引分类：postgresql有多种索引，本文见介绍以下4种\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ebtree\u003c/li\u003e\n\u003cli\u003ehash\u003c/li\u003e\n\u003cli\u003egist\u003c/li\u003e\n\u003cli\u003egin\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e索引系统表\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003epg_am：存储所有索引的方法\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_am\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eamname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"n\"\u003eamhandler\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eamtype\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-------+-------------+--------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003ebtree\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ebthandler\u003c/span\u003e\u003cspan class=\"w\"\u003e   \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003ehash\u003c/span\u003e\u003cspan class=\"w\"\u003e   \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ehashhandler\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003egist\u003c/span\u003e\u003cspan class=\"w\"\u003e   \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egisthandler\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003egin\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eginhandler\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003espgist\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003espghandler\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003ebrin\u003c/span\u003e\u003cspan class=\"w\"\u003e   \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ebrinhandler\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003epg_index：存储所有索引，索引列的下标\u003c/p\u003e","title":"PostgreSQL 3-8 Index"},{"content":"1 概述 select reltuples,relhasoids,oid from pg_class where relname = \u0026#39;t1\u0026#39;; -- reltuples = 0 select pg_relation_filepath(\u0026#39;t1\u0026#39;); -- oid = filepath = relfilenode vacuum full t1; select reltuples,relhasoids,oid from pg_class where relname = \u0026#39;t1\u0026#39;; -- oid 不变, reltuples = 0 -- oid != filepath = relfilenode != analyze t1; -- reltuples = 2，即有效tuple 启动autovacuum进程\nstandard_ProcessUtility(Node *parsetree) case T_VacuumStmt: ExecVacuum(VacuumStmt *vacstmt) vacuum(RangeVar *relation, Oid relid, VacuumParams *params) ServerLoop(void) StartAutoVacLauncher(void) AutoVacLauncherMain() /* if fail: 发送信号重启aotuvacuum进程 */ SendPostmasterSignal(PMSIGNAL_START_AUTOVAC_WORKER) sigusr1_handler(SIGNAL_ARGS) if CheckPostmasterSignal(PMSIGNAL_START_AUTOVAC_WORKER): StartAutovacuumWorker(void) Backend *bn = malloc(); bn-\u0026gt;pid = StartAutoVacWorker(void) AutoVacWorkerMain(int argc, char *argv[])() BaseInit(); InitPostgres(NULL, dbid, NULL, InvalidOid, dbname) do_autovacuum() autovacuum_do_vac_analyze(autovac_table *tab) vacuum(RangeVar *relation, Oid relid, VacuumParams *params) proc_exit(0) dlist_push_head(\u0026amp;BackendList, \u0026amp;bn-\u0026gt;elem) 查找所有待vacuum的表 do_autovacuum(void) /* table-by-table */ StartTransactionCommand() /* 查询pg_database系统表 */ tuple = SearchSysCache1(DATABASEOID) /* 打开pg_class系统表 */ classRel = heap_open(RelationRelationId) pg_class_desc = CreateTupleDescCopy(RelationGetDescr(classRel)) /* 为toast表创建hash表 */ table_toast_map = hash_create() /* 遍历pg_class系统表，记录所有需要vacuum和analyze的普通表和系统表 */ relScan = heap_beginscan_catalog(classRel) while tuple = heap_getnext(relScan) != NULL: Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple) relid = HeapTupleGetOid(tuple) relopts = extract_autovac_opts(tuple, pg_class_desc) tabentry = get_pgstat_tabentry_relid(relid, classForm-\u0026gt;relisshared) /* 检查表是否需要被vacuum和analyze */ relation_needs_vacanalyze(relid, relopts, classForm, tabentry, \u0026amp;dovacuum, \u0026amp;doanalyze) if dovacuum || doanalyze: /* 普通表加入list中 */ table_oids = lappend_oid(table_oids, relid) /* toast表加入hash表中 */ if OidIsValid(classForm-\u0026gt;reltoastrelid): hentry = hash_search(table_toast_map, \u0026amp;classForm-\u0026gt;reltoastrelid, HASH_ENTER) hentry-\u0026gt;ar_relid = relid eap_endscan(relScan) /* 第二次遍历pg_class系统表 */ relScan = heap_beginscan_catalog(classRel) while tuple = heap_getnext(relScan) != NULL: Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple) relid = HeapTupleGetOid(tuple) relopts = extract_autovac_opts(tuple, pg_class_desc) ... bstrategy = GetAccessStrategy(BAS_VACUUM) /* 开始遍历所有list中的表 */ foreach(cell, table_oids) Oid relid = lfirst_oid(cell) /* 再次检查是否仍需vacuum */ tab = table_recheck_autovac(relid, table_toast_map, pg_class_desc) if tab == NULL: continue MyWorkerInfo-\u0026gt;wi_tableoid = relid autovac_balance_cost() AutoVacuumUpdateDelay() autovacuum_do_vac_analyze(tab, bstrategy) vac_update_datfrozenxid() CommitTransactionCommand() 对单个表进行vacuum\nautovacuum_do_vac_analyze(autovac_table *tab, BufferAccessStrategy bstrategy) autovac_report_activity(tab) vacuum(tab-\u0026gt;at_vacoptions, tab-\u0026gt;at_relid, bstrategy) { relations = get_rel_oids(relid, relation) /* if relid == InvalidOid: 遍历pg_class，否则直接返回 */ foreach(cur, relations): Oid relid = lfirst_oid(cur) if options \u0026amp; VACOPT_VACUUM: if !vacuum_rel(relid, relation, options, params) continue if options \u0026amp; VACOPT_ANALYZE: analyze_rel(relid, relation, options, params, val_cols) if options \u0026amp; VACOPT_VACUUM \u0026amp;\u0026amp; !IsAutoVacuumWorkerProcess(): /* 更新pg_database系统表，清空pg_clog */ vac_update_datfrozenxid() } /* 执行vacuum */ vacuum_rel(Oid relid, RangeVar *relation, int options) if !options \u0026amp; VACOPT_FULL: ... lmode = (options \u0026amp; VACOPT_FULL) ? AccessExclusiveLock : ShareUpdateExclusiveLock if !(options \u0026amp; VACOPT_NOWAIT): onerel = try_relation_open(relid, lmode) else if ConditionalLockRelationOid(relid, lmode): onerel = try_relation_open(relid, NoLock) / 检查权限 **/ if !pg_class_ownercheck(RelationGetRelid(onerel), GetUserId()) || pg_database_ownercheck(MyDatabaseId, GetUserId()): ereport() /* 检查表的类型 */ if onerel-\u0026gt;rd_rel-\u0026gt;relkind != {RELKIND_RELATION, RELKIND_MATVIEW, RELKIND_TOASTVALUE}: ereport() if RELATION_IS_OTHER_TEMP(onerel): return false if options \u0026amp; VACOPT_FULL: relation_close(onerel, NoLock) /* 执行VACUUM FULL：新建1个文件，把旧文件中的有效数据复制到新文件中 */ cluster_rel(relid, InvalidOid, false) { //cluster_rel(Oid tableOid, Oid indexOid, bool recheck, bool verbose) Relation OldHeap = try_relation_open(tableOid, AccessExclusiveLock) if recheck: /* 检查权限 */ rebuild_relation(OldHeap, indexOid, verbose) { is_system_catalog = IsSystemRelation(OldHeap) OIDNewHeap = make_new_heap(tableOid, tableSpace, AccessExclusiveLock) copy_heap_data(OIDNewHeap, tableOid, indexOid) { NewHeap = heap_open(OIDNewHeap, AccessExclusiveLock) OldHeap = heap_open(OIDOldHeap, AccessExclusiveLock) oldTupDesc = RelationGetDescr(OldHeap) newTupDesc = RelationGetDescr(NewHeap) vacuum_set_xid_limits(OldHeap, 0, 0, 0, 0, \u0026amp;OldestXmin, \u0026amp;FreezeXid) is_system_catalog = IsSystemRelation(OldHeap) rwstate = begin_heap_rewrite(OldHeap, NewHeap, OldestXmin, FreezeXid) if OldIndex != NULL \u0026amp;\u0026amp; !use_sort: indexScan = index_beginscan(OldHeap, OldIndex) else: /* 顺序扫描*/ heapScan = heap_beginscan(OldHeap) /* 顺序扫描所有tuple */ for (;;) tuple = heap_getnext(heapScan) buf = heapScan-\u0026gt;rs_cbuf switch (HeapTupleSatisfiesVacuum(tuple, OldestXmin, buf)): case HEAPTUPLE_DEAD: isdead = true case HEAPTUPLE_RECENTLY_DEAD: tups_recently_dead += 1 case HEAPTUPLE_LIVE: isdead = false case HEAPTUPLE_INSERT_IN_PROGRESS: isdead = false if isdead: if rewrite_heap_dead_tuple(rwstate, tuple): tups_vacuumed += 1 tups_recently_dead -= 1 continue num_tuples += 1 if tuplesort != NULL: tuplesort_putheaptuple(tuplesort, tuple) else: reform_and_rewrite_tuple(tuple, oldTupDesc, newTupDesc, values, isnull, rwstate) { heap_deform_tuple(tuple, oldTupDesc, values, isnull); copiedTuple = heap_form_tuple(newTupDesc, values, isnull) rewrite_heap_tuple(rwstate, tuple, copiedTuple) { /* rewrite_heap_tuple(RewriteState state,HeapTuple old_tuple, HeapTuple new_tuple) */ heap_freeze_tuple(new_tuple-\u0026gt;t_data, state-\u0026gt;rs_freeze_xid,state-\u0026gt;rs_cutoff_multi) ... raw_heap_insert(state, new_tuple) { log_newpage() /* 一次记录一个page */ smgrextend() } } } heap_endscan(heapScan) end_heap_rewrite(rwstate) } finish_heap_swap(tableOid, OIDNewHeap, is_system_catalog) } } else: /* 执行LAZY VACUUM */ lazy_vacuum_rel(onerel, options, params, vac_strategy) if onerel: relation_close(onerel, NoLock) if toast_relid != InvalidOid: vacuum_rel(toast_relid, relation, options, params) 2 工作流程 2.1 auto_vacuum AutoVacWorkerMain do_autovacuum table_beginscan_catalog for each: relation_needs_vacanalyze lappend_oid # 添加待vacuum表 for each: autovacuum_do_vac_analyze vacuum if not relation get_all_vacuum_rels table_beginscan_catalog for loop if not vacuum_is_relation_owner: continue for each: vacuum_rel analyze_rel vacuum_open_relation do_analyze_rel 2.2 vacuum standard_ProcessUtility ExecVacuum vacuum 2.3 vacuum relation standard_ProcessUtility ExecVacuum vacuum 2.4 opengauss vacuum or vacuum relation\nstandard_ProcessUtility DoVacuumMppTable do_vacuum_mpp_table_other_node vacuum get_rel_oids for each: vacuum_rel analyze_rel analyze_rel_internal ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/3-12-vacuum/","summary":"\u003ch1 id=\"1-概述\"\u003e1 概述\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eselect\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ereltuples\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003erelhasoids\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efrom\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_class\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ewhere\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erelname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- reltuples = 0\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eselect\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_relation_filepath\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- oid = filepath = relfilenode\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003evacuum\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efull\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eselect\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ereltuples\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003erelhasoids\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eoid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efrom\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_class\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ewhere\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erelname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- oid 不变, reltuples = 0\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- oid != filepath = relfilenode !=\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eanalyze\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- reltuples = 2，即有效tuple\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e启动autovacuum进程\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003estandard_ProcessUtility\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eNode\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eparsetree\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003eT_VacuumStmt\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003eExecVacuum\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eVacuumStmt\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003evacstmt\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nf\"\u003evacuum\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRangeVar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003erelation\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eOid\u003c/span\u003e \u003cspan class=\"n\"\u003erelid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eVacuumParams\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eparams\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003eServerLoop\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eStartAutoVacLauncher\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003eAutoVacLauncherMain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"cm\"\u003e/* if fail: 发送信号重启aotuvacuum进程 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nf\"\u003eSendPostmasterSignal\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ePMSIGNAL_START_AUTOVAC_WORKER\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003esigusr1_handler\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eSIGNAL_ARGS\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"nf\"\u003eCheckPostmasterSignal\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ePMSIGNAL_START_AUTOVAC_WORKER\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003eStartAutovacuumWorker\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eBackend\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ebn\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003emalloc\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003ebn\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003epid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eStartAutoVacWorker\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"nf\"\u003eAutoVacWorkerMain\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eargc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003echar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eargv\u003c/span\u003e\u003cspan class=\"p\"\u003e[])()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003eBaseInit\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003eInitPostgres\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003edbid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eInvalidOid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003edbname\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003edo_autovacuum\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"nf\"\u003eautovacuum_do_vac_analyze\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eautovac_table\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003etab\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"nf\"\u003evacuum\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRangeVar\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003erelation\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eOid\u003c/span\u003e \u003cspan class=\"n\"\u003erelid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eVacuumParams\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eparams\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"nf\"\u003eproc_exit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"nf\"\u003edlist_push_head\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eBackendList\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003ebn\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eelem\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col start=\"2\"\u003e\n\u003cli\u003e查找所有待vacuum的表\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003edo_autovacuum\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* table-by-table */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eStartTransactionCommand\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* 查询pg_database系统表 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003etuple\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eSearchSysCache1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eDATABASEOID\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* 打开pg_class系统表 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eclassRel\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eheap_open\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eRelationRelationId\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_class_desc\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eCreateTupleDescCopy\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nf\"\u003eRelationGetDescr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eclassRel\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* 为toast表创建hash表 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003etable_toast_map\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003ehash_create\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* 遍历pg_class系统表，记录所有需要vacuum和analyze的普通表和系统表 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003erelScan\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eheap_beginscan_catalog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eclassRel\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"n\"\u003etuple\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eheap_getnext\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelScan\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eForm_pg_class\u003c/span\u003e \u003cspan class=\"n\"\u003eclassForm\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eForm_pg_class\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"nf\"\u003eGETSTRUCT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etuple\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003erelid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eHeapTupleGetOid\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etuple\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003erelopts\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eextract_autovac_opts\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etuple\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003epg_class_desc\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003etabentry\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eget_pgstat_tabentry_relid\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eclassForm\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003erelisshared\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"cm\"\u003e/* 检查表是否需要被vacuum和analyze */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003erelation_needs_vacanalyze\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003erelopts\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eclassForm\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003etabentry\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003edovacuum\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003edoanalyze\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003edovacuum\u003c/span\u003e \u003cspan class=\"o\"\u003e||\u003c/span\u003e \u003cspan class=\"nl\"\u003edoanalyze\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"cm\"\u003e/* 普通表加入list中 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003etable_oids\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003elappend_oid\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etable_oids\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003erelid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"cm\"\u003e/* toast表加入hash表中 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"nf\"\u003eOidIsValid\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eclassForm\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ereltoastrelid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003ehentry\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003ehash_search\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etable_toast_map\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eclassForm\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ereltoastrelid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eHASH_ENTER\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003ehentry\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ear_relid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erelid\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eeap_endscan\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelScan\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* 第二次遍历pg_class系统表 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003erelScan\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eheap_beginscan_catalog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eclassRel\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ewhile\u003c/span\u003e \u003cspan class=\"n\"\u003etuple\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eheap_getnext\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelScan\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eForm_pg_class\u003c/span\u003e \u003cspan class=\"n\"\u003eclassForm\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eForm_pg_class\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"nf\"\u003eGETSTRUCT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etuple\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003erelid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eHeapTupleGetOid\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etuple\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003erelopts\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eextract_autovac_opts\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etuple\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003epg_class_desc\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ebstrategy\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003eGetAccessStrategy\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eBAS_VACUUM\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* 开始遍历所有list中的表 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eforeach\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecell\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003etable_oids\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eOid\u003c/span\u003e \u003cspan class=\"n\"\u003erelid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003elfirst_oid\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecell\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"cm\"\u003e/* 再次检查是否仍需vacuum */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003etab\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003etable_recheck_autovac\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003erelid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003etable_toast_map\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003epg_class_desc\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003etab\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003econtinue\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eMyWorkerInfo\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ewi_tableoid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003erelid\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003eautovac_balance_cost\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003eAutoVacuumUpdateDelay\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003eautovacuum_do_vac_analyze\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etab\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ebstrategy\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003evac_update_datfrozenxid\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eCommitTransactionCommand\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e对单个表进行vacuum\u003c/p\u003e","title":"PostgreSQL 3-9 Vacuum"},{"content":"1 本地自测 1.1 快速tpcc vkill rm -rf $GAUSSHOME/data* # cp -r ~/w100_t200/data $GAUSSHOME/data # cp -r ~/w100_t200/data1 $GAUSSHOME/ cp -r ~/w5/data $GAUSSHOME/data cp -r ~/w5/data1 $GAUSSHOME/ # cp -r ~/w100/data $GAUSSHOME/data # cp -r ~/w100/data1 $GAUSSHOME/ # vb_guc set -D $GAUSSHOME/data -c \u0026#34;enable_ddl_logical_decode=on\u0026#34; # vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;enable_ddl_logical_decode=on\u0026#34; # vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;max_replication_slots=50\u0026#34; # vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;max_background_workers=50\u0026#34; # vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;max_logical_replication_workers=50\u0026#34; vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;max_connections=4000\u0026#34; vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;enable_audit=on\u0026#34; vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;audit_buffer_size=262144\u0026#34; vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;audit_directory_size=1073741824\u0026#34; vb_ctl start -D $GAUSSHOME/data vb_ctl start -D $GAUSSHOME/data1 # 五、发布端（发布） vsql -d pubdb -p 64000 -c \u0026#34;CREATE PUBLICATION pub1 FOR all tables WITH (ddl=\u0026#39;all\u0026#39;);\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; # # 六、订阅端（订阅） gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription vsql -d pubdb -p 65000 -c \u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=220);\u0026#34; # # vsql -d pubdb -p 65000 -r # \\q # cd ~/tpcc # source envbm # ./toolbm run vpub # 换窗口查询 vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; # 场景一：验证内存 vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM gs_thread_memory_context ORDER BY totalsize DESC limit 30;\u0026#34; \u0026gt; start_pub.mem vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM gs_shared_memory_detail ORDER BY totalsize DESC limit 30;;\u0026#34; \u0026gt;\u0026gt; start_pub.mem vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM gs_thread_memory_context ORDER BY totalsize DESC limit 30;;\u0026#34; \u0026gt; start_sub.mem vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM gs_shared_memory_detail ORDER BY totalsize DESC limit 30;;\u0026#34; \u0026gt;\u0026gt; start_sub.mem # 场景八：验证数据一致性 vsql -d pubdb -p 64000 -c \u0026#34;DROP TABLE IF EXISTS tcnt\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;CREATE TABLE tcnt (c1 TEXT,c2 INT);\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;DROP TABLE IF EXISTS tcnt\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;CREATE TABLE tcnt (c1 TEXT,c2 INT);\u0026#34; for t in bmsql_config bmsql_customer bmsql_district bmsql_history bmsql_item bmsql_new_order bmsql_oorder bmsql_order_line bmsql_stock bmsql_warehouse; do echo \u0026#34;$t\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;INSERT INTO tcnt VALUES(\u0026#39;$t\u0026#39;, (SELECT count(1) FROM $t));\u0026#34; done; for t in bmsql_config bmsql_customer bmsql_district bmsql_history bmsql_item bmsql_new_order bmsql_oorder bmsql_order_line bmsql_stock bmsql_warehouse; do echo \u0026#34;$t\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;INSERT INTO tcnt VALUES(\u0026#39;$t\u0026#39;, (SELECT count(1) FROM $t));\u0026#34; done; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM tcnt\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM tcnt;\u0026#34; # 场景一：重启订阅端（kill） for i in $(seq 0 10); do echo \u0026#34;$i------------------------------------------------------------------------------------\u0026#34; ps ux | grep \u0026#39;vastbase.*-D.*/data1\u0026#39; | grep -v grep | awk \u0026#39;{print $2}\u0026#39; | xargs kill -9 vb_ctl start -D $GAUSSHOME/data1 sleep 7 vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; \u0026gt;\u0026gt; a.out done; # 场景二：重启订阅端(stop) for i in $(seq 0 10); do echo \u0026#34;$i------------------------------------------------------------------------------------\u0026#34; echo \u0026#34;$i------------------------------------------------------------------------------------\u0026#34; \u0026gt;\u0026gt; a.out vb_ctl stop -D $GAUSSHOME/data1 vb_ctl start -D $GAUSSHOME/data1 vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; \u0026gt;\u0026gt; a.out sleep 7 vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; \u0026gt;\u0026gt; a.out done; # 场景三：重启发布端 vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; vb_ctl stop -D $GAUSSHOME/data sleep 5 vb_ctl start -D $GAUSSHOME/data vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; vb_ctl restart -D $GAUSSHOME/data1 # 场景三：重建 subscription for i in $(seq 0 10); do echo \u0026#34;$i------------------------------------------------------------------------------------\u0026#34; echo \u0026#34;$i------------------------------------------------------------------------------------\u0026#34; \u0026gt;\u0026gt; a.out vsql -d pubdb -p 65000 -c \u0026#34;DROP SUBSCRIPTION sub1;\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=20);\u0026#34; sleep 6 vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; \u0026gt;\u0026gt; a.out done; vsql -d pubdb -p 65000 -c \u0026#34;DROP SUBSCRIPTION sub1;\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=20);\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM pg_subscription_rel\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; SELECT pg_wal_lsn_diff(pg_current_wal_lsn(), \u0026#39;0/0\u0026#39;) / (1024 * 1024); # 场景五：ddl vsql -d pubdb -p 64000 -c \u0026#34;\\d\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;\\d\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;DROP TABLE bmsql_warehouse\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;CREATE TABLE t3(c1 INT)\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;\\d\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;\\d\u0026#34; # 场景六：多个发布订阅 vsql -d postgres -p 64000 -c \u0026#34;CREATE DATABASE db3;\u0026#34; vsql -d db3 -p 64000 -c \u0026#34;CREATE TABLE t3(c1 INT PRIMARY KEY, c2 TEXT);\u0026#34; vsql -d db3 -p 64000 -c \u0026#34;CREATE PUBLICATION pub3 FOR all tables WITH (ddl=\u0026#39;all\u0026#39;);\u0026#34; vsql -d db3 -p 64000 -c \u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot3\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; vsql -d postgres -p 65000 -c \u0026#34;CREATE DATABASE db3;\u0026#34; vsql -d db3 -p 65000 -c \u0026#34;CREATE TABLE t3(c1 INT PRIMARY KEY, c2 TEXT);\u0026#34; vsql -d db3 -p 65000 -c \u0026#34;CREATE SUBSCRIPTION sub3 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=db3 user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub3 WITH (create_slot=false, slot_name = \u0026#39;pslot3\u0026#39;, copy_data = false, worker_number=20);\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;DROP SUBSCRIPTION sub1;\u0026#34; for i in $(seq 0 10); do vsql -d db3 -p 64000 -c \u0026#34;BEGIN; INSERT INTO t3 VALUES($i,\u0026#39;a\u0026#39;); UPDATE t3 SET c2=\u0026#39;b\u0026#39; WHERE c1=$i-1; COMMIT;\u0026#34; \u0026amp; done; wait # 跑10分钟 ./toolbm run vpub vsql -d pubdb -p 65000 -c \u0026#34;DROP SUBSCRIPTION sub1;\u0026#34; # for t in bmsql_config bmsql_customer bmsql_district bmsql_history bmsql_item bmsql_new_order bmsql_oorder bmsql_order_line bmsql_stock bmsql_warehouse; do echo \u0026#34;$t\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;TRUNCATE $t\u0026#34; done; 续点重传 vkill rm -rf $GAUSSHOME/data* # cp -r ~/w5/data $GAUSSHOME/data # cp -r ~/w5/data1 $GAUSSHOME/ cp -r ~/w100/data $GAUSSHOME/data cp -r ~/w100/data1 $GAUSSHOME/ vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;max_connections=4000\u0026#34; vb_ctl start -D $GAUSSHOME/data vb_ctl start -D $GAUSSHOME/data1 # 五、发布端（发布） vsql -d pubdb -p 64000 -c \u0026#34;CREATE PUBLICATION pub1 FOR all tables WITH (ddl=\u0026#39;all\u0026#39;);\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; # # 六、订阅端（订阅） gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription vsql -d pubdb -p 65000 -c \u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=220);\u0026#34; # # vsql -d pubdb -p 65000 -r # \\q vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; # ./toolbm run vpub # 重启订阅端（kill） for i in $(seq 0 10); do echo \u0026#34;$i------------------------------------------------------------------------------------\u0026#34; ps ux | grep \u0026#39;vastbase.*-D.*/data1\u0026#39; | grep -v grep | awk \u0026#39;{print $2}\u0026#39; | xargs kill -9 vb_ctl start -D $GAUSSHOME/data1 sleep 7 vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; \u0026gt;\u0026gt; a.out done; vsql -d pubdb -p 64000 -c \u0026#34; SELECT * FROM pg_get_replication_slots(); \u0026#34; vsql -d pubdb -p 64000 -c \u0026#34; SELECT pg_current_wal_lsn();\u0026#34; # 验证数据一致性 vsql -d pubdb -p 64000 -c \u0026#34;DROP TABLE IF EXISTS tcnt\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;CREATE TABLE tcnt (c1 TEXT,c2 INT);\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;DROP TABLE IF EXISTS tcnt\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;CREATE TABLE tcnt (c1 TEXT,c2 INT);\u0026#34; for t in bmsql_config bmsql_customer bmsql_district bmsql_history bmsql_item bmsql_new_order bmsql_oorder bmsql_order_line bmsql_stock bmsql_warehouse; do echo \u0026#34;$t\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;INSERT INTO tcnt VALUES(\u0026#39;$t\u0026#39;, (SELECT count(1) FROM $t));\u0026#34; done; for t in bmsql_config bmsql_customer bmsql_district bmsql_history bmsql_item bmsql_new_order bmsql_oorder bmsql_order_line bmsql_stock bmsql_warehouse; do echo \u0026#34;$t\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;INSERT INTO tcnt VALUES(\u0026#39;$t\u0026#39;, (SELECT count(1) FROM $t));\u0026#34; done; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM tcnt\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM tcnt;\u0026#34; -- ===================== worker_number ======================= CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false); DROP SUBSCRIPTION sub1; \\! vsql -d pubdb -p 64000 -c \u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; CREATE SUBSCRIPTION sub2 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=1); DROP SUBSCRIPTION sub2; \\! vsql -d pubdb -p 64000 -c \u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; CREATE SUBSCRIPTION sub3 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=2); DROP SUBSCRIPTION sub3; \\! vsql -d pubdb -p 64000 -c \u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; CREATE SUBSCRIPTION sub4 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=200); DROP SUBSCRIPTION sub4; \\! vsql -d pubdb -p 64000 -c \u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; CREATE SUBSCRIPTION sub5 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=400); DROP SUBSCRIPTION sub5; CREATE SUBSCRIPTION sub6 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=1000); DROP SUBSCRIPTION sub6; -- ===================== copy_data ======================= -- do truncate fist CREATE SUBSCRIPTION sub21 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = true, worker_number=50); SELECT * FROM pg_subscription_rel; DROP SUBSCRIPTION sub21; -- copy and stop -- ===================== cache file ======================= -- 1. drop subscription -- 2. kill progress -- ===================== 断点续传 ======================= vsql -d postgres -p 50000 -c \u0026#34;DROP TABLE IF EXISTS t1\u0026#34; vsql -d postgres -p 50000 -c \u0026#34;CREATE TABLE t1(c1 INT, c2 TEXT)\u0026#34; for i in $(seq 0 10); do vsql -d postgres -p 50000 -c \u0026#34;BEGIN; INSERT INTO t1 VALUES($i,\u0026#39;a\u0026#39;); UPDATE t1 SET c2=\u0026#39;b\u0026#39; WHERE c1=$i-1; COMMIT;\u0026#34; \u0026amp; done vsql -d postgres -p 50000 -c \u0026#34;SELECT * FROM t1 ORDER BY c1\u0026#34; parallel_apply.source 1 自测 批量验证 初始化模板 export VDATA=~/g100/rep/data vb_guc set -D $VDATA -c \u0026#34;port=64000\u0026#34; vb_guc set -D $VDATA -c \u0026#34;max_connection=2000\u0026#34; vb_guc set -D $VDATA -c \u0026#34;wal_level=logical\u0026#34; vb_guc set -D $VDATA -c \u0026#34;max_replication_slots=100\u0026#34; vb_guc set -D $VDATA -c \u0026#34;max_background_workers=100\u0026#34; vb_guc set -D $VDATA -c \u0026#34;max_logical_replication_workers=100\u0026#34; sed -i \u0026#39;1i host all all 0.0.0.0/0 sha256\\n\u0026#39; $VDATA/pg_hba.conf echo \u0026#34;host replication all 0.0.0.0/0 sha256\u0026#34; \u0026gt;\u0026gt; $VDATA/pg_hba.conf insert性能 export VDATA=~/g100/rep/data vkill rm -rf ~/g100/rep/data cp -r ~/g100/rep/temp ~/g100/rep/data vstart vsql -d postgres -p 64000 -r -- 3 create publicatioin \\c postgres CREATE DATABASE pubdb; \\c pubdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); CREATE PUBLICATION pub1 FOR all tables; CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); -- sub CREATE DATABASE subdb; \\c subdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); \\! gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name=\u0026#39;pslot1\u0026#39;, copy_data=false, worker_number=80); SELECT count(1) FROM t1; SELECT * FROM vb_parallel_apply_stat(); \\c pubdb truncate t1; \\c subdb truncate t1; SELECT datname,state,length(query) FROM pg_stat_activity WHERE datname = \u0026#39;pubdb\u0026#39;; 多个发布订阅 vb_guc set -D ~/g100/rep/data -c \u0026#34;max_replication_slots=256\u0026#34; vb_guc set -D ~/g100/rep/data -c \u0026#34;max_background_workers=256\u0026#34; vb_guc set -D ~/g100/rep/data -c \u0026#34;max_logical_replication_workers=256\u0026#34; export VDATA=~/g100/rep/data vkill rm -rf ~/g100/rep/data cp -r ~/g100/rep/temp ~/g100/rep/data vb_guc set -D ~/g100/rep/data -c \u0026#34;enable_ddl_logical_decode=on\u0026#34; vb_guc set -D ~/g100/rep/data -c \u0026#34;max_wal_senders=36\u0026#34; vb_guc set -D ~/g100/rep/data -c \u0026#34;max_replication_slots=256\u0026#34; vb_guc set -D ~/g100/rep/data -c \u0026#34;max_background_workers=256\u0026#34; vb_guc set -D ~/g100/rep/data -c \u0026#34;max_logical_replication_workers=256\u0026#34; vb_guc set -D ~/g100/rep/data -c \u0026#34;max_connections=1000\u0026#34; vstart rm -rf ~/g100/rep/data1 vb_guc set -D ~/g100/rep/data1 -c \u0026#34;port=65000\u0026#34; cp -r ~/g100/rep/temp ~/g100/rep/data1 vb_ctl start -D ~/g100/rep/data1 # 发布 vsql -d postgres -p 64000 -c \u0026#34;CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;;\u0026#34; for i in $(seq 0 11); do vsql -d postgres -p 64000 -c \u0026#34;CREATE DATABASE pubdb$i;\u0026#34; vsql -d pubdb$i -p 64000 -c \u0026#34;CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT);\u0026#34; vsql -d pubdb$i -p 64000 -c \u0026#34;CREATE PUBLICATION pub$i FOR all tables;\u0026#34; vsql -d pubdb$i -p 64000 -c \u0026#34;SELECT pg_create_logical_replication_slot(\u0026#39;pslot$i\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; done; # 5 load data for i in $(seq 0 11); do for j in $(seq 0 10); do vsql -d pubdb$i -p 64000 -c \u0026#34;BEGIN; INSERT INTO t1 VALUES($j,\u0026#39;a\u0026#39;); UPDATE t1 SET c2=\u0026#39;b\u0026#39; WHERE c1=$j-1; COMMIT;\u0026#34; \u0026amp; done; sleep 2 done; wait # 订阅 gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription for i in $(seq 0 11); do vsql -d postgres -p 65000 -c \u0026#34;CREATE DATABASE subdb$i;\u0026#34; vsql -d subdb$i -p 65000 -c \u0026#34;CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT);\u0026#34; vsql -d subdb$i -p 65000 -c \u0026#34;CREATE SUBSCRIPTION sub$i CONNECTION \u0026#39;host=127.0.0.1 port=64001 dbname=pubdb$i user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub$i WITH (create_slot=false, slot_name = \u0026#39;pslot$i\u0026#39;, copy_data = false, worker_number=30);\u0026#34; done; sleep 5 # 6 check for i in $(seq 0 11); do vsql -d pubdb$i -p 64000 -c \u0026#34;SELECT count(1) FROM t1\u0026#34; done; for i in $(seq 0 11); do vsql -d subdb$i -p 65000 -c \u0026#34;SELECT count(1) FROM t1\u0026#34; done; vsql -d postgres -p 64000 -c \u0026#34; SELECT * FROM pg_get_replication_slots();\u0026#34; vsql -d postgres -p 65000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; # 7 cleanup DROP SUBSCRIPTION sub1; \\c postgres DROP DATABASE IF EXISTS pubdb; DROP DATABASE IF EXISTS subdb; DROP USER pu1; copydata export VDATA=~/g100/rep/data vkill rm -rf ~/g100/rep/data cp -r ~/g100/rep/temp ~/g100/rep/data vstart rm -rf ~/g100/rep/data1 cp -r ~/g100/rep/temp ~/g100/rep/data1 vb_guc set -D ~/g100/rep/data1 -c \u0026#34;port=65000\u0026#34; vb_ctl start -D ~/g100/rep/data1 vsql -d postgres -p 64000 -r -- 3 create publicatioin -- pub \\c postgres CREATE DATABASE pubdb; \\c pubdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); CREATE PUBLICATION pub1 FOR all tables; -- CREATE PUBLICATION pub1 FOR TABLE t1,t2; CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; -- INSERT INTO t1 VALUES(1,\u0026#39;a\u0026#39;),(2,\u0026#39;b\u0026#39;),(3,\u0026#39;c\u0026#39;); -- INSERT INTO t1 (c1,c2) SELECT i,\u0026#39;BASE_\u0026#39; || i || \u0026#39;_\u0026#39; || repeat(\u0026#39;X\u0026#39;, 13000) FROM generate_series(1, 10000) AS i; \\q -- for i in $(seq 0 1000); do vsql -d pubdb -p 64000 -c \u0026#34;INSERT INTO t1 VALUES($i,\u0026#39;a\u0026#39;); \u0026#34; ; done vsql -d postgres -p 65000 -r -- sub CREATE DATABASE subdb; \\c subdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); \\! gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (copy_data=false, worker_number=10); -- \\! for i in $(seq 20000 20010); do vsql -d pubdb -p 64000 -c \u0026#34;INSERT INTO t1 VALUES($i,\u0026#39;a\u0026#39;); \u0026#34; ; done SELECT * FROM t1; SELECT * FROM vb_parallel_apply_stat(); vsql -d pubdb -p 64000 -c \u0026#34;SELECT count(1) FROM t1\u0026#34; vsql -d subdb -p 65000 -c \u0026#34;SELECT count(1) FROM t1\u0026#34; vsql -d subdb -p 65000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; SELECT * FROM pg_replication_slots; INSERT INTO t1 VALUES(4,\u0026#39;a\u0026#39;),(5,\u0026#39;b\u0026#39;),(6,\u0026#39;c\u0026#39;); ddl export VDATA=~/g100/rep/data vkill rm -rf ~/g100/rep/data cp -r ~/g100/rep/temp ~/g100/rep/data vb_guc set -D ~/g100/rep/data -c \u0026#34;enable_ddl_logical_decode=on\u0026#34; vstart rm -rf ~/g100/rep/data1 cp -r ~/g100/rep/temp ~/g100/rep/data1 vb_guc set -D ~/g100/rep/data1 -c \u0026#34;port=65000\u0026#34; vb_ctl start -D ~/g100/rep/data1 vsql -d postgres -p 64000 -r -- 3 create publicatioin -- pub \\c postgres CREATE DATABASE pubdb; \\c pubdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); CREATE PUBLICATION pub1 FOR all tables WITH (publish=\u0026#39;insert,update,delete,truncate\u0026#39;, ddl=\u0026#39;all\u0026#39;); -- CREATE PUBLICATION pub1 FOR TABLE t1,t2; CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; -- INSERT INTO t1 VALUES(1,\u0026#39;a\u0026#39;),(2,\u0026#39;b\u0026#39;),(3,\u0026#39;c\u0026#39;); \\q vsql -d postgres -p 65000 -r -- sub CREATE DATABASE subdb; \\c subdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); \\! gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (copy_data=true, worker_number=4); SELECT * FROM t1; \\! vsql -d pubdb -p 64000 -c \u0026#34;TRUNCATE t1\u0026#34; \\! sleep 1 SELECT * FROM t1; \\! vsql -d pubdb -p 64000 -c \u0026#34;DROP TABLE t1\u0026#34; \\! sleep 1 SELECT * FROM t1; SELECT * FROM pg_replication_slots; INSERT INTO t1 VALUES(4,\u0026#39;a\u0026#39;),(5,\u0026#39;b\u0026#39;),(6,\u0026#39;c\u0026#39;); sub-txn + ddl export VDATA=~/g100/rep/data vkill rm -rf ~/g100/rep/data cp -r ~/g100/rep/temp ~/g100/rep/data vb_guc set -D ~/g100/rep/data -c \u0026#34;enable_ddl_logical_decode=on\u0026#34; vstart rm -rf ~/g100/rep/data1 cp -r ~/g100/rep/temp ~/g100/rep/data1 vb_guc set -D ~/g100/rep/data1 -c \u0026#34;port=65000\u0026#34; vb_ctl start -D ~/g100/rep/data1 vsql -d postgres -p 64000 -r -- 3 create publicatioin -- pub \\c postgres CREATE DATABASE pubdb; \\c pubdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); CREATE PUBLICATION pub1 FOR all tables WITH (publish=\u0026#39;insert,update,delete,truncate\u0026#39;, ddl=\u0026#39;all\u0026#39;); -- CREATE PUBLICATION pub1 FOR TABLE t1,t2; CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; INSERT INTO t1 VALUES(1,\u0026#39;a\u0026#39;),(2,\u0026#39;b\u0026#39;),(3,\u0026#39;c\u0026#39;); \\q vsql -d postgres -p 65000 -r -- sub CREATE DATABASE subdb; \\c subdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); \\! gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (copy_data=true, worker_number=4); SELECT * FROM t1; \\! vsql -d pubdb -p 64000 -c \u0026#34;TRUNCATE t1\u0026#34; \\! sleep 1 SELECT * FROM t1; \\! vsql -d pubdb -p 64000 -c \u0026#34;DROP TABLE t1\u0026#34; \\! sleep 1 SELECT * FROM t1; \\! vsql -d pubdb -p 64000 -c \u0026#34;BEGIN; CREATE TABLE t3(c1 int); SAVEPOINT sp1; INSERT INTO t3 VALUES(3); SAVEPOINT sp2; TRUNCATE t3; SAVEPOINT sp3; COMMIT;\u0026#34; SELECT * FROM t3; DROP TABLE t3; SELECT * FROM pg_replication_slots; INSERT INTO t1 VALUES(4,\u0026#39;a\u0026#39;),(5,\u0026#39;b\u0026#39;),(6,\u0026#39;c\u0026#39;); disable export VDATA=~/g100/rep/data vkill rm -rf ~/g100/rep/data cp -r ~/g100/rep/temp ~/g100/rep/data vstart rm -rf ~/g100/rep/data1 cp -r ~/g100/rep/temp ~/g100/rep/data1 vb_guc set -D ~/g100/rep/data1 -c \u0026#34;port=65000\u0026#34; vb_ctl start -D ~/g100/rep/data1 vsql -d postgres -p 64000 -r -- 3 create publicatioin -- pub \\c postgres CREATE DATABASE pubdb; \\c pubdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); CREATE PUBLICATION pub1 FOR all tables WITH (ddl=\u0026#39;all\u0026#39;); -- CREATE PUBLICATION pub1 FOR TABLE t1,t2; CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; INSERT INTO t1 VALUES(1,\u0026#39;a\u0026#39;),(2,\u0026#39;b\u0026#39;),(3,\u0026#39;c\u0026#39;); \\q vsql -d postgres -p 65000 -r -- sub CREATE DATABASE subdb; \\c subdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); \\! gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (copy_data=true, worker_number=4); SELECT * FROM t1; -- SELECT * FROM pg_replication_slots; SELECT * FROM pg_stat_subscription; ALTER SUBSCRIPTION sub1 DISABLE; \\! vsql -d pubdb -p 64000 -c \u0026#34;INSERT INTO t1 VALUES(4,\u0026#39;a\u0026#39;),(5,\u0026#39;b\u0026#39;),(6,\u0026#39;c\u0026#39;);\u0026#34; SELECT * FROM t1; ALTER SUBSCRIPTION sub1 ENABLE; SELECT * FROM pg_replication_slots; 基础场景 vkill vinit -- 1 config vb_guc set -D $GAUSSHOME/data -c \u0026#34;wal_level=logical\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_replication_slots=100\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_background_workers=100\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_logical_replication_workers=100\u0026#34; sed -i \u0026#39;1i host all all 0.0.0.0/0 sha256\\n\u0026#39; $GAUSSHOME/data/pg_hba.conf echo \u0026#34;host replication all 0.0.0.0/0 sha256\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/pg_hba.conf -- 2 startup vstart vsql -d postgres -p 50000 -r -- 3 create publicatioin \\c postgres CREATE DATABASE pubdb; \\c pubdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); CREATE PUBLICATION pub1 FOR all tables; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; -- 4 create subscription CREATE DATABASE subdb; \\c subdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); \\! gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription \\! vsql -d subdb -p 50000 -c \u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=50001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false);\u0026#34; -- , worker_number=30 -- 172.16.103.90 \\c pubdb INSERT INTO t1 VALUES(1,\u0026#39;a\u0026#39;),(2,\u0026#39;b\u0026#39;),(3,\u0026#39;c\u0026#39;); UPDATE t1 SET c1 = 2 WHERE c2 = \u0026#39;c\u0026#39;; INSERT INTO t1 VALUES(4,\u0026#39;d\u0026#39;); BEGIN; INSERT INTO t1 VALUES(5,\u0026#39;e\u0026#39;); UPDATE t1 SET c1 = 1 WHERE c2 = \u0026#39;b\u0026#39;; INSERT INTO t1 VALUES(6,\u0026#39;f\u0026#39;); COMMIT; BEGIN; INSERT INTO t1 VALUES(7,\u0026#39;d\u0026#39;); UPDATE t1 SET c2 = \u0026#39;a\u0026#39; WHERE c1 = 2; COMMIT; -- 5 load data \\! for i in $(seq 0 10); do vsql -d pubdb -p 50000 -c \u0026#34;BEGIN; INSERT INTO t1 VALUES($i,\u0026#39;a\u0026#39;); UPDATE t1 SET c2=\u0026#39;b\u0026#39; WHERE c1=$i-1; COMMIT;\u0026#34; \u0026gt; /dev/null 2\u0026gt;\u0026amp;1 \u0026amp; done; wait \\! sleep 3 -- 5 check subscription \\o pubdb.out \\c pubdb SELECT * FROM t1 ORDER BY c1; \\o \\o subdb.out \\c subdb SELECT * FROM t1 ORDER BY c1; \\o \\! grep -Irn \u0026#34;rows\u0026#34; pubdb.out \\! grep -Irn \u0026#34;rows\u0026#34; subdb.out \\! diff pubdb.out subdb.out \\! cat subdb.out \\! rm -f pubdb.out subdb.out -- 7 cleanup DROP SUBSCRIPTION sub1; \\c postgres DROP DATABASE IF EXISTS pubdb; DROP DATABASE IF EXISTS subdb; DROP USER pu1; 空库feedback vkill rm -rf $GAUSSHOME/data* cp -r ~/w5/data $GAUSSHOME/data cp -r ~/w5/data1 $GAUSSHOME/ vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;max_connections=4000\u0026#34; vb_ctl start -D $GAUSSHOME/data vb_ctl start -D $GAUSSHOME/data1 # 五、发布端（发布） vsql -d pubdb -p 64000 -c \u0026#34;CREATE PUBLICATION pub1 FOR all tables WITH (ddl=\u0026#39;all\u0026#39;);\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;CREATE DATABASE db1\u0026#34;; vsql -d pubdb -p 64000 -c \u0026#34;CREATE DATABASE db2\u0026#34;; vsql -d db1 -p 64000 -c \u0026#34;CREATE PUBLICATION p1 FOR all tables WITH (ddl=\u0026#39;all\u0026#39;);\u0026#34; vsql -d db1 -p 64000 -c \u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;ps1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; vsql -d db2 -p 64000 -c \u0026#34;CREATE PUBLICATION p2 FOR all tables WITH (ddl=\u0026#39;all\u0026#39;);\u0026#34; vsql -d db2 -p 64000 -c \u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;ps2\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; # 六、订阅端（订阅） gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription vsql -d pubdb -p 65000 -c \u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=220);\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;CREATE DATABASE db1\u0026#34;; vsql -d pubdb -p 65000 -c \u0026#34;CREATE DATABASE db2\u0026#34;; vsql -d db1 -p 65000 -c \u0026#34;CREATE SUBSCRIPTION s1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=db1 user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION p1 WITH (create_slot=false, slot_name = \u0026#39;ps1\u0026#39;, copy_data = false, worker_number=220);\u0026#34; vsql -d db2 -p 65000 -c \u0026#34;CREATE SUBSCRIPTION s2 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=db2 user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION p2 WITH (create_slot=false, slot_name = \u0026#39;ps2\u0026#39;, copy_data = false, worker_number=220);\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;CREATE VIEW pstat AS SELECT slot_name,active,confirmed_flush, (pg_wal_lsn_diff(confirmed_flush, \u0026#39;0/0\u0026#39;) / (1024 * 1024))::int as confirmed_lsn FROM pg_get_replication_slots();\u0026#34; # 查看复制进度 vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM pstat\u0026#34; # 查看速度 vsql -d pubdb -p 64000 -c \u0026#34;SELECT (pg_wal_lsn_diff(pg_current_wal_lsn(), \u0026#39;0/0\u0026#39;) / (1024 * 1024))::int as mb\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; 子事务 1. 这是一个基于opengauss开发的数据 2. 我已经设置了一些alias命令。全量编译vcmake。增量编译：vrecmake。启动集群：vinit, vstart。强制停止集群：vkill。 3. core文件目录：/data/ 4. 并行逻辑复制关键代码：parallel_apply.cpp 5. $GAUSSHOME也就是install目录下，所有文件都是临时生成的，随便动 vkill vinit -- 1 config vb_guc set -D $GAUSSHOME/data -c \u0026#34;wal_level=logical\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_replication_slots=100\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_background_workers=100\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_logical_replication_workers=100\u0026#34; # vb_guc set -D $GAUSSHOME/data -c \u0026#34;enable_audit=on\u0026#34; # vb_guc set -D $GAUSSHOME/data -c \u0026#34;audit_buffer_size=262144\u0026#34; # vb_guc set -D $GAUSSHOME/data -c \u0026#34;audit_directory_size=1073741824\u0026#34; sed -i \u0026#39;1i host all all 0.0.0.0/0 sha256\\n\u0026#39; $GAUSSHOME/data/pg_hba.conf echo \u0026#34;host replication all 0.0.0.0/0 sha256\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/pg_hba.conf -- 2 startup vstart vsql -d postgres -p 50000 -r -- 3 create publicatioin \\c postgres CREATE DATABASE pubdb; \\c pubdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); CREATE PUBLICATION pub1 FOR all tables; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; -- 4 create subscription CREATE DATABASE subdb; \\c subdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); \\! gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription \\! vsql -d subdb -p 50000 -c \u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=50001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=20);\u0026#34; -- , worker_number=30 -- 172.16.103.90 \\c pubdb BEGIN; INSERT INTO t1 VALUES(1,\u0026#39;111\u0026#39;); -- 假如xid=1 SAVEPOINT s1; INSERT INTO t1 VALUES(2,\u0026#39;222\u0026#39;); -- 假如xid=2 [savepoint 2, xid:1-2] SAVEPOINT s2; INSERT INTO t1 VALUES(3,\u0026#39;333\u0026#39;); -- 假如xid=3 [savepoint 3, xid:1-2-3] SAVEPOINT s3; INSERT INTO t1 VALUES(4,\u0026#39;444\u0026#39;); -- 假如xid=4 [savepoint 4, xid:1-2-3-4] SAVEPOINT s4; INSERT INTO t1 VALUES(5,\u0026#39;555\u0026#39;); -- 假如xid=5 [savepoint 5, xid:1-2-3-4-5] ROLLBACK TO SAVEPOINT s2; INSERT INTO t1 VALUES(6,\u0026#39;666\u0026#39;); -- 假如xid=6 [rollback to 3: xid:1-2] SAVEPOINT s5; INSERT INTO t1 VALUES(7,\u0026#39;777\u0026#39;); -- 假如xid=7 RELEASE SAVEPOINT s2; -- 此时，xid=6和xid=7会归并到xid=2的事务中 INSERT INTO t1 VALUES(8,\u0026#39;888\u0026#39;); -- 假如xid=2（假设上面RELEASE到s1，则xid=1，和顶层事务一致） COMMIT; -- \\! sleep 3 -- 5 check subscription \\c pubdb SELECT xmin,* FROM t1 ORDER BY c1; \\c subdb SELECT * FROM vb_parallel_apply_stat(); SELECT xmin,* FROM t1 ORDER BY c1; -- rollback to top \\c pubdb BEGIN; INSERT INTO t2 VALUES(1,\u0026#39;111\u0026#39;); -- 假如xid=1 SAVEPOINT s1; INSERT INTO t2 VALUES(2,\u0026#39;222\u0026#39;); -- 假如xid=2 SAVEPOINT s2; INSERT INTO t2 VALUES(3,\u0026#39;333\u0026#39;); -- 假如xid=3 SAVEPOINT s3; INSERT INTO t2 VALUES(4,\u0026#39;444\u0026#39;); -- 假如xid=4 SAVEPOINT s4; INSERT INTO t2 VALUES(5,\u0026#39;555\u0026#39;); -- 假如xid=5 ROLLBACK TO SAVEPOINT s2; INSERT INTO t2 VALUES(6,\u0026#39;666\u0026#39;); -- 假如xid=6 SAVEPOINT s5; INSERT INTO t2 VALUES(7,\u0026#39;777\u0026#39;); -- 假如xid=7 RELEASE SAVEPOINT s1; -- 此时，xid=6和xid=7会归并到xid=2的事务中 INSERT INTO t2 VALUES(8,\u0026#39;888\u0026#39;); -- 假如xid=2（假设上面RELEASE到s1，则xid=1，和顶层事务一致） COMMIT; -- \\! sleep 3 -- 5 check subscription \\c pubdb SELECT xmin,* FROM t2 ORDER BY c1; \\c subdb SELECT xmin,* FROM t2 ORDER BY c1; SELECT * FROM vb_parallel_apply_stat(); -- 延时检查 CREATE TABLE t3 (c1 INT, c2 TEXT ); ALTER TABLE t3 ADD CONSTRAINT t3_c1_unique UNIQUE (c1) DEFERRABLE; -- 事务1 -- 事务2 BEGIN; INSERT INTO t3 VALUES (1, \u0026#39;a\u0026#39;); BEGIN; SET CONSTRAINTS ALL DEFERRED; INSERT INTO t3 VALUES (1, \u0026#39;a\u0026#39;); COMMIT; COMMIT; -- 7 cleanup DROP SUBSCRIPTION sub1; \\c postgres DROP DATABASE IF EXISTS pubdb; DROP DATABASE IF EXISTS subdb; DROP USER pu1; 子事务 + 主键冲突 vkill vinit -- 1 config vb_guc set -D $GAUSSHOME/data -c \u0026#34;wal_level=logical\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_replication_slots=100\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_background_workers=100\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_logical_replication_workers=100\u0026#34; sed -i \u0026#39;1i host all all 0.0.0.0/0 sha256\\n\u0026#39; $GAUSSHOME/data/pg_hba.conf echo \u0026#34;host replication all 0.0.0.0/0 sha256\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/pg_hba.conf -- 2 startup vstart vsql -d postgres -p 50000 -r -- 3 create publicatioin \\c postgres CREATE DATABASE pubdb; \\c pubdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); CREATE PUBLICATION pub1 FOR all tables; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; -- 4 create subscription CREATE DATABASE subdb; \\c subdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); \\! gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=50001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=20); INSERT INTO t1 VALUES(3,\u0026#39;old\u0026#39;); \\c pubdb BEGIN; INSERT INTO t1 VALUES(1,\u0026#39;111\u0026#39;); -- 假如xid=1 SAVEPOINT s1; INSERT INTO t1 VALUES(2,\u0026#39;222\u0026#39;); -- 假如xid=2 [savepoint 2, xid:1-2] SAVEPOINT s2; INSERT INTO t1 VALUES(3,\u0026#39;333\u0026#39;); -- 假如xid=3 [savepoint 3, xid:1-2-3] SAVEPOINT s3; INSERT INTO t1 VALUES(4,\u0026#39;444\u0026#39;); -- 假如xid=4 [savepoint 4, xid:1-2-3-4] SAVEPOINT s4; COMMIT; \\c subdb SELECT * FROM t1; SELECT * FROM vb_parallel_apply_stat(); -- 7 cleanup DROP SUBSCRIPTION sub1; \\c postgres DROP DATABASE IF EXISTS pubdb; DROP DATABASE IF EXISTS subdb; DROP USER pu1; 子事务开发 -- 子事务开发 CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); SELECT pg_current_wal_lsn(); -- 场景一：relase commit BEGIN; INSERT INTO t1 VALUES(1,\u0026#39;111\u0026#39;); -- 假如xid=1 SAVEPOINT s1; INSERT INTO t1 VALUES(2,\u0026#39;222\u0026#39;); -- 假如xid=2 SAVEPOINT s2; INSERT INTO t1 VALUES(3,\u0026#39;333\u0026#39;); -- 假如xid=3 SAVEPOINT s3; INSERT INTO t1 VALUES(4,\u0026#39;444\u0026#39;); -- 假如xid=4 SAVEPOINT s4; INSERT INTO t1 VALUES(5,\u0026#39;555\u0026#39;); -- 假如xid=5 ROLLBACK TO SAVEPOINT s2; INSERT INTO t1 VALUES(6,\u0026#39;666\u0026#39;); -- 假如xid=6 SAVEPOINT s5; INSERT INTO t1 VALUES(7,\u0026#39;777\u0026#39;); -- 假如xid=7 RELEASE SAVEPOINT s2; -- 此时，xid=6和xid=7会归并到xid=2的事务中 INSERT INTO t1 VALUES(8,\u0026#39;888\u0026#39;); -- 假如xid=2（假设上面RELEASE到s1，则xid=1，和顶层事务一致） COMMIT; SELECT xmin,* FROM t1 ORDER BY c1; \\! pg_xlogdump -p $GAUSSHOME/data/pg_xlog -s xxx -x xid -- 场景二：release abort BEGIN; INSERT INTO t1 VALUES(1,\u0026#39;111\u0026#39;); -- 假如xid=1 SAVEPOINT s1; INSERT INTO t1 VALUES(2,\u0026#39;222\u0026#39;); -- 假如xid=2 SAVEPOINT s2; INSERT INTO t1 VALUES(3,\u0026#39;333\u0026#39;); -- 假如xid=3 SAVEPOINT s3; INSERT INTO t1 VALUES(4,\u0026#39;444\u0026#39;); -- 假如xid=4 SAVEPOINT s4; INSERT INTO t1 VALUES(5,\u0026#39;555\u0026#39;); -- 假如xid=5 ROLLBACK TO SAVEPOINT s2; INSERT INTO t1 VALUES(6,\u0026#39;666\u0026#39;); -- 假如xid=6 SAVEPOINT s5; INSERT INTO t1 VALUES(7,\u0026#39;777\u0026#39;); -- 假如xid=7 RELEASE SAVEPOINT s2; -- 此时，xid=6和xid=7会归并到xid=2的事务中 INSERT INTO t1 VALUES(8,\u0026#39;888\u0026#39;); -- 假如xid=2（假设上面RELEASE到s1，则xid=1，和顶层事务一致） ROLLBACK TO SAVEPOINT s1; COMMIT; SELECT xmin,* FROM t1 ORDER BY c1; -- pg 用例 echo \u0026#34; wal_level=logical max_worker_processes=20 max_logical_replication_workers=20 max_parallel_apply_workers_per_subscription=10 \u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf \\c postgres CREATE DATABASE pubdb; CREATE DATABASE subdb; \\c pubdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); CREATE PUBLICATION pub1 FOR ALL TABLES; CREATE USER pu1 REPLICATION LOGIN PASSWORD \u0026#39;pu1.12345\u0026#39;; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); -- 2 create subscription \\c subdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=5432 dbname=pubdb user=pu1 password=pu1.12345 replication=database\u0026#39; PUBLICATION pub1 WITH ( create_slot=false, slot_name=\u0026#39;pslot1\u0026#39;, copy_data=false, streaming=parallel ); -- 3 test transaction -- \\c pubdb -- BEGIN; -- INSERT INTO t1 VALUES(1,\u0026#39;111\u0026#39;); -- top xid -- SAVEPOINT s1; -- INSERT INTO t1 VALUES(2,\u0026#39;222\u0026#39;); -- subxid 2 -- SAVEPOINT s2; -- INSERT INTO t1 VALUES(3,\u0026#39;333\u0026#39;); -- subxid 3 -- SAVEPOINT s3; -- INSERT INTO t1 VALUES(4,\u0026#39;444\u0026#39;); -- subxid 4 -- SAVEPOINT s4; -- INSERT INTO t1 VALUES(5,\u0026#39;555\u0026#39;); -- subxid 5 -- ROLLBACK TO SAVEPOINT s2; -- INSERT INTO t1 VALUES(6,\u0026#39;666\u0026#39;); -- subxid 6 -- SAVEPOINT s5; -- INSERT INTO t1 VALUES(7,\u0026#39;777\u0026#39;); -- subxid 7 -- RELEASE SAVEPOINT s2; -- INSERT INTO t1 VALUES(8,\u0026#39;888\u0026#39;); -- 回到s1对应事务上下文 -- COMMIT; \\c pubdb BEGIN; INSERT INTO t1 VALUES(1,\u0026#39;111\u0026#39;); -- 假如xid=1 SAVEPOINT s1; INSERT INTO t1 VALUES(2,\u0026#39;222\u0026#39;); -- 假如xid=2 SAVEPOINT s2; INSERT INTO t1 VALUES(3,\u0026#39;333\u0026#39;); -- 假如xid=3 SAVEPOINT s3; INSERT INTO t1 VALUES(4,\u0026#39;444\u0026#39;); -- 假如xid=4 SAVEPOINT s4; INSERT INTO t1 VALUES(5,\u0026#39;555\u0026#39;); -- 假如xid=5 ROLLBACK TO SAVEPOINT s2; INSERT INTO t1 VALUES(6,\u0026#39;666\u0026#39;); -- 假如xid=6 SAVEPOINT s5; INSERT INTO t1 VALUES(7,\u0026#39;777\u0026#39;); -- 假如xid=7 RELEASE SAVEPOINT s2; -- 此时，xid=6和xid=7会归并到xid=2的事务中 INSERT INTO t1 VALUES(8,\u0026#39;888\u0026#39;); -- 假如xid=2（假设上面RELEASE到s1，则xid=1，和顶层事务一致） ROLLBACK TO SAVEPOINT s1; COMMIT; -- 4 check \\c pubdb SELECT xmin,* FROM t1 ORDER BY c1; \\c subdb SELECT * FROM pg_stat_subscription; SELECT xmin,* FROM t1 ORDER BY c1; # 发布端：2阶段处理 ReleaseSavepoint for loop: cur = CurrentTransactionState cur-\u0026gt;blockState = TBLOCK_SUBRELEASE cur = cur-\u0026gt;parent CommitTransactionCommand if CurrentTransactionState is TBLOCK_SUBRELEASE for loop: CommitSubTransaction AtSubCommit_childXids CurrentTransactionState-\u0026gt;parent-\u0026gt;childXids[cnt++] = CurrentTransactionState-\u0026gt;xid PopTransaction CurrentTransactionState = s-\u0026gt;parent # 订阅端： pa_start_subtrans DefineSavepoint subxactlist = lappend_xid(subxactlist, current_xid) apply_handle_stream_commit pa_stream_abort for loop: curxid = subxactlist if curxid == subxid: RollbackToSavepoint 实现原理：\nBEGIN; INSERT INTO t1 VALUES(1,\u0026#39;111\u0026#39;); -- 假如xid=1 SAVEPOINT s1; INSERT INTO t1 VALUES(2,\u0026#39;222\u0026#39;); -- 假如xid=2 [savepoint 2, xid:1-2] SAVEPOINT s2; INSERT INTO t1 VALUES(3,\u0026#39;333\u0026#39;); -- 假如xid=3 [savepoint 3, xid:1-2-3] SAVEPOINT s3; INSERT INTO t1 VALUES(4,\u0026#39;444\u0026#39;); -- 假如xid=4 [savepoint 4, xid:1-2-3-4] SAVEPOINT s4; INSERT INTO t1 VALUES(5,\u0026#39;555\u0026#39;); -- 假如xid=5 [savepoint 5, xid:1-2-3-4-5] ROLLBACK TO SAVEPOINT s2; [rollback to 5, xid:1-2-3-4] [rollback to 4, xid:1-2-3] [rollback to 3, xid:1-2] INSERT INTO t1 VALUES(6,\u0026#39;666\u0026#39;); -- 假如xid=6 [savepoint 6, xid:1-2-6] SAVEPOINT s5; INSERT INTO t1 VALUES(7,\u0026#39;777\u0026#39;); -- 假如xid=7 [savepoint 7, xid:1-2-6-7] RELEASE SAVEPOINT s2; -- 此时，xid=6和xid=7会归并到xid=2的事务中 INSERT INTO t1 VALUES(8,\u0026#39;888\u0026#39;); -- 假如xid=2（假设上面RELEASE到s1，则xid=1，和顶层事务一致） -- ROLLBACK TO s2; [rollback to 2, xid:1] COMMIT; disable subscirption vkill vinit -- 1 config vb_guc set -D $GAUSSHOME/data -c \u0026#34;wal_level=logical\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_replication_slots=100\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_background_workers=100\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_logical_replication_workers=100\u0026#34; sed -i \u0026#39;1i host all all 0.0.0.0/0 sha256\\n\u0026#39; $GAUSSHOME/data/pg_hba.conf echo \u0026#34;host replication all 0.0.0.0/0 sha256\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/pg_hba.conf -- 2 startup vstart vsql -d postgres -p 50000 -r -- 3 create publicatioin \\c postgres CREATE DATABASE pubdb; \\c pubdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); CREATE PUBLICATION pub1 FOR all tables; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; -- 4 create subscription CREATE DATABASE subdb; \\c subdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); \\! gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription \\! vsql -d subdb -p 50000 -c \u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=50001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=20);\u0026#34; -- \\c pubdb BEGIN; INSERT INTO t1 VALUES(1,\u0026#39;111\u0026#39;); INSERT INTO t1 VALUES(2,\u0026#39;222\u0026#39;); INSERT INTO t1 VALUES(3,\u0026#39;333\u0026#39;); COMMIT; \\! sleep 3 -- 5 check subscription \\c pubdb SELECT xmin,* FROM t1 ORDER BY c1; \\c subdb SELECT xmin,* FROM t1 ORDER BY c1; \\! for i in $(seq 10 100); do vsql -d pubdb -p 50000 -c \u0026#34;INSERT INTO t1 VALUES($i,\u0026#39;a\u0026#39;);\u0026#34;; done; ALTER SUBSCRIPTION sub1(enable=false); 发布端异常 vkill vinit -- 1 config vb_guc set -D $GAUSSHOME/data -c \u0026#34;wal_level=logical\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_replication_slots=100\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_background_workers=100\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_logical_replication_workers=100\u0026#34; sed -i \u0026#39;1i host all all 0.0.0.0/0 sha256\\n\u0026#39; $GAUSSHOME/data/pg_hba.conf echo \u0026#34;host replication all 0.0.0.0/0 sha256\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/pg_hba.conf -- 2 startup vstart vsql -d postgres -p 50000 -r -- 3 create publicatioin \\c postgres CREATE DATABASE pubdb; \\c pubdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); CREATE PUBLICATION pub1 FOR all tables; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; -- 4 create subscription CREATE DATABASE subdb; \\c subdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); \\! gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription \\! vsql -d subdb -p 50000 -c \u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=50001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=20);\u0026#34; -- , worker_number=30 -- 172.16.103.90 \\c pubdb BEGIN; INSERT INTO t1 VALUES(1,\u0026#39;111\u0026#39;); -- 假如xid=1 SAVEPOINT s1; INSERT INTO t1 VALUES(2,\u0026#39;222\u0026#39;); -- 假如xid=2 SAVEPOINT s2; INSERT INTO t1 VALUES(3,\u0026#39;333\u0026#39;); -- 假如xid=3 SAVEPOINT s3; INSERT INTO t1 VALUES(4,\u0026#39;444\u0026#39;); -- 假如xid=4 SAVEPOINT s4; INSERT INTO t1 VALUES(5,\u0026#39;555\u0026#39;); -- 假如xid=5 ROLLBACK TO SAVEPOINT s2; INSERT INTO t1 VALUES(6,\u0026#39;666\u0026#39;); -- 假如xid=6 SAVEPOINT s5; INSERT INTO t1 VALUES(7,\u0026#39;777\u0026#39;); -- 假如xid=7 RELEASE SAVEPOINT s2; -- 此时，xid=6和xid=7会归并到xid=2的事务中 INSERT INTO t1 VALUES(8,\u0026#39;888\u0026#39;); COMMIT; \\! sleep 3 -- 5 check subscription \\c pubdb SELECT xmin,* FROM t1 ORDER BY c1; \\c subdb SELECT xmin,* FROM t1 ORDER BY c1; \\c pubdb BEGIN; INSERT INTO t1 VALUES(1,\u0026#39;111\u0026#39;); -- 假如xid=1 SAVEPOINT s1; INSERT INTO t1 VALUES(2,\u0026#39;222\u0026#39;); -- 假如xid=2 SAVEPOINT s2; INSERT INTO t1 VALUES(3,\u0026#39;333\u0026#39;); -- 假如xid=3 COMMIT; INSERT INTO t1 VALUES(9, \u0026#39;999\u0026#39;); \\! sleep 3 -- 5 check subscription \\c pubdb SELECT xmin,* FROM t1 ORDER BY c1; \\c subdb SELECT xmin,* FROM t1 ORDER BY c1; -- 7 cleanup DROP SUBSCRIPTION sub1; \\c postgres DROP DATABASE IF EXISTS pubdb; DROP DATABASE IF EXISTS subdb; DROP USER pu1; 无主键场景 vkill vinit -- 1 config vb_guc set -D $GAUSSHOME/data -c \u0026#34;wal_level=logical\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_replication_slots=100\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_background_workers=100\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_logical_replication_workers=100\u0026#34; sed -i \u0026#39;1i host all all 0.0.0.0/0 sha256\\n\u0026#39; $GAUSSHOME/data/pg_hba.conf echo \u0026#34;host replication all 0.0.0.0/0 sha256\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/pg_hba.conf -- 2 startup vstart vsql -d postgres -p 50000 -r -- 3 create publicatioin \\c postgres CREATE DATABASE pubdb; \\c pubdb CREATE TABLE t1(c1 INT, c2 TEXT); CREATE TABLE t2(c1 INT, c2 TEXT); SELECT relreplident FROM pg_class WHERE relname in (\u0026#39;t1\u0026#39;, \u0026#39;t2\u0026#39;); ALTER TABLE t1 REPLICA IDENTITY FULL; ALTER TABLE t2 REPLICA IDENTITY FULL; CREATE PUBLICATION pub1 FOR all tables; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; -- 4 create subscription CREATE DATABASE subdb; \\c subdb CREATE TABLE t1(c1 INT, c2 TEXT); CREATE TABLE t2(c1 INT, c2 TEXT); \\! gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription \\! vsql -d subdb -p 50000 -c \u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=50001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=30);\u0026#34; -- , worker_number=30 -- 172.16.103.90 -- 5 load data \\! for i in $(seq 0 50); do vsql -d pubdb -p 50000 -c \u0026#34;BEGIN; INSERT INTO t1 VALUES($i,\u0026#39;a\u0026#39;); UPDATE t1 SET c2=\u0026#39;b\u0026#39; WHERE c1=$i-1; UPDATE t1 SET c2=\u0026#39;a\u0026#39; WHERE c1=$i-2; COMMIT;\u0026#34; \u0026amp; done; wait \\c pubdb SELECT * FROM t1; \\c subdb SELECT * FROM t2; \\o pubdb.out \\c pubdb SELECT * FROM t1 ORDER BY c1; \\o \\o subdb.out \\c subdb SELECT * FROM t1 ORDER BY c1; \\o \\! grep -Irn \u0026#34;rows\u0026#34; pubdb.out \\! grep -Irn \u0026#34;rows\u0026#34; subdb.out \\! diff pubdb.out subdb.out 多个发布订阅 vkill rm -rf $GAUSSHOME/data vinit -- 1 config vb_guc set -D $GAUSSHOME/data -c \u0026#34;wal_level=logical\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_wal_senders=100\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;work_mem=1GB\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;maintenance_work_mem=4GB\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_replication_slots=100\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_background_workers=100\u0026#34; vb_guc set -D $GAUSSHOME/data -c \u0026#34;max_logical_replication_workers=100\u0026#34; sed -i \u0026#39;1i host all all 0.0.0.0/0 sha256\\n\u0026#39; $GAUSSHOME/data/pg_hba.conf echo \u0026#34;host replication all 0.0.0.0/0 sha256\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/pg_hba.conf -- 2 startup vstart -- 3 create publicatioin vsql -d postgres -p 50000 -c \u0026#34;CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;;\u0026#34; for i in $(seq 0 11); do vsql -d postgres -p 50000 -c \u0026#34;CREATE DATABASE pubdb$i;\u0026#34; vsql -d pubdb$i -p 50000 -c \u0026#34;CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT);\u0026#34; vsql -d pubdb$i -p 50000 -c \u0026#34;CREATE PUBLICATION pub$i FOR all tables;\u0026#34; vsql -d pubdb$i -p 50000 -c \u0026#34;SELECT pg_create_logical_replication_slot(\u0026#39;pslot$i\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; done; -- 4 create subscription gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription for i in $(seq 0 11); do vsql -d postgres -p 50000 -c \u0026#34;CREATE DATABASE subdb$i;\u0026#34; vsql -d subdb$i -p 50000 -c \u0026#34;CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT);\u0026#34; vsql -d subdb$i -p 50000 -c \u0026#34;CREATE SUBSCRIPTION sub$i CONNECTION \u0026#39;host=127.0.0.1 port=50001 dbname=pubdb$i user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub$i WITH (create_slot=false, slot_name = \u0026#39;pslot$i\u0026#39;, copy_data = false, worker_number=30);\u0026#34; done; -- 5 load data for i in $(seq 0 11); do for j in $(seq 0 10); do vsql -d pubdb$i -p 50000 -c \u0026#34;BEGIN; INSERT INTO t1 VALUES($j,\u0026#39;a\u0026#39;); UPDATE t1 SET c2=\u0026#39;b\u0026#39; WHERE c1=$j-1; COMMIT;\u0026#34; \u0026amp; done; sleep 2 done; wait -- 6 check for i in $(seq 0 11); do vsql -d pubdb$i -p 50000 -c \u0026#34;SELECT count(1) FROM t1\u0026#34; done; for i in $(seq 0 11); do vsql -d subdb$i -p 50000 -c \u0026#34;SELECT count(1) FROM t1\u0026#34; done; vsql -d pubdb -p 50000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; -- 7 cleanup DROP SUBSCRIPTION sub1; \\c postgres DROP DATABASE IF EXISTS pubdb; DROP DATABASE IF EXISTS subdb; DROP USER pu1; 2 标准版 make fastcheck_checktest TESTS=\u0026#39;rep_pa_apply\u0026#39; dbcmpt=A -- 1 config \\setenv DATADIR @abs_srcdir@/tmp_check/datanode1 \\! @abs_bindir@/vb_guc set -D $DATADIR -c \u0026#34;wal_level=logical\u0026#34; \u0026gt; /dev/null 2\u0026gt;\u0026amp;1 \\! @abs_bindir@/vb_guc set -D $DATADIR -c \u0026#34;max_replication_slots=100\u0026#34; \u0026gt; /dev/null 2\u0026gt;\u0026amp;1 \\! @abs_bindir@/vb_guc set -D $DATADIR -c \u0026#34;max_background_workers=100\u0026#34; \u0026gt; /dev/null 2\u0026gt;\u0026amp;1 \\! @abs_bindir@/vb_guc set -D $DATADIR -c \u0026#34;max_logical_replication_workers=100\u0026#34; \u0026gt; /dev/null 2\u0026gt;\u0026amp;1 \\! sed -i \u0026#39;1i host all all 0.0.0.0/0 sha256\\n\u0026#39; $DATADIR/pg_hba.conf \\! echo \u0026#34;host replication all 0.0.0.0/0 sha256\u0026#34; \u0026gt;\u0026gt; $DATADIR/pg_hba.conf -- 2 startup \\! @abs_bindir@/vb_ctl restart -D $DATADIR \u0026gt; /dev/null 2\u0026gt;\u0026amp;1 \\c regression -- 3 create publicatioin CREATE DATABASE pubdb; \\c pubdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); CREATE PUBLICATION pub1 FOR all tables; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; -- 4 create subscription CREATE DATABASE subdb; \\c subdb CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT); CREATE TABLE t2(c1 INT PRIMARY KEY, c2 TEXT); \\! @abs_bindir@/gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D @abs_bindir@ -o subscription \u0026gt; /dev/null 2\u0026gt;\u0026amp;1 \\! pub_port=`expr @portstring@ + 1` \u0026amp;\u0026amp; @abs_bindir@/vsql -d subdb -p @portstring@ -c \u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=\u0026#34;$pub_port\u0026#34; dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=30);\u0026#34; -- 5 load data \\! for i in $(seq 0 10); do @abs_bindir@/vsql -d pubdb -p @portstring@ -c \u0026#34;BEGIN; INSERT INTO t1 VALUES($i,\u0026#39;a\u0026#39;); UPDATE t1 SET c2=\u0026#39;b\u0026#39; WHERE c1=$i-1; COMMIT;\u0026#34; \u0026gt; /dev/null 2\u0026gt;\u0026amp;1 \u0026amp; done; wait -- wait replication \\! sleep 4 -- 5 check subscription \\o pubdb.out \\c pubdb SELECT * FROM t1 ORDER BY c1; \\o \\o subdb.out \\c subdb SELECT * FROM t1 ORDER BY c1; \\o \\! grep -Irn \u0026#34;rows\u0026#34; pubdb.out \\! grep -Irn \u0026#34;rows\u0026#34; subdb.out \\! diff pubdb.out subdb.out \\! rm -f pubdb.out subdb.out -- 7 cleanup DROP SUBSCRIPTION sub1; \\c regression DROP DATABASE IF EXISTS pubdb; DROP DATABASE IF EXISTS subdb; DROP USER pu1; toto todo delete leader – ok delete dcache if no worker, log it – ok startup, cleanup cache file – ok message is too long \u0026gt; 4000 transaction is too long todo 0812 worker error to leader - ok copy_data reconnect test: enable/disable _REP – ok vb_parallel_apply_stat – ok mem leak test todo 0820 relarr 100个 txn_cache_pop_data，文件data最大4095 fd \u0026lt;= 0 ASSERT 多sub\nvkill rm -rf $GAUSSHOME/data* # cp -r ~/w100_t50/data_w100 $GAUSSHOME/data # cp -r ~/w100_t50/data1 $GAUSSHOME/ cp -r ~/w5/data $GAUSSHOME/data cp -r ~/w5/data1 $GAUSSHOME/ vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;max_replication_slots=100\u0026#34; vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;max_background_workers=100\u0026#34; vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;max_logical_replication_workers=100\u0026#34; # vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;max_connections=4000\u0026#34; vb_ctl start -D $GAUSSHOME/data vb_ctl start -D $GAUSSHOME/data1 # 五、发布端（发布） vsql -d pubdb -p 64000 -c \u0026#34;CREATE PUBLICATION pub1 FOR TABLE bmsql_warehouse,bmsql_history;\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;CREATE PUBLICATION pub2 FOR TABLE bmsql_oorder,bmsql_config,bmsql_district,bmsql_item;\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;CREATE PUBLICATION pub3 FOR TABLE bmsql_order_line,bmsql_customer,bmsql_new_order,bmsql_stock;\u0026#34; # vsql -d pubdb -p 64000 -c \u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; # 六、订阅端（订阅） gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription vsql -d pubdb -p 65000 -c \u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (copy_data = false, worker_number=30);\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;CREATE SUBSCRIPTION sub2 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub2 WITH (copy_data = false, worker_number=30);\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;CREATE SUBSCRIPTION sub3 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub3 WITH (copy_data = false, worker_number=30);\u0026#34; # vsql -d pubdb -p 65000 -r # \\q vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM pg_subscription_rel\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34; ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/3-13-replication-test/","summary":"\u003ch1 id=\"1-本地自测\"\u003e1 本地自测\u003c/h1\u003e\n\u003ch2 id=\"11-快速tpcc\"\u003e1.1 快速tpcc\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evkill\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003erm -rf \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data*\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# cp -r ~/w100_t200/data $GAUSSHOME/data\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# cp -r ~/w100_t200/data1 $GAUSSHOME/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp -r ~/w5/data \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp -r ~/w5/data1 \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# cp -r ~/w100/data $GAUSSHOME/data\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# cp -r ~/w100/data1 $GAUSSHOME/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# vb_guc set -D $GAUSSHOME/data -c \u0026#34;enable_ddl_logical_decode=on\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;enable_ddl_logical_decode=on\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;max_replication_slots=50\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;max_background_workers=50\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# vb_guc set -D $GAUSSHOME/data1 -c \u0026#34;max_logical_replication_workers=50\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data1 -c \u003cspan class=\"s2\"\u003e\u0026#34;max_connections=4000\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data1 -c \u003cspan class=\"s2\"\u003e\u0026#34;enable_audit=on\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data1 -c \u003cspan class=\"s2\"\u003e\u0026#34;audit_buffer_size=262144\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data1 -c \u003cspan class=\"s2\"\u003e\u0026#34;audit_directory_size=1073741824\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_ctl start -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_ctl start -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 五、发布端（发布）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE PUBLICATION pub1 FOR all tables WITH (ddl=\u0026#39;all\u0026#39;);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# # 六、订阅端（订阅）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc generate -S \u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/bin -o subscription\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=220);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# vsql -d pubdb -p 65000 -r\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# \\q\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# cd ~/tpcc\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# source envbm\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# ./toolbm run vpub\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 换窗口查询\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 场景一：验证内存\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM gs_thread_memory_context ORDER BY totalsize DESC limit 30;\u0026#34;\u003c/span\u003e \u0026gt; start_pub.mem\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM gs_shared_memory_detail ORDER BY totalsize DESC limit 30;;\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; start_pub.mem\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM gs_thread_memory_context ORDER BY totalsize DESC limit 30;;\u0026#34;\u003c/span\u003e \u0026gt; start_sub.mem\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM gs_shared_memory_detail ORDER BY totalsize DESC limit 30;;\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; start_sub.mem\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 场景八：验证数据一致性\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;DROP TABLE IF EXISTS tcnt\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE TABLE tcnt (c1 TEXT,c2 INT);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;DROP TABLE IF EXISTS tcnt\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE TABLE tcnt (c1 TEXT,c2 INT);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e t in bmsql_config bmsql_customer bmsql_district bmsql_history bmsql_item bmsql_new_order bmsql_oorder bmsql_order_line bmsql_stock bmsql_warehouse\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$t\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c  \u003cspan class=\"s2\"\u003e\u0026#34;INSERT INTO tcnt VALUES(\u0026#39;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$t\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#39;, (SELECT count(1) FROM \u003c/span\u003e\u003cspan class=\"nv\"\u003e$t\u003c/span\u003e\u003cspan class=\"s2\"\u003e));\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e t in bmsql_config bmsql_customer bmsql_district bmsql_history bmsql_item bmsql_new_order bmsql_oorder bmsql_order_line bmsql_stock bmsql_warehouse\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$t\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c  \u003cspan class=\"s2\"\u003e\u0026#34;INSERT INTO tcnt VALUES(\u0026#39;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$t\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#39;, (SELECT count(1) FROM \u003c/span\u003e\u003cspan class=\"nv\"\u003e$t\u003c/span\u003e\u003cspan class=\"s2\"\u003e));\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM tcnt\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM tcnt;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 场景一：重启订阅端（kill）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e i in \u003cspan class=\"k\"\u003e$(\u003c/span\u003eseq \u003cspan class=\"m\"\u003e0\u003c/span\u003e 10\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e------------------------------------------------------------------------------------\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    ps ux \u003cspan class=\"p\"\u003e|\u003c/span\u003e grep \u003cspan class=\"s1\"\u003e\u0026#39;vastbase.*-D.*/data1\u0026#39;\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e grep -v grep \u003cspan class=\"p\"\u003e|\u003c/span\u003e awk \u003cspan class=\"s1\"\u003e\u0026#39;{print $2}\u0026#39;\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e xargs \u003cspan class=\"nb\"\u003ekill\u003c/span\u003e -9\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vb_ctl start -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    sleep \u003cspan class=\"m\"\u003e7\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; a.out\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 场景二：重启订阅端(stop)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e i in \u003cspan class=\"k\"\u003e$(\u003c/span\u003eseq \u003cspan class=\"m\"\u003e0\u003c/span\u003e 10\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e------------------------------------------------------------------------------------\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e------------------------------------------------------------------------------------\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; a.out\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vb_ctl stop -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vb_ctl start -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; a.out\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    sleep \u003cspan class=\"m\"\u003e7\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; a.out\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 场景三：重启发布端\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_ctl stop -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esleep \u003cspan class=\"m\"\u003e5\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_ctl start -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_ctl restart -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 场景三：重建 subscription\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e i in \u003cspan class=\"k\"\u003e$(\u003c/span\u003eseq \u003cspan class=\"m\"\u003e0\u003c/span\u003e 10\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e------------------------------------------------------------------------------------\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e------------------------------------------------------------------------------------\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; a.out\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;DROP SUBSCRIPTION sub1;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=20);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    sleep \u003cspan class=\"m\"\u003e6\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; a.out\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;DROP SUBSCRIPTION sub1;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=20);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM pg_subscription_rel\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eSELECT pg_wal_lsn_diff\u003cspan class=\"o\"\u003e(\u003c/span\u003epg_current_wal_lsn\u003cspan class=\"o\"\u003e()\u003c/span\u003e, \u003cspan class=\"s1\"\u003e\u0026#39;0/0\u0026#39;\u003c/span\u003e\u003cspan class=\"o\"\u003e)\u003c/span\u003e / \u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e1024\u003c/span\u003e * 1024\u003cspan class=\"o\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 场景五：ddl\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;\\d\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;\\d\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;DROP TABLE bmsql_warehouse\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE TABLE t3(c1 INT)\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;\\d\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;\\d\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 场景六：多个发布订阅\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d postgres -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE DATABASE db3;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d db3 -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE TABLE t3(c1 INT PRIMARY KEY, c2 TEXT);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d db3 -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE PUBLICATION pub3 FOR all tables WITH (ddl=\u0026#39;all\u0026#39;);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d db3 -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot3\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d postgres -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE DATABASE db3;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d db3 -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE TABLE t3(c1 INT PRIMARY KEY, c2 TEXT);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d db3 -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE SUBSCRIPTION sub3 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=db3 user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub3 WITH (create_slot=false, slot_name = \u0026#39;pslot3\u0026#39;, copy_data = false, worker_number=20);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;DROP SUBSCRIPTION sub1;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e i in \u003cspan class=\"k\"\u003e$(\u003c/span\u003eseq \u003cspan class=\"m\"\u003e0\u003c/span\u003e 10\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003edo\u003c/span\u003e vsql -d db3 -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;BEGIN; INSERT INTO t3 VALUES(\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e,\u0026#39;a\u0026#39;); UPDATE t3 SET c2=\u0026#39;b\u0026#39; WHERE c1=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e-1; COMMIT;\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e\u0026amp;\u003c/span\u003e \u003cspan class=\"k\"\u003edone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"nb\"\u003ewait\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 跑10分钟\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e./toolbm run vpub\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;DROP SUBSCRIPTION sub1;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e t in bmsql_config bmsql_customer bmsql_district bmsql_history bmsql_item bmsql_new_order bmsql_oorder bmsql_order_line bmsql_stock bmsql_warehouse\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$t\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c  \u003cspan class=\"s2\"\u003e\u0026#34;TRUNCATE \u003c/span\u003e\u003cspan class=\"nv\"\u003e$t\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"续点重传\"\u003e续点重传\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evkill\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003erm -rf \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data*\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# cp -r ~/w5/data $GAUSSHOME/data\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# cp -r ~/w5/data1 $GAUSSHOME/\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp -r ~/w100/data \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp -r ~/w100/data1 \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data1 -c \u003cspan class=\"s2\"\u003e\u0026#34;max_connections=4000\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_ctl start -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_ctl start -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 五、发布端（发布）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE PUBLICATION pub1 FOR all tables WITH (ddl=\u0026#39;all\u0026#39;);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# # 六、订阅端（订阅）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc generate -S \u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/bin -o subscription\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=220);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# vsql -d pubdb -p 65000 -r\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# \\q\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# ./toolbm run vpub\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 重启订阅端（kill）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e i in \u003cspan class=\"k\"\u003e$(\u003c/span\u003eseq \u003cspan class=\"m\"\u003e0\u003c/span\u003e 10\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e------------------------------------------------------------------------------------\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    ps ux \u003cspan class=\"p\"\u003e|\u003c/span\u003e grep \u003cspan class=\"s1\"\u003e\u0026#39;vastbase.*-D.*/data1\u0026#39;\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e grep -v grep \u003cspan class=\"p\"\u003e|\u003c/span\u003e awk \u003cspan class=\"s1\"\u003e\u0026#39;{print $2}\u0026#39;\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e xargs \u003cspan class=\"nb\"\u003ekill\u003c/span\u003e -9\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vb_ctl start -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    sleep \u003cspan class=\"m\"\u003e7\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; a.out\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;  SELECT * FROM pg_get_replication_slots(); \u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;  SELECT pg_current_wal_lsn();\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 验证数据一致性\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;DROP TABLE IF EXISTS tcnt\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE TABLE tcnt (c1 TEXT,c2 INT);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;DROP TABLE IF EXISTS tcnt\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE TABLE tcnt (c1 TEXT,c2 INT);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e t in bmsql_config bmsql_customer bmsql_district bmsql_history bmsql_item bmsql_new_order bmsql_oorder bmsql_order_line bmsql_stock bmsql_warehouse\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$t\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c  \u003cspan class=\"s2\"\u003e\u0026#34;INSERT INTO tcnt VALUES(\u0026#39;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$t\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#39;, (SELECT count(1) FROM \u003c/span\u003e\u003cspan class=\"nv\"\u003e$t\u003c/span\u003e\u003cspan class=\"s2\"\u003e));\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e t in bmsql_config bmsql_customer bmsql_district bmsql_history bmsql_item bmsql_new_order bmsql_oorder bmsql_order_line bmsql_stock bmsql_warehouse\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$t\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c  \u003cspan class=\"s2\"\u003e\u0026#34;INSERT INTO tcnt VALUES(\u0026#39;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$t\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#39;, (SELECT count(1) FROM \u003c/span\u003e\u003cspan class=\"nv\"\u003e$t\u003c/span\u003e\u003cspan class=\"s2\"\u003e));\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM tcnt\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM tcnt;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- ===================== worker_number =======================\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCONNECTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecreate_slot\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eslot_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pslot1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecopy_data\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e64000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCONNECTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecreate_slot\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eslot_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pslot1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecopy_data\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eworker_number\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e64000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCONNECTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecreate_slot\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eslot_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pslot1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecopy_data\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eworker_number\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e64000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub4\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCONNECTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecreate_slot\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eslot_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pslot1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecopy_data\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eworker_number\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e200\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub4\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e64000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub5\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCONNECTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecreate_slot\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eslot_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pslot1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecopy_data\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eworker_number\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e400\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub5\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub6\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCONNECTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecreate_slot\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eslot_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pslot1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecopy_data\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eworker_number\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e1000\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub6\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- ===================== copy_data =======================\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- do truncate fist\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub21\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCONNECTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecreate_slot\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eslot_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pslot1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecopy_data\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eworker_number\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e50\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_subscription_rel\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub21\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- copy and stop\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- ===================== cache file =======================\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 1. drop subscription\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 2. kill progress\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- ===================== 断点续传 =======================\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d postgres -p \u003cspan class=\"m\"\u003e50000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;DROP TABLE IF EXISTS t1\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d postgres -p \u003cspan class=\"m\"\u003e50000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE TABLE t1(c1 INT, c2 TEXT)\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e i in \u003cspan class=\"k\"\u003e$(\u003c/span\u003eseq \u003cspan class=\"m\"\u003e0\u003c/span\u003e 10\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003edo\u003c/span\u003e vsql -d postgres -p \u003cspan class=\"m\"\u003e50000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;BEGIN; INSERT INTO t1 VALUES(\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e,\u0026#39;a\u0026#39;); UPDATE t1 SET c2=\u0026#39;b\u0026#39; WHERE c1=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e-1; COMMIT;\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e\u0026amp;\u003c/span\u003e \u003cspan class=\"k\"\u003edone\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d postgres -p \u003cspan class=\"m\"\u003e50000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM t1 ORDER BY c1\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"parallel_applysource\"\u003eparallel_apply.source\u003c/h2\u003e\n\u003ch3 id=\"1-自测\"\u003e1 自测\u003c/h3\u003e\n\u003ch3 id=\"批量验证\"\u003e批量验证\u003c/h3\u003e\n\u003ch4 id=\"初始化模板\"\u003e初始化模板\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eexport\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eVDATA\u003c/span\u003e\u003cspan class=\"o\"\u003e=~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eVDATA\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;port=64000\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eVDATA\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;max_connection=2000\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eVDATA\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;wal_level=logical\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eVDATA\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;max_replication_slots=100\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eVDATA\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;max_background_workers=100\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eVDATA\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;max_logical_replication_workers=100\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003esed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1i host all all 0.0.0.0/0 sha256\\n\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eVDATA\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003epg_hba\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003econf\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eecho\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;host replication all 0.0.0.0/0 sha256\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eVDATA\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003epg_hba\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003econf\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"insert性能\"\u003einsert性能\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eexport\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eVDATA\u003c/span\u003e\u003cspan class=\"o\"\u003e=~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evkill\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003erm\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003erf\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ecp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003etemp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evstart\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e64000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 create publicatioin\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eall\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etables\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eREPLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSYSADMIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eLOGIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eENCRYPTED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_create_logical_replication_slot\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pslot1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pgoutput\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- sub\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egs_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egenerate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003ebin\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eo\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubscription\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCONNECTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;host=127.0.0.1 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecreate_slot\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eslot_name\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pslot1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecopy_data\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eworker_number\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e80\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_parallel_apply_stat\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003etruncate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003etruncate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edatname\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003elength\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003equery\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_stat_activity\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edatname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pubdb\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"多个发布订阅\"\u003e多个发布订阅\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D ~/g100/rep/data -c \u003cspan class=\"s2\"\u003e\u0026#34;max_replication_slots=256\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D ~/g100/rep/data -c \u003cspan class=\"s2\"\u003e\u0026#34;max_background_workers=256\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D ~/g100/rep/data -c \u003cspan class=\"s2\"\u003e\u0026#34;max_logical_replication_workers=256\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eVDATA\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e~/g100/rep/data\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evkill\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003erm -rf ~/g100/rep/data\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp -r ~/g100/rep/temp ~/g100/rep/data\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D ~/g100/rep/data -c \u003cspan class=\"s2\"\u003e\u0026#34;enable_ddl_logical_decode=on\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D ~/g100/rep/data -c \u003cspan class=\"s2\"\u003e\u0026#34;max_wal_senders=36\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D ~/g100/rep/data -c \u003cspan class=\"s2\"\u003e\u0026#34;max_replication_slots=256\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D ~/g100/rep/data -c \u003cspan class=\"s2\"\u003e\u0026#34;max_background_workers=256\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D ~/g100/rep/data -c \u003cspan class=\"s2\"\u003e\u0026#34;max_logical_replication_workers=256\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D ~/g100/rep/data -c \u003cspan class=\"s2\"\u003e\u0026#34;max_connections=1000\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evstart\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003erm -rf ~/g100/rep/data1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D ~/g100/rep/data1 -c \u003cspan class=\"s2\"\u003e\u0026#34;port=65000\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp -r ~/g100/rep/temp ~/g100/rep/data1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_ctl start -D  ~/g100/rep/data1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 发布\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d postgres -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e i in \u003cspan class=\"k\"\u003e$(\u003c/span\u003eseq \u003cspan class=\"m\"\u003e0\u003c/span\u003e 11\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d postgres -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE DATABASE pubdb\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d pubdb\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d pubdb\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE PUBLICATION pub\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e FOR all tables;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d pubdb\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT pg_create_logical_replication_slot(\u0026#39;pslot\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 5 load data\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e i in \u003cspan class=\"k\"\u003e$(\u003c/span\u003eseq \u003cspan class=\"m\"\u003e0\u003c/span\u003e 11\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003efor\u003c/span\u003e j in \u003cspan class=\"k\"\u003e$(\u003c/span\u003eseq \u003cspan class=\"m\"\u003e0\u003c/span\u003e 10\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        vsql -d pubdb\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;BEGIN; INSERT INTO t1 VALUES(\u003c/span\u003e\u003cspan class=\"nv\"\u003e$j\u003c/span\u003e\u003cspan class=\"s2\"\u003e,\u0026#39;a\u0026#39;); UPDATE t1 SET c2=\u0026#39;b\u0026#39; WHERE c1=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$j\u003c/span\u003e\u003cspan class=\"s2\"\u003e-1; COMMIT;\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e\u0026amp;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003edone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    sleep \u003cspan class=\"m\"\u003e2\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"nb\"\u003ewait\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 订阅\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc generate -S \u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/bin -o subscription\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e i in \u003cspan class=\"k\"\u003e$(\u003c/span\u003eseq \u003cspan class=\"m\"\u003e0\u003c/span\u003e 11\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d postgres -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE DATABASE subdb\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d subdb\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE TABLE t1(c1 INT PRIMARY KEY, c2 TEXT);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d subdb\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE SUBSCRIPTION sub\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e CONNECTION \u0026#39;host=127.0.0.1 port=64001 dbname=pubdb\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e WITH (create_slot=false, slot_name = \u0026#39;pslot\u003c/span\u003e\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#39;, copy_data = false, worker_number=30);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esleep \u003cspan class=\"m\"\u003e5\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 6 check\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e i in \u003cspan class=\"k\"\u003e$(\u003c/span\u003eseq \u003cspan class=\"m\"\u003e0\u003c/span\u003e 11\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d pubdb\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT count(1) FROM t1\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e i in \u003cspan class=\"k\"\u003e$(\u003c/span\u003eseq \u003cspan class=\"m\"\u003e0\u003c/span\u003e 11\u003cspan class=\"k\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    vsql -d subdb\u003cspan class=\"nv\"\u003e$i\u003c/span\u003e -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT count(1) FROM t1\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d postgres -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34; SELECT * FROM pg_get_replication_slots();\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d postgres -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 7 cleanup\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eDROP SUBSCRIPTION sub1\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"se\"\u003e\\c\u003c/span\u003e postgres\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eDROP DATABASE IF EXISTS pubdb\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eDROP DATABASE IF EXISTS subdb\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eDROP USER pu1\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"copydata\"\u003ecopydata\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eexport\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eVDATA\u003c/span\u003e\u003cspan class=\"o\"\u003e=~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evkill\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003erm\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003erf\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ecp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003etemp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evstart\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003erm\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003erf\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003edata1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ecp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003etemp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003edata1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003edata1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;port=65000\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_ctl\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003estart\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003edata1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e64000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 create publicatioin\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- pub\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eall\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etables\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- CREATE PUBLICATION pub1 FOR TABLE t1,t2;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eREPLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSYSADMIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eLOGIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eENCRYPTED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- INSERT INTO t1 VALUES(1,\u0026#39;a\u0026#39;),(2,\u0026#39;b\u0026#39;),(3,\u0026#39;c\u0026#39;);\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- INSERT INTO t1 (c1,c2) SELECT i,\u0026#39;BASE_\u0026#39; || i || \u0026#39;_\u0026#39; || repeat(\u0026#39;X\u0026#39;, 13000) FROM generate_series(1, 10000) AS i;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"n\"\u003eq\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- for i in $(seq 0 1000); do vsql -d pubdb -p 64000 -c \u0026#34;INSERT INTO t1 VALUES($i,\u0026#39;a\u0026#39;); \u0026#34; ; done\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e65000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- sub\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egs_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egenerate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003ebin\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eo\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubscription\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCONNECTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;host=127.0.0.1 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecopy_data\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eworker_number\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- \\! for i in $(seq 20000 20010); do vsql -d pubdb -p 64000 -c \u0026#34;INSERT INTO t1 VALUES($i,\u0026#39;a\u0026#39;); \u0026#34; ; done\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_parallel_apply_stat\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e64000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT count(1) FROM t1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e65000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT count(1) FROM t1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e65000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_replication_slots\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),(\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),(\u003c/span\u003e\u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"ddl\"\u003eddl\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eexport\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eVDATA\u003c/span\u003e\u003cspan class=\"o\"\u003e=~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evkill\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003erm\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003erf\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ecp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003etemp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;enable_ddl_logical_decode=on\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evstart\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003erm\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003erf\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003edata1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ecp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003etemp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003edata1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003edata1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;port=65000\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_ctl\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003estart\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003edata1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e64000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 create publicatioin\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- pub\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eall\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etables\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epublish\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;insert,update,delete,truncate\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eddl\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;all\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- CREATE PUBLICATION pub1 FOR TABLE t1,t2;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eREPLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSYSADMIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eLOGIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eENCRYPTED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- INSERT INTO t1 VALUES(1,\u0026#39;a\u0026#39;),(2,\u0026#39;b\u0026#39;),(3,\u0026#39;c\u0026#39;);\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"n\"\u003eq\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e65000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- sub\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e  \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egs_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egenerate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003ebin\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eo\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubscription\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCONNECTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;host=127.0.0.1 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecopy_data\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eworker_number\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e64000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;TRUNCATE t1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esleep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e64000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;DROP TABLE t1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esleep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_replication_slots\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),(\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),(\u003c/span\u003e\u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"sub-txn--ddl\"\u003esub-txn + ddl\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eexport\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eVDATA\u003c/span\u003e\u003cspan class=\"o\"\u003e=~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evkill\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003erm\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003erf\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ecp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003etemp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;enable_ddl_logical_decode=on\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evstart\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003erm\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003erf\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003edata1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ecp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003etemp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003edata1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003edata1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;port=65000\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_ctl\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003estart\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003edata1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e64000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 create publicatioin\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- pub\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eall\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etables\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epublish\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;insert,update,delete,truncate\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eddl\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;all\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- CREATE PUBLICATION pub1 FOR TABLE t1,t2;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eREPLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSYSADMIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eLOGIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eENCRYPTED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"n\"\u003eq\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e65000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- sub\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egs_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egenerate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003ebin\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eo\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubscription\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCONNECTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;host=127.0.0.1 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecopy_data\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eworker_number\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e64000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;TRUNCATE t1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esleep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e64000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;DROP TABLE t1\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esleep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e64000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;BEGIN; CREATE TABLE t3(c1 int); SAVEPOINT sp1; INSERT INTO t3 VALUES(3); SAVEPOINT sp2; TRUNCATE t3; SAVEPOINT sp3; COMMIT;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_replication_slots\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),(\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),(\u003c/span\u003e\u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"disable\"\u003edisable\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eexport\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eVDATA\u003c/span\u003e\u003cspan class=\"o\"\u003e=~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evkill\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003erm\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003erf\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ecp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003etemp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evstart\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003erm\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003erf\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003edata1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ecp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003etemp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003edata1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003edata1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;port=65000\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_ctl\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003estart\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"o\"\u003e~/\u003c/span\u003e\u003cspan class=\"n\"\u003eg100\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003erep\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003edata1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e64000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 create publicatioin\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- pub\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eall\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etables\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eddl\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;all\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- CREATE PUBLICATION pub1 FOR TABLE t1,t2;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eREPLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSYSADMIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eLOGIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eENCRYPTED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"n\"\u003eq\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e65000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- sub\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egs_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egenerate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003ebin\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eo\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubscription\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCONNECTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;host=127.0.0.1 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecopy_data\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eworker_number\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- SELECT * FROM pg_replication_slots;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_stat_subscription\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDISABLE\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e64000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;INSERT INTO t1 VALUES(4,\u0026#39;a\u0026#39;),(5,\u0026#39;b\u0026#39;),(6,\u0026#39;c\u0026#39;);\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eENABLE\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_replication_slots\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"基础场景\"\u003e基础场景\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evkill\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evinit\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 1 config\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;wal_level=logical\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;max_replication_slots=100\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;max_background_workers=100\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;max_logical_replication_workers=100\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003esed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1i host all all 0.0.0.0/0 sha256\\n\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003epg_hba\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003econf\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eecho\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;host replication all 0.0.0.0/0 sha256\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003epg_hba\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003econf\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2 startup\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evstart\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e50000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 create publicatioin\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eall\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etables\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_create_logical_replication_slot\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pslot1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pgoutput\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eREPLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSYSADMIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eLOGIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eENCRYPTED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 4 create subscription\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egs_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egenerate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003ebin\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eo\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubscription\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e50000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=50001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false);\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- , worker_number=30\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 172.16.103.90\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eUPDATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSET\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;c\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;d\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;e\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eUPDATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSET\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;b\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;f\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCOMMIT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e7\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;d\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eUPDATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSET\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCOMMIT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 5 load data\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ein\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eseq\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003edo\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e50000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;BEGIN; INSERT INTO t1 VALUES($i,\u0026#39;a\u0026#39;); UPDATE t1 SET c2=\u0026#39;b\u0026#39; WHERE c1=$i-1; COMMIT;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003edev\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003enull\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026amp;\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edone\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ewait\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esleep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 5 check subscription\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"n\"\u003eo\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"n\"\u003eo\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"n\"\u003eo\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"n\"\u003eo\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egrep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eIrn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;rows\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egrep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eIrn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;rows\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ediff\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecat\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erm\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ef\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"k\"\u003eout\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 7 cleanup\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"空库feedback\"\u003e空库feedback\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evkill\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003erm -rf \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data*\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp -r ~/w5/data \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp -r ~/w5/data1 \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data1 -c \u003cspan class=\"s2\"\u003e\u0026#34;max_connections=4000\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_ctl start -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_ctl start -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 五、发布端（发布）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE PUBLICATION pub1 FOR all tables WITH (ddl=\u0026#39;all\u0026#39;);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE DATABASE db1\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE DATABASE db2\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d db1 -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE PUBLICATION p1 FOR all tables WITH (ddl=\u0026#39;all\u0026#39;);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d db1 -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;ps1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d db2 -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE PUBLICATION p2 FOR all tables WITH (ddl=\u0026#39;all\u0026#39;);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d db2 -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;ps2\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 六、订阅端（订阅）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc generate -S \u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/bin -o subscription\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=220);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE DATABASE db1\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE DATABASE db2\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d db1 -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE SUBSCRIPTION s1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=db1 user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION p1 WITH (create_slot=false, slot_name = \u0026#39;ps1\u0026#39;, copy_data = false, worker_number=220);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d db2 -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE SUBSCRIPTION s2 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=db2 user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION p2 WITH (create_slot=false, slot_name = \u0026#39;ps2\u0026#39;, copy_data = false, worker_number=220);\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;CREATE VIEW pstat AS SELECT slot_name,active,confirmed_flush, (pg_wal_lsn_diff(confirmed_flush, \u0026#39;0/0\u0026#39;) / (1024 * 1024))::int as confirmed_lsn FROM pg_get_replication_slots();\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 查看复制进度\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM pstat\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 查看速度\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT (pg_wal_lsn_diff(pg_current_wal_lsn(), \u0026#39;0/0\u0026#39;) / (1024 * 1024))::int as mb\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e65000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d pubdb -p \u003cspan class=\"m\"\u003e64000\u003c/span\u003e -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT * FROM vb_parallel_apply_stat()\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"子事务\"\u003e子事务\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-markdown\" data-lang=\"markdown\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e1.\u003c/span\u003e 这是一个基于opengauss开发的数据\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e2.\u003c/span\u003e 我已经设置了一些alias命令。全量编译vcmake。增量编译：vrecmake。启动集群：vinit, vstart。强制停止集群：vkill。\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e3.\u003c/span\u003e core文件目录：/data/\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e4.\u003c/span\u003e 并行逻辑复制关键代码：parallel_apply.cpp\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e5.\u003c/span\u003e $GAUSSHOME也就是install目录下，所有文件都是临时生成的，随便动\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evkill\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evinit\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 1 config\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;wal_level=logical\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;max_replication_slots=100\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;max_background_workers=100\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;max_logical_replication_workers=100\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e#\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;enable_audit=on\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e#\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;audit_buffer_size=262144\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e#\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;audit_directory_size=1073741824\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003esed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1i host all all 0.0.0.0/0 sha256\\n\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003epg_hba\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003econf\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eecho\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;host replication all 0.0.0.0/0 sha256\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003epg_hba\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003econf\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2 startup\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evstart\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e50000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 create publicatioin\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eall\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etables\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_create_logical_replication_slot\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pslot1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pgoutput\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eREPLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSYSADMIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eLOGIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eENCRYPTED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 4 create subscription\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egs_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egenerate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003ebin\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eo\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubscription\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e50000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=50001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false, worker_number=20);\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- , worker_number=30\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 172.16.103.90\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;222\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=2 [savepoint 2, xid:1-2]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;333\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=3 [savepoint 3, xid:1-2-3]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;444\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=4 [savepoint 4, xid:1-2-3-4]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es4\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;555\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=5 [savepoint 5, xid:1-2-3-4-5]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eROLLBACK\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;666\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=6  [rollback to 3: xid:1-2]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es5\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e7\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;777\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=7\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eRELEASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 此时，xid=6和xid=7会归并到xid=2的事务中\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=2（假设上面RELEASE到s1，则xid=1，和顶层事务一致）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCOMMIT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- \\! sleep 3\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 5 check subscription\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003exmin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_parallel_apply_stat\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003exmin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- rollback to top\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;222\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=2\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;333\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=3\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;444\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=4\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es4\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;555\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=5\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eROLLBACK\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;666\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=6\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es5\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e7\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;777\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=7\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eRELEASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 此时，xid=6和xid=7会归并到xid=2的事务中\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=2（假设上面RELEASE到s1，则xid=1，和顶层事务一致）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCOMMIT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- \\! sleep 3\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 5 check subscription\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003exmin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003exmin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_parallel_apply_stat\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 延时检查\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eADD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCONSTRAINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et3_c1_unique\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUNIQUE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDEFERRABLE\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 事务1                            -- 事务2\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e                                    \u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e                                    \u003c/span\u003e\u003cspan class=\"k\"\u003eSET\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCONSTRAINTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eALL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDEFERRED\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e                                    \u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCOMMIT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e                                    \u003c/span\u003e\u003cspan class=\"k\"\u003eCOMMIT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 7 cleanup\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"子事务--主键冲突\"\u003e子事务 + 主键冲突\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evkill\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evinit\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 1 config\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;wal_level=logical\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;max_replication_slots=100\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;max_background_workers=100\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evb_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;max_logical_replication_workers=100\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003esed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;1i host all all 0.0.0.0/0 sha256\\n\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003epg_hba\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003econf\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eecho\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;host replication all 0.0.0.0/0 sha256\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003epg_hba\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003econf\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2 startup\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evstart\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e50000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 create publicatioin\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eall\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etables\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_create_logical_replication_slot\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pslot1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pgoutput\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eREPLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSYSADMIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eLOGIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eENCRYPTED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 4 create subscription\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egs_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egenerate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003ebin\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eo\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubscription\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCONNECTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;host=127.0.0.1 port=50001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecreate_slot\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eslot_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pslot1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecopy_data\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eworker_number\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"mi\"\u003e20\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;old\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;222\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=2 [savepoint 2, xid:1-2]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;333\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=3 [savepoint 3, xid:1-2-3]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;444\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=4 [savepoint 4, xid:1-2-3-4]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es4\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCOMMIT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evb_parallel_apply_stat\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 7 cleanup\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"子事务开发\"\u003e子事务开发\u003c/h4\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 子事务开发\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_current_wal_lsn\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 场景一：relase commit\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;222\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=2\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;333\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=3\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;444\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=4\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es4\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;555\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=5\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eROLLBACK\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;666\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=6\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es5\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e7\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;777\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=7\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eRELEASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 此时，xid=6和xid=7会归并到xid=2的事务中\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=2（假设上面RELEASE到s1，则xid=1，和顶层事务一致）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCOMMIT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003exmin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"o\"\u003e!\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_xlogdump\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003epg_xlog\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003es\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003exxx\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ex\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003exid\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 场景二：release abort\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;222\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=2\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;333\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=3\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;444\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=4\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es4\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;555\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=5\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eROLLBACK\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;666\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=6\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es5\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e7\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;777\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=7\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eRELEASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 此时，xid=6和xid=7会归并到xid=2的事务中\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=2（假设上面RELEASE到s1，则xid=1，和顶层事务一致）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eROLLBACK\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCOMMIT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003exmin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- pg 用例\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eecho\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003ewal_level=logical\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003emax_worker_processes=20\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003emax_logical_replication_workers=20\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003emax_parallel_apply_workers_per_subscription=10 \u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003ePG_HOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003epostgresql\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003econf\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eALL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eTABLES\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eREPLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eLOGIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pu1.12345\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_create_logical_replication_slot\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pslot1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pgoutput\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2 create subscription\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIMARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUBSCRIPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esub1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCONNECTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;host=127.0.0.1 port=5432 dbname=pubdb user=pu1 password=pu1.12345 replication=database\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003ecreate_slot\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eslot_name\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pslot1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003ecopy_data\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003estreaming\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"n\"\u003eparallel\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 test transaction\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- \\c pubdb\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- BEGIN;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- INSERT INTO t1 VALUES(1,\u0026#39;111\u0026#39;); -- top xid\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- SAVEPOINT s1;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- INSERT INTO t1 VALUES(2,\u0026#39;222\u0026#39;); -- subxid 2\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- SAVEPOINT s2;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- INSERT INTO t1 VALUES(3,\u0026#39;333\u0026#39;); -- subxid 3\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- SAVEPOINT s3;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- INSERT INTO t1 VALUES(4,\u0026#39;444\u0026#39;); -- subxid 4\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- SAVEPOINT s4;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- INSERT INTO t1 VALUES(5,\u0026#39;555\u0026#39;); -- subxid 5\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- ROLLBACK TO SAVEPOINT s2;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- INSERT INTO t1 VALUES(6,\u0026#39;666\u0026#39;); -- subxid 6\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- SAVEPOINT s5;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- INSERT INTO t1 VALUES(7,\u0026#39;777\u0026#39;); -- subxid 7\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- RELEASE SAVEPOINT s2;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- INSERT INTO t1 VALUES(8,\u0026#39;888\u0026#39;); -- 回到s1对应事务上下文\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- COMMIT;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;111\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;222\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=2\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;333\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=3\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;444\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=4\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es4\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;555\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=5\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eROLLBACK\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;666\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=6\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es5\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e7\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;777\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=7\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eRELEASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 此时，xid=6和xid=7会归并到xid=2的事务中\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;888\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 假如xid=2（假设上面RELEASE到s1，则xid=1，和顶层事务一致）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eROLLBACK\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSAVEPOINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCOMMIT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 4 check\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003exmin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_stat_subscription\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003exmin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 发布端：2阶段处理\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eReleaseSavepoint\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"n\"\u003eloop\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ecur\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eCurrentTransactionState\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ecur\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eblockState\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eTBLOCK_SUBRELEASE\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ecur\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ecur\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eparent\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eCommitTransactionCommand\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003eCurrentTransactionState\u003c/span\u003e \u003cspan class=\"ow\"\u003eis\u003c/span\u003e \u003cspan class=\"n\"\u003eTBLOCK_SUBRELEASE\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"n\"\u003eloop\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eCommitSubTransaction\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eAtSubCommit_childXids\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eCurrentTransactionState\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eparent\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003echildXids\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ecnt\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eCurrentTransactionState\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003exid\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003ePopTransaction\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eCurrentTransactionState\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003es\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eparent\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 订阅端：\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003epa_start_subtrans\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eDefineSavepoint\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003esubxactlist\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003elappend_xid\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esubxactlist\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ecurrent_xid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eapply_handle_stream_commit\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003epa_stream_abort\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"n\"\u003eloop\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ecurxid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003esubxactlist\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003ecurxid\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"n\"\u003esubxid\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eRollbackToSavepoint\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e实现原理：\u003c/p\u003e","title":"PostgreSQL 3-13 逻辑复制测试记录"},{"content":"目录 目录 1 基本概念 1.1 业务场景 1.2 逻辑复制 1.3 实现思路 1.4 基本概念 2 使用方法 2.1 发布端：配置参数 2.2 发布端：创建发布 2.3 订阅端：创建订阅 3 核心设计 3.1 整体架构 3.2 工作流程 3.3 数据格式 4 实现源码 4.1 订阅端：apply-launch 4.2 订阅端：apply-worker 4.3 发布端：postmaster 4.4 发布端：wal-sender 5 性能优化 5.1 现状 5.2 优化方案 优化点一：发布端-流复制协议（逻辑数据） 优化点二：订阅段-并行回放机制（逻辑数据） 优化点三：发布端-并行解码机制 5.3 未来方案 一、计划优化点一：发布端-事务提交等待 5.4 方案分析 一、事务正确性 6 性能测试 参考资料 1 基本概念 1.1 业务场景 场景一：数据共享（异构数据库）\n1个公司，有2个部门：商品库存部门、商品成本部门。2个部门有不同技术栈，使用不同数据库产品:postgresql、mysql。2个部门需共享相同的表：商品信息表。\n场景二：数据容灾\n应用存储数据时，同时将数据存储至postgresql于mysql中，避免某款数据库出现无法恢复的数据损坏问题。\n场景三：版本升级\n从postgresql 13版本，升级到postgresql 16版本。\n场景四：数据迁移（异构数据库）\n从postgresql，将数据库迁移到mysql中。\n1.2 逻辑复制 从一个数据库中，将针对指定表的insert、delete、update等写操作，复制到其他另一个数据库、工具等。\n复制该场景中，有2种角色：\n发布端：发送端 订阅端：接收端 1.3 实现思路 此处，以postgresql为例，逻辑复制实现思路如下：\n上图中，关键流程如下：\n执行sql：应用执行insert、delete、update等语句 生成wal：postgres进程执行sql，生成wal，将wal写入文件 发送wal：如果启用逻辑复制，发布端会启动一个用于逻辑复制的wal-sender进程，读取wal，将wal解码为logical-wal，并将logical-wal发送给订阅端 重放logical-wal：订阅端将logical-wal当做单条insert、delete、update语句执行 1.4 基本概念 逻辑复制大致流程，与物理复制类似。不过，在复制流程中，差异也很多，以上图为例，关键差异如下：\n物理复制 复制粒度：实例产生的所有wal 发送数据：wal 发送粒度：流 回放数据：回放wal 逻辑复制： 复制粒度：指定的一个或多个用户表，或者表中符合指定过滤条件的数据 发送数据：logical-wal。针对一个写操作，会发送一条对应的logical-wal，即一条message。message中的关键内容包括：操作、数据。 示例1： 执行sql：INSERT INTO t1 VALEUS (1, 'data1') 生成wal：[1] [1800 1810 0 1 ..] [1, 'data1'] ...。格式为：操作类型、filenode、数据等 格式： 发送logical-wal: [I] [1, 'data1'] 示例2： 执行sql：DELETE FROM t1 WHERE c2 = 'data1' 生成wal：[3] [1800 1810 0 1 ..]。格式为：操作类型、filenode等 发送logical-wal: [D] ['data1'] 发送粒度：默认情况下，是一个完整事务包含的多条message 回放数据：apply logical-wal。提取logical-wal中的操作与数据，调用heapam层接口。示例： 示例1： 接收logical-wal: [I] [1, 'data1'] 回放logical-wal：heap_insert 示例2： 接收logical-wal: [D] ['data1'] 回放logical-wal：heap_beginscan、heap_delete 2 使用方法 2.1 发布端：配置参数 修改wal级别，多存储一些信息\necho \u0026#34;wal_level=logical\u0026#34; \u0026gt;\u0026gt; $PGDATA/postgresql.conf 配置身份认证非核心参数\necho \u0026#34;max_replication_slots=4\u0026#34; \u0026gt;\u0026gt; $PGDATA/postgresql.conf echo \u0026#34;max_wal_senders=4\u0026#34; \u0026gt;\u0026gt; $$PGDATA/postgresql.conf echo \u0026#34;max_logical_replication_workers=32\u0026#34; \u0026gt;\u0026gt; $PGDATA/postgresql.conf echo \u0026#34;listen_addresses=\u0026#39;*\u0026#39;\u0026#34; \u0026gt;\u0026gt; $PGDATA/postgresql.conf sed -i \u0026#39;1i host all all 0.0.0.0/0 md5\\n\u0026#39; $PGDATA/pg_hba.conf echo \u0026#34;host replication all 0.0.0.0/0 md5\u0026#34; \u0026gt;\u0026gt; $PGDATA/pg_hba.conf 发布端：重启参数生效\n2.2 发布端：创建发布 创建表\nCREATE TABLE pt1(c1 INT,c2 TEXT); CREATE TABLE pt2(c1 INT, c2 TEXT); 创建发布信息\n指定哪些表需要复制。\nCREATE PUBLICATION pub1 FOR TABLE pt1,pt2; 创建复制槽\n存储复制状态：wal的位置。\n存储数据格式\nSELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); 创建用户：订阅端通过该用户连接发布端，以进行数据传输\nCREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; GRANT ALL ON pt1,pt2 TO pu1; 2.3 订阅端：创建订阅 创建表\n与发布端保持一致\nCREATE TABLE pt1(c1 INT,c2 TEXT); CREATE TABLE pt2(c1 INT, c2 TEXT); 创建订阅信息\nCREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=5432 dbname=pubdb user=pu1 password=pu1.12345\u0026#39; PUBLICATION pub1 WITH (create_slot = false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = true); 订阅端自动启动apply-worker进程，与发布端建立连接，接收发布端的logical-wal，并回放logical-wal。\n3 核心设计 3.1 整体架构 逻辑复制架构中，有3类角色：\n应用：发送sql 发布端：执行sql，生成wal，解码wal生成logical-wal，发送logical-wal 订阅端：接收logical-wal，回放logical-wal 以2个事务并发执行sql为例，在发布端，关键进程为wal-sender。在订阅端，关键进程为apply-worker。\n3.2 工作流程 以下是一个典型场景的大致流程：\n步骤1-9：发布端接收客户端连接，接收与执行sql 步骤10-28：订阅端启动实例，检查订阅信息，与发布端建立连接并进行逻辑复制 [发布端] [订阅端] postmaster postgres wal-writer wal-sender wal-file postmaster apply-launch apply-worker +-------------------+------------------------------+------------+---------------------------+---+---------------------------+---------------------------+----------------------+ | 1 receive connect | | | | | | | | 2 fork postgres -\u0026gt;| | | | | | | | | 3 receive sql | | | | | | | | delete .. t1 .. c1=10 | | | | | | | | 4 scan tuple from t1 | | | | | | | | 5 get tuple pointer | | | | | | | | 6 mark tuple deleted | | | | | | | | 7 generate wal | | | | | | | | type=delete,xid=11 | | | | | | | | filenode=1700,offset=8-3 | | | | | | | | data=\u0026#39;10\u0026#39;,column=1 | | | | | | | | 8 copy wal to wal-buffer ---\u0026gt;| | | | | | | | 9 write wal---------------------------\u0026gt;| | | | | | | | 10 startp | | | | | | 11 startup apply-launch -\u0026gt;| | | | | | | 12 read suscription | | | | | | 13 calucate worker num | | | | | \u0026lt;-------------------------| 14 register worker info | | | | | 15 read bgworker info | | | | | 16 startup apply-worker -----------------------------\u0026gt;| | \u0026lt;-------------------------------------------------------------+---------------------------+-----------------------------------------------------------| 17 ask publication | 18 receive connect | | | | 19 fork postgres as wal-sender ------------------------------\u0026gt;| | | | 20 read wal \u0026lt;-------------| | | 21 decod to decode-wal | | 22 send decoded-wal -----------------------------------------------------------------\u0026gt;| | 23 receive decoded-wal | 24 apply decoded-wal | (if is postgresql) | 25 scan tuple from t1 | 26 get tuple pointer | 27 mark tuple deleted | 28 generate wal 3.3 数据格式 4 实现源码 上述流程中可以看到，逻辑复制由订阅端触发。此处，从订阅端开始，介绍复制流程：\n4.1 订阅端：apply-launch 4.2 订阅端：apply-worker 4.3 发布端：postmaster 4.4 发布端：wal-sender 5 性能优化 5.1 现状 首先，以一个简单示例，介绍vastbase当前版本逻辑复制的工作流程，假设：有3个事务并行执行update, insert, delete等操作，复制流程如下：\n各关键步骤的解释如下：\n发布端 生成wal: 执行事务，生成wal。产生wal的操作包括：begin, insert, update, delete, commit等 读取wal-reacord: wal-sender线程，按序读取wal-record 解码wal-record：wal-sender线程，提取wal-record中的关键信息，包括操作类型、tuple中的数据等逻辑信息，不包括filenode等物理信息，生成logical-msg。1条wal-record生成1条logic-msg 缓存logic-msg：生成logic-msg后，一般不直接发送，而是先缓存，达到特定条件才发送。属于同一事务的logical-msg缓存在一起 发送txn-package：当解码到commit transaction的wal-record时，发送一次txn-package，包含该事务所有的logic-msg 订阅端 接收txn-package：apply-worker线程，持续接收txn-package 回放logic-msg：从txn-package按序读取logic-msg中，解析操作类型、数据等，调用heapam层接口重放logical-msg 当前版本，几个关键设计如下：\n发布端 生成wal 读取wal-record 解码wal-record 发送txn-package： 发送内容：发送3个txn-package，1个txn-packag包含1个事务的所有logical-msg 发送时机：解码到commit transaction的wal-record后 订阅端 接收txn-package：串行接收3个txn-package 回放logic-msg：串行回放txn-package中的所有logical-msg 5.2 优化方案 优化点一：发布端-流复制协议（逻辑数据） 从订阅段角度看，一次接收与处理一个事务的package，复制过程是串行的。\n流复制协议，主要优化上述流程中的：发送txn-package、接收txn-package步骤，让发布端并行发送多个事务的logical-msg。即同一时刻，订阅端可能存在多个未提交的事务。\n复制流程中，改动如下：\n发布端 生成wal 读取wal-record 解码wal-record 发送stm-package： 发送内容：发送3个或更多的stm-package，1个stm-packag包含1个事务的部分logical-msg 发送时机：已缓存的logical-msg总大小达到阈值，以及解码到commit transaction的wal-record后 订阅端 接收stm-package：接收3个或更多的stm-package 回放logic-msg 流程图如下：\n优化点二：订阅段-并行回放机制（逻辑数据） 并行回放机制，主要优化上述流程中的：回放logical-msg步骤，让订阅端并行回放多个事务的logical-msg。流复制协议，让发布端并行发送事务数据，并行回放机制，依赖流复制协议。\n复制流程中，改动如下：\n发布端 生成wal 读取wal-record 解码wal-record 发送stm-package： 订阅端 接收stm-package：leader线程，持续接收stm-package，提取、记录事务信息，分发stm-package给worker，由worker完成apply。从package中提取xid，判断事务状态： 事务开始：（即本事务的第1个stm-package） 尝试申请1个空闲的worker，发送stm-package。之后，worker被该事务独占，只接收、回放本事务的stm-package，直到回放完事务commit或abort的logical-msg，才释放worer 如果没有空闲worker，stm-package会暂时缓存，等待空闲worker 事务进程中（即本事务的第2+个stm-package） 查找已占用的worer，发送stm-package 事务结束（package中commit/abort对应的logical-msg） 查找对应的worer，发送stm-package，等待对commit/abort的apply，才继续接收下一个package 回放logic-msg：worker线程，接收stm-package，提取logical-msg中的信息，调用heapam接口回放。 流程图如下：\n另外，事务并行后，需确保数据一致性。示例：在发布单，有事务1和2，更新同1个tuple，事务1先更新，事务wal日志如下：\nB: 1 B: 2 U: 1 -- 先更新 C: 1 U: 2 -- 事务1提交后，才更新成功 C: 2 在并行回放场景，订阅端，必须确保：C:1限制，U:2后执行。当前方案中，解决该问题的设计如下：\n发布端：解码到C后，直接发送 订阅端：接收到C后，等待C回放完成，再继续接收后续的logical-msg 另外，还有一些特殊场景，与核心设计无关，此处不展开讨论，比如：\n混合机制：发布端同时发送stm-packpage和txn-package（订阅端启用1个txn-worker和多个stm-worker，txn-worker只处理txn-package） 抢占机制：收到stm-package，内含commit的logical-msg，但是，没有空闲的stm-worker，无法处理commit。（此时txn-worker是空闲的，抢占txn-worker） 优化点三：发布端-并行解码机制 高并发场景，在发布端，有数百个线程执行事务并生成wal，而仅有1个线程解码wal。实现流复制协议、并行回放机制后，解码存在瓶颈，因此，需使用并行解码机制。\n当前版本的vastbase中，已具备并行解码功能，只是无法用于逻辑复制场景，需额外改动适配。\n复制流程中，改动如下：\n发布端 生成wal 读取wal-record 以前，读取、解码、发送步骤，由1个wal-sender线程完成。现在，将读取、解码、发送等步骤，拆分为多个线程。该机制非本次新增，此处不再详细介绍。 解码wal-record 发送stm-package 订阅端 接收stm-package 回放logic-msg 最终，集成3个优化方案后，流程图如下：\n目前，测试数据如下：\n测试场景：tpcc\n部署：单机 warhouse：100 并发：400 tpmc：约40w 测试结果\n基线： 发布端wal生成速度：约100m/s 端到端逻辑复制：约10m/s 目标： 端到端逻辑复制：70-100m/s 优化后： 端到端逻辑复制：解码、发送、接收、多线程分发、并行回放(60-100个线程)：约50m/s 订阅端只接收：解码、发送、接收：80+m/s 订阅端只多线程分发：解码、发送、接收、多线程分发：70+m/s 性能瓶颈\nworker饥饿：通过火焰图分析，订阅端的worker线程，大部分时候出于饥饿状态，需继续优化，充分利用worker线程。 负载均衡：tpcc中，1个事务中执行的写操作，从5个到20+个不等，订阅端回放结果如下： 5.3 未来方案 一、计划优化点一：发布端-事务提交等待 发布端解码事务commit日志后，判断订阅端进行中的事务量，如果事务较少，则先发送一批其他事务的stm-packpage，再发送commit的logical-msg\n5.4 方案分析 一、事务正确性 6 性能测试 参考资料 pg 邮件列表：https://www.postgresql.org/list/pgsql-hackers/ ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/3-13-logical-replication-tuning/","summary":"\u003ch1 id=\"目录\"\u003e目录\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E7%9B%AE%E5%BD%95\"\u003e目录\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5\"\u003e1 基本概念\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-1-%E4%B8%9A%E5%8A%A1%E5%9C%BA%E6%99%AF\"\u003e1.1 业务场景\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-%E9%80%BB%E8%BE%91%E5%A4%8D%E5%88%B6\"\u003e1.2 逻辑复制\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-3-%E5%AE%9E%E7%8E%B0%E6%80%9D%E8%B7%AF\"\u003e1.3 实现思路\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-4-%E5%9F%BA%E6%9C%AC%E6%A6%82%E5%BF%B5\"\u003e1.4 基本概念\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-%E4%BD%BF%E7%94%A8%E6%96%B9%E6%B3%95\"\u003e2 使用方法\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#2-1-%E5%8F%91%E5%B8%83%E7%AB%AF%EF%BC%9A%E9%85%8D%E7%BD%AE%E5%8F%82%E6%95%B0\"\u003e2.1 发布端：配置参数\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-2-%E5%8F%91%E5%B8%83%E7%AB%AF%EF%BC%9A%E5%88%9B%E5%BB%BA%E5%8F%91%E5%B8%83\"\u003e2.2 发布端：创建发布\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-3-%E8%AE%A2%E9%98%85%E7%AB%AF%EF%BC%9A%E5%88%9B%E5%BB%BA%E8%AE%A2%E9%98%85\"\u003e2.3 订阅端：创建订阅\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-%E6%A0%B8%E5%BF%83%E8%AE%BE%E8%AE%A1\"\u003e3 核心设计\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#3-1-%E6%95%B4%E4%BD%93%E6%9E%B6%E6%9E%84\"\u003e3.1 整体架构\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-2-%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B\"\u003e3.2 工作流程\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-3-%E6%95%B0%E6%8D%AE%E6%A0%BC%E5%BC%8F\"\u003e3.3 数据格式\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-%E5%AE%9E%E7%8E%B0%E6%BA%90%E7%A0%81\"\u003e4 实现源码\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#4-1-%E8%AE%A2%E9%98%85%E7%AB%AF%EF%BC%9Aapply-launch\"\u003e4.1 订阅端：apply-launch\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-2-%E8%AE%A2%E9%98%85%E7%AB%AF%EF%BC%9Aapply-worker\"\u003e4.2 订阅端：apply-worker\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-3-%E5%8F%91%E5%B8%83%E7%AB%AF%EF%BC%9Apostmaster\"\u003e4.3 发布端：postmaster\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-4-%E5%8F%91%E5%B8%83%E7%AB%AF%EF%BC%9Awal-sender\"\u003e4.4 发布端：wal-sender\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#5-%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96\"\u003e5 性能优化\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#5-1-%E7%8E%B0%E7%8A%B6\"\u003e5.1 现状\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#5-2-%E4%BC%98%E5%8C%96%E6%96%B9%E6%A1%88\"\u003e5.2 优化方案\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BC%98%E5%8C%96%E7%82%B9%E4%B8%80%EF%BC%9A%E5%8F%91%E5%B8%83%E7%AB%AF-%E6%B5%81%E5%A4%8D%E5%88%B6%E5%8D%8F%E8%AE%AE%EF%BC%88%E9%80%BB%E8%BE%91%E6%95%B0%E6%8D%AE%EF%BC%89\"\u003e优化点一：发布端-流复制协议（逻辑数据）\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BC%98%E5%8C%96%E7%82%B9%E4%BA%8C%EF%BC%9A%E8%AE%A2%E9%98%85%E6%AE%B5-%E5%B9%B6%E8%A1%8C%E5%9B%9E%E6%94%BE%E6%9C%BA%E5%88%B6%EF%BC%88%E9%80%BB%E8%BE%91%E6%95%B0%E6%8D%AE%EF%BC%89\"\u003e优化点二：订阅段-并行回放机制（逻辑数据）\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BC%98%E5%8C%96%E7%82%B9%E4%B8%89%EF%BC%9A%E5%8F%91%E5%B8%83%E7%AB%AF-%E5%B9%B6%E8%A1%8C%E8%A7%A3%E7%A0%81%E6%9C%BA%E5%88%B6\"\u003e优化点三：发布端-并行解码机制\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#5-3-%E6%9C%AA%E6%9D%A5%E6%96%B9%E6%A1%88\"\u003e5.3 未来方案\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%80%E3%80%81%E8%AE%A1%E5%88%92%E4%BC%98%E5%8C%96%E7%82%B9%E4%B8%80%EF%BC%9A%E5%8F%91%E5%B8%83%E7%AB%AF-%E4%BA%8B%E5%8A%A1%E6%8F%90%E4%BA%A4%E7%AD%89%E5%BE%85\"\u003e一、计划优化点一：发布端-事务提交等待\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#5-4-%E6%96%B9%E6%A1%88%E5%88%86%E6%9E%90\"\u003e5.4 方案分析\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%80%E3%80%81%E4%BA%8B%E5%8A%A1%E6%AD%A3%E7%A1%AE%E6%80%A7\"\u003e一、事务正确性\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#6-%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95\"\u003e6 性能测试\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99\"\u003e参考资料\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"1-基本概念\"\u003e1 基本概念\u003c/h1\u003e\n\u003ch2 id=\"11-业务场景\"\u003e1.1 业务场景\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e场景一：数据共享（异构数据库）\u003c/strong\u003e\u003cbr\u003e\n1个公司，有2个部门：商品库存部门、商品成本部门。2个部门有不同技术栈，使用不同数据库产品:postgresql、mysql。2个部门需共享相同的表：商品信息表。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e场景二：数据容灾\u003c/strong\u003e\u003cbr\u003e\n应用存储数据时，同时将数据存储至postgresql于mysql中，避免某款数据库出现无法恢复的数据损坏问题。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e场景三：版本升级\u003c/strong\u003e\u003cbr\u003e\n从postgresql 13版本，升级到postgresql 16版本。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e场景四：数据迁移（异构数据库）\u003c/strong\u003e\u003cbr\u003e\n从postgresql，将数据库迁移到mysql中。\u003c/p\u003e","title":"PostgreSQL 3-13 逻辑复制原理与性能优化"},{"content":"2 使用 2.1 发布端 配置\n# vb echo \u0026#34;wal_level=logical\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/postgresql.conf echo \u0026#34;max_replication_slots=4\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/postgresql.conf echo \u0026#34;max_wal_senders=4\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/postgresql.conf # echo \u0026#34;max_worker_processes=8\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/postgresql.conf echo \u0026#34;max_logical_replication_workers=32\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/postgresql.conf echo \u0026#34;listen_addresses=\u0026#39;*\u0026#39;\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/postgresql.conf sed -i \u0026#39;1i host all all 0.0.0.0/0 md5\\n\u0026#39; $GAUSSHOME/data/pg_hba.conf echo \u0026#34;host replication all 0.0.0.0/0 md5\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/pg_hba.conf # host all all 0.0.0.0/0 md5 psql -d postgres -c \u0026#34;SELECT name,setting FROM pg_settings WHERE name in (\u0026#39;wal_level\u0026#39;, \u0026#39;max_replication_slots\u0026#39;, \u0026#39;max_wal_senders\u0026#39;, \u0026#39;max_worker_processes\u0026#39;, \u0026#39;max_logical_replication_workers\u0026#39;)\u0026#34; 创建基表\nCREATE DATABASE pubdb; \\c pubdb CREATE TABLE pt1(c1 INT,c2 TEXT); CREATE TABLE pt2(c1 INT, c2 TEXT); INSERT INTO pt1 VALUES (1,\u0026#39;data1-1\u0026#39;), (2,\u0026#39;data1-2\u0026#39;); INSERT INTO pt1 VALUES (1,\u0026#39;data2-1\u0026#39;), (2,\u0026#39;data2-2\u0026#39;); 创建发布用户\n-- 订阅端通过pu1用户来连接发布端，以接收数据 CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; GRANT CONNECT ON DATABASE pubdb TO pu1; GRANT USAGE ON SCHEMA public TO pu1; GRANT ALL ON pt1,pt2 TO pu1; 导入tpcc数据\n./toolbm create 创建发布信息\n\\c pubdb set role pu1 password \u0026#39;pu1.12345\u0026#39;; set search_path to \u0026#39;pu1\u0026#39;; SELECT txid_current(); CREATE PUBLICATION pub1 FOR all tables; -- CREATE PUBLICATION pub1 FOR TABLE pt1,pt2; -- SELECT * FROM pg_publication; -- SELECT * FROM pg_publication_rel; -- 设置发布状态 SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); -- SELECT * FROM pg_replication_slots; -- SELECT * FROM pg_stat_replication_slots; -- 检查数据 -- SELECT * FROM pg_logical_slot_peek_changes(\u0026#39;pslot1\u0026#39;, NULL, NULL); -- 删除slot -- SELECT pg_drop_replication_slot(\u0026#39;pslot1\u0026#39;); 验证\n-- psql -h 172.16.100.134 -p 54000 -d pubdb -U pu1 -W pu1.12345 其他参考语法\n-- ALTER SUBSCRIPTION sub1 DISABLE; -- ALTER SUBSCRIPTION sub1 ENABLE; -- ALTER PUBlication pub1 ADD TABLE new_tbl; 2.2 订阅端 配置\n作为客户端访问发布端，无需配置任何guc参数\n# 如果发布端、订阅端在同一机器，确保二者端口不同 # echo \u0026#34;port=5433\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/datas/postgresql.conf 创建基表，与发布端表定义一致\n-- psql -p 5433 -d postgres CREATE DATABASE subdb; \\c subdb -- CREATE TABLE pt1(c1 INT,c2 TEXT); -- CREATE TABLE pt2(c1 INT, c2 TEXT); \\! vsql -d subdb -U pu1 -W \u0026#39;pu1.12345\u0026#39; -f /home/shenkun/tpcc/benchmarksql-5.0/run/sql.common/sub.sql 创建订阅信息\n\\! gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription -- x86 \\c subdb set search_path to \u0026#39;pu1\u0026#39;; CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.100.134 port=5433 dbname=pubdb user=pu1 password=pu1.12345\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false); -- arm CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.46 port=54001 dbname=pubdb user=pu1 password=pu1.12345\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false); -- SELECT * FROM pg_subscription; -- SELECT * FROM pg_subscription_rel; -- SELECT * FROM pg_stat_subscription; 查看表数据\n\\c subdb SELECT * FROM pt1; -- 向发布端表写数据，订阅端也会收到数据 \\c pubdb INSERT INTO pt1 VALUES(1, \u0026#39;data-after-sub\u0026#39;); \\c subdb SELECT * FROM pt1; 其他操作\n-- 暂停接受数据 ALTER SUBSCRIPTION sub1 DISABLE; 2.3 x86 all vb\n@vb CREATE DATABASE pubdb; \\c pubdb CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; GRANT CONNECT ON DATABASE pubdb TO pu1; GRANT USAGE ON SCHEMA public TO pu1; -- tpcc load data ------------------------------ ./toolbm create -- tpcc load data ------------------------------ \\c pubdb set role pu1 password \u0026#39;pu1.12345\u0026#39;; set search_path to \u0026#39;pu1\u0026#39;; CREATE PUBLICATION pub1 FOR all tables; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); CREATE DATABASE subdb; \\c subdb CREATE SCHEMA pu1; GRANT CONNECT ON DATABASE subdb TO pu1; GRANT USAGE ON SCHEMA public TO pu1; -- tpcc load data ------------------------------ vi cfg/props.pg subdb warhouse=0 ./toolbm create -- tpcc load data ------------------------------ \\! gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription \\c subdb set search_path to \u0026#39;pu1\u0026#39;; truncate bmsql_config,bmsql_customer,bmsql_district,bmsql_history,bmsql_item,bmsql_new_order,bmsql_oorder,bmsql_order_line,bmsql_stock,bmsql_warehouse; CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.100.134 port=5433 dbname=pubdb user=pu1 password=pu1.12345\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false); ------------------------------- SELECT txid_current(); vsql -d postgres -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; 2.3 vb-single-db(复制位置) rm -rf $GAUSSHOME/data* vinit sed -i \u0026#39;1i host all all 0.0.0.0/0 sha256\\n\u0026#39; $GAUSSHOME/data/pg_hba.conf echo \u0026#34;host replication all 0.0.0.0/0 sha256\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/pg_hba.conf echo \u0026#34; wal_level=logical max_replication_slots=400 max_background_workers=400 max_logical_replication_workers=400 max_wal_senders=4 listen_addresses=\u0026#39;*\u0026#39; port=64000 max_connections=1000 shared_buffers = 100GB work_mem = 1GB maintenance_work_mem = 4GB effective_cache_size = 500GB wal_buffers = 1GB checkpoint_timeout = 55min checkpoint_segments = 102400 checkpoint_timeout = 60min incremental_checkpoint_timeout = 120s max_process_memory = 700GB \u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/postgresql.conf vstart vsql -d postgres -p 64000 -r -- 2 发布端 -- 2.1 建表 CREATE DATABASE pubdb; CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; \\c pubdb CREATE TABLE pt1(c1 INT,c2 TEXT); CREATE TABLE pt2(c1 INT, c2 TEXT); INSERT INTO pt1 VALUES (1,\u0026#39;111111111111\u0026#39;), (2,\u0026#39;22222222222222\u0026#39;); INSERT INTO pt2 VALUES (1,\u0026#39;111111111111\u0026#39;), (2,\u0026#39;22222222222222\u0026#39;); -- 2.2 发布 CREATE PUBLICATION pub1 FOR all tables; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); -- 3 订阅端 -- 3.1 建表 \\c postgres CREATE DATABASE subdb; \\c subdb CREATE TABLE pt1(c1 INT,c2 TEXT); CREATE TABLE pt2(c1 INT, c2 TEXT); -- 3.2 订阅 \\! gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = true); -- 检查copy_data状态 -- 4 验证 \\c subdb SELECT * FROM pt1; \\c pubdb INSERT INTO pt1 VALUES (3,\u0026#39;33333333333\u0026#39;); INSERT INTO pt1 VALUES (3,\u0026#39;44444444444\u0026#39;); \\c subdb SELECT * FROM pt1; \\c pubdb INSERT INTO pt1 VALUES (3,\u0026#39;55555555555555555\u0026#39;); INSERT INTO pt1 VALUES (3,\u0026#39;666666666666666\u0026#39;); INSERT INTO pt1 VALUES (3,\u0026#39;777777777777\u0026#39;); \\c subdb SELECT * FROM pt1; \\c pubdb INSERT INTO pt1 VALUES (3,\u0026#39;8888888\u0026#39;); INSERT INTO pt2 VALUES (3,\u0026#39;8888888\u0026#39;); -- 其他 -- 订阅端查看表状态 SELECT * FROM pg_subscription_rel; CREATE FUNCTION lsn(text) RETURNS bigint AS $$ SELECT ((\u0026#39;x\u0026#39; || lpad(split_part($1,\u0026#39;/\u0026#39;,1),8,\u0026#39;0\u0026#39;))::bit(32)::bigint\u0026lt;\u0026lt;32) | (\u0026#39;x\u0026#39; || lpad(split_part($1,\u0026#39;/\u0026#39;,2),8,\u0026#39;0\u0026#39;))::bit(32)::bigint $$ LANGUAGE sql IMMUTABLE; SELECT catalog_xmin,lsn(restart_lsn),lsn(confirmed_flush) FROM pg_get_replication_slots(); SELECT lsn(pg_current_wal_lsn()); -- 数据来源 -- pg_replication_origin，存储数据来源 roident | roname --------+---------- 1 | pg_%subid \\c subdb DROP SUBSCRIPTION sub1; multi_db_and_pub rm -rf $GAUSSHOME/data* vinit # 自己初始化数据库 sed -i \u0026#39;1i host all all 0.0.0.0/0 sha256\\n\u0026#39; $GAUSSHOME/data/pg_hba.conf echo \u0026#34;host replication all 0.0.0.0/0 sha256\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/pg_hba.conf echo \u0026#34; wal_level=logical max_replication_slots=32 max_wal_senders=4 max_logical_replication_workers=32 listen_addresses=\u0026#39;*\u0026#39; port=64000 max_connections=1000 shared_buffers = 100GB work_mem = 1GB maintenance_work_mem = 4GB effective_cache_size = 500GB wal_buffers = 1GB checkpoint_timeout = 55min checkpoint_segments = 102400 checkpoint_timeout = 60min incremental_checkpoint_timeout = 120s max_process_memory = 700GB \u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/postgresql.conf vstart # 自己启动数据库 vsql -d postgres -p 64000 -r -- 用户 CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; \\! gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription -- 发布端 CREATE DATABASE db1; \\c db1 CREATE TABLE ta1(c1 INT,c2 TEXT); CREATE TABLE tb1(c1 INT, c2 TEXT); INSERT INTO ta1 VALUES (1,\u0026#39;111\u0026#39;), (2,\u0026#39;222\u0026#39;); CREATE PUBLICATION pub1 FOR all tables WITH (ddl = \u0026#39;all\u0026#39;); SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); \\c postgres CREATE DATABASE db2; \\c db2 CREATE TABLE ta2(c1 INT,c2 TEXT); CREATE TABLE tb2(c1 INT, c2 TEXT); INSERT INTO ta2 VALUES (1,\u0026#39;111\u0026#39;), (2,\u0026#39;222\u0026#39;); CREATE PUBLICATION pub2 FOR all tables WITH (ddl = \u0026#39;all\u0026#39;); SELECT pg_create_logical_replication_slot(\u0026#39;pslot2\u0026#39;, \u0026#39;pgoutput\u0026#39;); \\c postgres CREATE DATABASE db3; \\c db3 CREATE PUBLICATION pub3 FOR all tables WITH (ddl = \u0026#39;all\u0026#39;); SELECT pg_create_logical_replication_slot(\u0026#39;pslot3\u0026#39;, \u0026#39;pgoutput\u0026#39;); -- 订阅端 \\c postgres CREATE DATABASE sdb1; \\c sdb1 CREATE TABLE ta1(c1 INT,c2 TEXT); CREATE TABLE tb1(c1 INT, c2 TEXT); CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=db1 user=pu1 password=pu1.12345\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false); \\c postgres CREATE DATABASE sdb2; \\c sdb2 CREATE TABLE ta2(c1 INT,c2 TEXT); CREATE TABLE tb2(c1 INT, c2 TEXT); CREATE SUBSCRIPTION sub2 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=db2 user=pu1 password=pu1.12345\u0026#39; PUBLICATION pub2 WITH (create_slot=false, slot_name = \u0026#39;pslot2\u0026#39;, copy_data = false); \\c postgres CREATE DATABASE sdb3; \\c sdb3 CREATE TABLE ta3(c1 INT,c2 TEXT); CREATE SUBSCRIPTION sub3 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=db3 user=pu1 password=pu1.12345\u0026#39; PUBLICATION pub3 WITH (create_slot=false, slot_name = \u0026#39;pslot3\u0026#39;, copy_data = false); \\c db1 INSERT INTO ta1 VALUES (1,\u0026#39;333\u0026#39;), (2,\u0026#39;444\u0026#39;); \\c db2 INSERT INTO ta2 VALUES (1,\u0026#39;555\u0026#39;), (2,\u0026#39;666\u0026#39;); \\c sdb1 SELECT * FROM ta1; \\c sdb2 SELECT * FROM ta2; SELECT * FROM rep_stat(\u0026#39;show\u0026#39;); -- 清理 \\c sdb1 DROP SUBSCRIPTION sub1; \\c sdb2 DROP SUBSCRIPTION sub2; \\c sdb3 DROP SUBSCRIPTION sub3; tpcc（with copy data） rm -rf $GAUSSHOME/data* # 一、发布端（导数） vinit sed -i \u0026#39;1i host all all 0.0.0.0/0 sha256\\n\u0026#39; $GAUSSHOME/data/pg_hba.conf echo \u0026#34;host replication all 0.0.0.0/0 sha256\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/pg_hba.conf cp -r $GAUSSHOME/data $GAUSSHOME/data1 echo \u0026#34; wal_level=logical max_wal_senders=4 max_replication_slots=256 max_background_workers=256 max_logical_replication_workers=256 listen_addresses=\u0026#39;*\u0026#39; port=64000 max_connections=1000 shared_buffers = 100GB work_mem = 1GB maintenance_work_mem = 4GB effective_cache_size = 500GB wal_buffers = 1GB checkpoint_timeout = 55min checkpoint_segments = 102400 checkpoint_timeout = 60min incremental_checkpoint_timeout = 120s max_process_memory = 700GB \u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/postgresql.conf vstart # 二、发布端（导数） vsql -d postgres -p 64000 -c \u0026#34;CREATE DATABASE pubdb;\u0026#34; vsql -d postgres -p 64000 -c \u0026#34;CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;;\u0026#34;; cd ~/tpcc source envbm ./toolbm create vpub # 100 warehouse, 400 term, 5 min, tmpc = 42w cd - # 三、订阅端（安装） echo \u0026#34; wal_level=logical max_replication_slots=400 max_background_workers=400 max_logical_replication_workers=400 max_connections=3000 max_wal_senders=4 listen_addresses=\u0026#39;*\u0026#39; port=65000 max_connections=1000 shared_buffers = 100GB work_mem = 1GB maintenance_work_mem = 4GB effective_cache_size = 500GB wal_buffers = 1GB checkpoint_timeout = 55min checkpoint_segments = 102400 checkpoint_timeout = 60min incremental_checkpoint_timeout = 120s max_process_memory = 700GB \u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data1/postgresql.conf vb_ctl start -D $GAUSSHOME/data1 # 四、订阅端（建表） vsql -d postgres -p 65000 -c \u0026#34;CREATE DATABASE pubdb;\u0026#34; vsql -d postgres -p 65000 -c \u0026#34;CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;;\u0026#34;; vsql -d pubdb -p 65000 -f ~/tpcc/benchmarksql-5.0/run/sql.common/tableCreates.sql vsql -d pubdb -p 65000 -f ~/tpcc/benchmarksql-5.0/run/sql.common/indexCreates.sql # 五、开始跑tpcc(换窗口) ./toolbm run vpub # 五、发布端（发布） vsql -d pubdb -p 64000 -c \u0026#34;CREATE PUBLICATION pub1 FOR all tables;\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; sleep 3 # 六、订阅端（订阅） gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription # don\u0026#39;t use localhost vsql -d pubdb -p 65000 -c \u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345\u0026#39; PUBLICATION pub1 WITH (slot_name = \u0026#39;pslot1\u0026#39;, worker_number = 380);\u0026#34; # create_slot=false, , copy_data = true # vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;start\u0026#39;)\u0026#34; # 七、发布端（监测） vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; # 八、订阅端（监测） vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM pg_subscription_rel\u0026#34; # 验证 for t in bmsql_config bmsql_customer bmsql_district bmsql_history bmsql_item bmsql_new_order bmsql_oorder bmsql_order_line bmsql_stock bmsql_warehouse; do echo \u0026#34;$t\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;SELECT count(1) FROM $t\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;SELECT count(1) FROM $t\u0026#34; done; vsql -d postgres -p 64000 -r\nCREATE TABLE tt1(c1 INT, c2 TEXT);\nCREATE PUBLICATION tpub1 FOR all tables;\nSELECT pg_create_logical_replication_slot(‘tpslot1’, ‘pgoutput’);\nvb_recvlogical -d postgres -p 64000 -U pu1 -W ‘pu1.12345’ –slot tpslot1 –start -f - -o proto_version=4 -o publication_names=tpub1 -o streaming=extreme\n2.3 vb-rep-tpcc rm -rf $GAUSSHOME/data* # 一、发布端（导数） vinit sed -i \u0026#39;1i host all all 0.0.0.0/0 sha256\\n\u0026#39; $GAUSSHOME/data/pg_hba.conf echo \u0026#34;host replication all 0.0.0.0/0 sha256\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/pg_hba.conf cp -r $GAUSSHOME/data $GAUSSHOME/data1 echo \u0026#34; wal_level=logical max_wal_senders=4 max_replication_slots=256 max_background_workers=256 max_logical_replication_workers=256 listen_addresses=\u0026#39;*\u0026#39; port=64000 max_connections=1000 shared_buffers = 100GB work_mem = 1GB maintenance_work_mem = 4GB effective_cache_size = 500GB wal_buffers = 1GB checkpoint_timeout = 55min checkpoint_segments = 102400 checkpoint_timeout = 60min incremental_checkpoint_timeout = 120s max_process_memory = 700GB \u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/postgresql.conf vstart # 二、发布端（导数） vsql -d postgres -p 64000 -c \u0026#34;CREATE DATABASE pubdb;\u0026#34; vsql -d postgres -p 64000 -c \u0026#34;CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;;\u0026#34;; cd ~/tpcc ./toolbm create vpub cd - # ./toolbm run vpub # 100 warehouse, 400 term, 5 min, tmpc = 42w # 三、订阅端（安装） echo \u0026#34; wal_level=logical max_replication_slots=400 max_background_workers=400 max_logical_replication_workers=400 max_wal_senders=4 listen_addresses=\u0026#39;*\u0026#39; port=65000 max_connections=1000 shared_buffers = 100GB work_mem = 1GB maintenance_work_mem = 4GB effective_cache_size = 500GB wal_buffers = 1GB checkpoint_timeout = 55min checkpoint_segments = 102400 checkpoint_timeout = 60min incremental_checkpoint_timeout = 120s max_process_memory = 700GB \u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data1/postgresql.conf vb_ctl start -D $GAUSSHOME/data1 # 四、订阅端（建表） vsql -d postgres -p 65000 -c \u0026#34;CREATE DATABASE pubdb;\u0026#34; vsql -d postgres -p 65000 -c \u0026#34;CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;;\u0026#34;; vsql -d pubdb -p 65000 -f ~/tpcc/benchmarksql-5.0/run/sql.common/tableCreates.sql vsql -d pubdb -p 65000 -f ~/tpcc/benchmarksql-5.0/run/sql.common/indexCreates.sql for t in bmsql_config bmsql_customer bmsql_district bmsql_history bmsql_item bmsql_new_order bmsql_oorder bmsql_order_line bmsql_stock bmsql_warehouse; do rm -f ./1.bin # 发布端：导出 vsql -d pubdb -p 64000 -c \u0026#34;COPY $t TO \u0026#39;`pwd`/1.bin\u0026#39; BINARY\u0026#34; # 订阅端：导入 vsql -d pubdb -p 65000 -c \u0026#34;COPY $t FROM \u0026#39;`pwd`/1.bin\u0026#39; BINARY\u0026#34; done; SEQ_VAL=$(vsql -d pubdb -p 64000 -c \u0026#34;SELECT last_value FROM bmsql_hist_id_seq;\u0026#34; -t -A) vsql -d pubdb -p 65000 -c \u0026#34;SELECT setval(\u0026#39;bmsql_hist_id_seq\u0026#39;, $SEQ_VAL);\u0026#34; # 备份 ----------------------------------- vb_ctl stop -D $GAUSSHOME/data vb_ctl stop -D $GAUSSHOME/data1 mkdir ~/repd cp -r $GAUSSHOME/data ~/repd cp -r $GAUSSHOME/data1 ~/repd # 测试 rm -rf $GAUSSHOME/data1 cp -r ~/repd/data1 $GAUSSHOME vb_ctl start -D $GAUSSHOME/data1 # ----------------------------- # 恢复 本地快速tpcc vkill rm -rf $GAUSSHOME/data* # cp -r ~/w100_t50/data_w100 $GAUSSHOME/data # cp -r ~/w100_t50/data1 $GAUSSHOME/ cp -r ~/w5/data $GAUSSHOME/data cp -r ~/w5/data1 $GAUSSHOME/ # export VBDATA=$GAUSSHOME/data # vb_guc set -D $VBDATA -c \u0026#34;ssl=on\u0026#34; # vb_guc set -D $VBDATA -c \u0026#34;require_ssl=off\u0026#34; # vb_guc set -D $VBDATA -c \u0026#34;ssl_cert_file=\u0026#39;`pwd`/server.crt\u0026#39;\u0026#34; # vb_guc set -D $VBDATA -c \u0026#34;ssl_key_file=\u0026#39;`pwd`/server.key\u0026#39;\u0026#34; # vb_guc set -D $VBDATA -c \u0026#34;ssl_ca_file=\u0026#39;`pwd`/demoCA/cacert.pem\u0026#39;\u0026#34; # export VBDATA=$GAUSSHOME/data1 # vb_guc set -D $VBDATA -c \u0026#34;ssl=on\u0026#34; # vb_guc set -D $VBDATA -c \u0026#34;require_ssl=on\u0026#34; # vb_guc set -D $VBDATA -c \u0026#34;ssl_cert_file=\u0026#39;`pwd`/server.crt\u0026#39;\u0026#34; # vb_guc set -D $VBDATA -c \u0026#34;ssl_key_file=\u0026#39;`pwd`/server.key\u0026#39;\u0026#34; # vb_guc set -D $VBDATA -c \u0026#34;ssl_ca_file=\u0026#39;`pwd`/demoCA/cacert.pem\u0026#39;\u0026#34; vb_ctl start -D $GAUSSHOME/data # gs_guc set -D $GAUSSHOME/data1 -c \u0026#34;max_replication_slots=400\u0026#34; # gs_guc set -D $GAUSSHOME/data1 -c \u0026#34;max_background_workers=400\u0026#34; # gs_guc set -D $GAUSSHOME/data1 -c \u0026#34;max_logical_replication_workers=400\u0026#34; vb_ctl start -D $GAUSSHOME/data1 # ----------------------------------- # # 验证 # for t in bmsql_config bmsql_customer bmsql_district bmsql_history bmsql_item bmsql_new_order bmsql_oorder bmsql_order_line bmsql_stock bmsql_warehouse; do # echo \u0026#34;$t\u0026#34; # vsql -d pubdb -p 64000 -c \u0026#34;SELECT count(1) FROM $t\u0026#34; # vsql -d pubdb -p 65000 -c \u0026#34;SELECT count(1) FROM $t\u0026#34; # done; # 五、发布端（发布） vsql -d pubdb -p 64000 -c \u0026#34;CREATE PUBLICATION pub1 FOR all tables;\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; # vsql -d pubdb -p 64000 -r # CREATE FUNCTION lsn(text) RETURNS bigint AS $$ SELECT ((\u0026#39;x\u0026#39; || lpad(split_part($1,\u0026#39;/\u0026#39;,1),8,\u0026#39;0\u0026#39;))::bit(32)::bigint\u0026lt;\u0026lt;32) | (\u0026#39;x\u0026#39; || lpad(split_part($1,\u0026#39;/\u0026#39;,2),8,\u0026#39;0\u0026#39;))::bit(32)::bigint $$ LANGUAGE sql IMMUTABLE; # \\q # SELECT catalog_xmin,lsn(restart_lsn),lsn(confirmed_flush) FROM pg_get_replication_slots(); # vsql -d pubdb -p 64000 -c \u0026#34; SELECT lsn(pg_current_wal_lsn());\u0026#34; # 七、发布端（监测） vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; # 跑10分钟 ./toolbm run vpub # --------------------------------------------- # 六、订阅端（订阅） gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription # don\u0026#39;t use localhost vsql -d pubdb -p 65000 -c \u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345 sslmode=disable\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = true, worker_number=300);\u0026#34; # worker_number=100 vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; sleep 20 vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; \u0026amp;\u0026amp; sleep 10 \u0026amp;\u0026amp; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; \u0026amp;\u0026amp; sleep 100 \u0026amp;\u0026amp; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; \u0026amp;\u0026amp; sleep 10 \u0026amp;\u0026amp; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; # 测试订阅速度 sleep 30 vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; \u0026amp;\u0026amp; sleep 100 \u0026amp;\u0026amp; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; \u0026amp;\u0026amp; sleep 100 \u0026amp;\u0026amp; vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; \u0026amp;\u0026amp; sleep 100 \u0026amp;\u0026amp; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; sleep 60 vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; \u0026amp;\u0026amp; sleep 100 \u0026amp;\u0026amp; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; # 八、订阅端（监测） vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; # 发 vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; \u0026amp;\u0026amp; sleep 10 \u0026amp;\u0026amp; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; # 订 vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;) LIMIT 10\u0026#34; \u0026amp;\u0026amp; sleep 10 \u0026amp;\u0026amp; vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;) LIMIT 10\u0026#34; # 八、公共 vsql -d pubdb -p 64000 -c \u0026#34;\\d+\u0026#34; \u0026amp;\u0026amp; vsql -d pubdb -p 65000 -c \u0026#34;\\d+\u0026#34; vsql -d pubdb -p 64000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; \u0026amp;\u0026amp; vsql -d pubdb -p 65000 -c \u0026#34;SELECT * FROM rep_stat(\u0026#39;show\u0026#39;)\u0026#34; # 重新测试 vsql -d pubdb -p 64000 -c \u0026#34;SELECT pg_replication_slot_advance(\u0026#39;pslot1\u0026#39;, pg_current_wal_lsn());\u0026#34; vsql -d pubdb -p 65000 -c \u0026#34;DROP SUBSCRIPTION sub1\u0026#34; # todo # 1. 内存管理 # 2. 停止线程 编号 tpcc并发数 tpmc (10min) tpmTotal 发布端速度 订阅端速度(2次抽样) 1 10 5.8w 12.9w 13.4 m/s 52.2 m/s 2 50 21.8w 48.6w 50.9 m/s {76.4, 77.3} m/s 3 100 33.3w 73.9w 77.5 m/s {74.0, 73.2} m/s 4 200 35.4w 78.7w 82.8 m/s {73.8, 70.7} m/s 5 300 36.3w 80.9w 84.9 m/s {66.4, 64.0} m/s 6 400 32.6w 72.6w 76.4 m/s {62.1, 60.8} m/s 测试环境：单机，kunpeng-920，128核，760G内存，tpcc 100 warehousee 发布端速度：tpcc运行10min，(结束lsn - 开始lsn) / 600s 订阅端速度：启动复制，抽样：(第130s的lsn - 第30s的lsn) / 100s，(第230s的lsn - 第130s的lsn) / 100s 假设:\nt1：备机升级停机时间 t2：追赶时间 s1：发布端，生成xlog速度 s2：发布端，追赶期间，生成xlog速度 s3：订阅端，追赶速度\n发布端xlog增量：t1 * s1 + t2 * s2\n订阅端xlog增量：t1 * 0 + t2 * s3 以100并发为例，备机停机t1=600s，s1=77，s3=70：\n如果s2降速至50，则t2 = 23100s = 38.5 min\n如果s2降速至40，则t2 = 1540s = 25.6 min\n如果s2降速至30，则t2 = 1155s = 19.2 min\n如果s2降速至20，则t2 = 924s = 15.4 min\n如果s2降速至10，则t2 = 770s = 12.8 min\n如果s2降速至0 ，则t2 = 660s = 11 min\n如果发布端通过降低并发数降速，s3能更高，如果并发数不变，通过其他方法降速，s3应该也不变。\n基础\n200并发 | 37.6w | 83.6w | 88m/s 不dispatch：120-130m/s 串行：11.1 m/s 串行，不dispatch：22.5 m/s 串行，不dispatch，并行解码：79 m/s 50并发 | 24.2w | 53.9w | 56.47m/s\n不apply\n200 | 37 | 82 | 87 | {89， 90}\n不dispatch\n200 | 38 | 84 | 88 |\n系统表新增1列：硬编码，无需升级脚本\n新增系统表 新增函数 新增xlog类型\ngaussdb灰度升级流程 主a 备b 备c +-----------------------+---------------------------+----------------------------- |1 ==\u0026gt;执行业务 |2 开始升级 |3 执行pre-upgrade脚本 (不停业务) |4 重放pre-upgrade xlog |5 重放pre-upgrade xlog |6 替换二进制 |7 kill进程 |8 重启进程 |9 物理复制追赶主机 |10 替换二进制 |11 kill进程 |12 重启进程 |13 物理复制追赶主机 |14 升为主机 |15 降为备机 |16 ==\u0026gt;执行业务 [以后b一直是主机] |17 替换二进制 |18 kill进程 |19 重启进程 |20 物理复制追赶主机 |21 执行post-upgrade脚本 |22 重放post-upgrade xlog |23 重放post-upgrade xlog |24 升级成功 vastbase滚动升级 主a 备b 备c +-----------------------+---------------------------+----------------------------- |1 ==\u0026gt;执行业务 |2 开始滚动升级，暂停物理复制 lag=400M |3 暂停物理复制 |4 创建逻辑复制槽 lsn1=1G |5 恢复物理复制 |6 物理复制追赶到逻辑复制槽 |6 开始单节点升级 |7 [升级] 停止进程 |8 [升级] 替换二进制等 |9 [升级] 启动进程 |10 单节点升级成功 |11 持续执行业务 lsn2=2G |12 创建订阅，启动逻辑复制，lsn1=1G |13 逻辑复制开始追赶（初始差距：lsn2-lsn1) |14 持续执行业务 lsn3=2.5G |15 逻辑复制持续追赶 lsn=1.6G |16 (可重置lag) |17 差距持续缩小（从lsn2-lsn1降低到lag） |18 发送停机命令 |19 停止业务 |20 差距持续缩小，从lag缩小至0 |21 停止进程成功 begin\ninsert t1\nupdate t2\ndelete t3\ncommit\nbegin\ninsert t3\nbegin\nupdate t1\nbegin\nupdate t4\nvb 特性开发 # create pulication CreateSubscription parse_subscription_options heap_open(\u0026#39;pg_subscription\u0026#39;) simple_heap_insert replorigin_create heap_open(\u0026#39;pg_replication_origin\u0026#39;) AttemptConnectPublisher ApplyLauncherWakeupAtCommit # send signal to apply-launcher # startup apply-launcher ApplyLauncherMain get_subscription_list heap_open(\u0026#39;pg_subscription\u0026#39;) logical_worker_launcher # startup apply-worker ApplyWorkerMain GetSubscription 2.4 90-pg16 copy-data pg(copy data)\npg_ctl stop -D $PG_HOME/data \u0026amp; pg_ctl stop -D $PG_HOME/data1 rm -rf $PG_HOME/data* initdb -D $PG_HOME/data sed -i \u0026#39;1i host all all 0.0.0.0/0 md5\\n\u0026#39; $PG_HOME/data/pg_hba.conf echo \u0026#34;host replication all 0.0.0.0/0 md5\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/pg_hba.conf cp -r $PG_HOME/data $PG_HOME/data1 echo \u0026#34; wal_level=logical max_replication_slots=4 max_wal_senders=4 max_worker_processes=8 max_logical_replication_workers=32 listen_addresses=\u0026#39;*\u0026#39; port=64000 max_connections=1000 password_encryption=md5 shared_buffers = 100GB work_mem = 1GB maintenance_work_mem = 4GB effective_cache_size = 500GB wal_buffers = 1GB checkpoint_timeout = 55min max_wal_size= 100GB \u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf echo \u0026#34; wal_level=logical max_replication_slots=4 max_wal_senders=4 max_worker_processes=8 max_logical_replication_workers=32 listen_addresses=\u0026#39;*\u0026#39; port=65000 max_connections=1000 password_encryption=md5 shared_buffers = 100GB work_mem = 1GB maintenance_work_mem = 4GB effective_cache_size = 500GB wal_buffers = 1GB checkpoint_timeout = 55min max_wal_size= 100GB \u0026#34; \u0026gt;\u0026gt; $PG_HOME/data1/postgresql.conf rm -f $PG_HOME/log $PG_HOME/log1 pg_ctl start -D $PG_HOME/data -l $PG_HOME/log pg_ctl start -D $PG_HOME/data1 -l $PG_HOME/log1 psql -d postgres -p 64000 -c \u0026#34;CREATE DATABASE pubdb;\u0026#34; psql -d postgres -p 64000 -c \u0026#34;CREATE USER pu1 REPLICATION SUPERUSER PASSWORD \u0026#39;pu1.12345\u0026#39;;\u0026#34;; psql -d postgres -p 65000 -c \u0026#34;CREATE DATABASE pubdb\u0026#34;; psql -d postgres -p 65000 -c \u0026#34;CREATE USER pu1 REPLICATION SUPERUSER PASSWORD \u0026#39;pu1.12345\u0026#39;;\u0026#34;; -- tpcc load data ------------------------------ ./toolbm create pub psql -d pubdb -p 65000 -f ~/tpcc/benchmarksql-5.0/run/sql.common/tableCreates.sql psql -d pubdb -p 65000 -f ~/tpcc/benchmarksql-5.0/run/sql.common/indexCreates.sql -- tpcc load data ------------------------------ psql -d pubdb -p 64000 -c \u0026#34;CREATE PUBLICATION pub1 FOR all tables;\u0026#34; psql -d pubdb -p 64000 -c \u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; psql -d pubdb -p 65000 -c \u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=localhost port=64000 dbname=pubdb user=pu1 password=pu1.12345\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = true);\u0026#34; psql -d pubdb -p 64000 -c \u0026#34;\\d+\u0026#34; \u0026amp;\u0026amp; psql -d pubdb -p 65000 -c \u0026#34;\\d+\u0026#34; psql -d postgres -p 64000 -c \u0026#34;SELECT rep_stat(\u0026#39;show\u0026#39;)\u0026#34; \u0026gt; $PG_HOME/start \u0026amp;\u0026amp; psql -d postgres -p 65000 -c \u0026#34;SELECT rep_stat(\u0026#39;show\u0026#39;)\u0026#34; \u0026gt;\u0026gt; $PG_HOME/start cat $PG_HOME/start psql -d postgres -p 64000 -c \u0026#34;SELECT rep_stat(\u0026#39;show\u0026#39;) AS ppp\u0026#34; \u0026amp;\u0026amp; psql -d postgres -p 65000 -c \u0026#34;SELECT rep_stat(\u0026#39;show\u0026#39;) AS sss\u0026#34; \u0026amp;\u0026amp; sleep 10 \u0026amp;\u0026amp; psql -d postgres -p 64000 -c \u0026#34;SELECT rep_stat(\u0026#39;show\u0026#39;) AS ppp\u0026#34; \u0026amp;\u0026amp; psql -d postgres -p 65000 -c \u0026#34;SELECT rep_stat(\u0026#39;show\u0026#39;) AS sss\u0026#34; psql -d postgres -p 64000 -c \u0026#34;SELECT rep_stat(\u0026#39;show\u0026#39;) AS ppp\u0026#34; \u0026amp;\u0026amp; sleep 10 \u0026amp;\u0026amp; psql -d postgres -p 64000 -c \u0026#34;SELECT rep_stat(\u0026#39;show\u0026#39;) AS ppp\u0026#34; ./toolbm run pub psql -d pubdb -p 64000 -c \u0026#34;SELECT count(*) FROm bmsql_order_line\u0026#34; \u0026amp;\u0026amp; psql -d pubdb -p 65000 -c \u0026#34;SELECT count(*) FROm bmsql_order_line\u0026#34; pg(copy data, stream)\npg_ctl stop -D $PG_HOME/data \u0026amp; pg_ctl stop -D $PG_HOME/data1 rm -f log log1 rm -rf $PG_HOME/data* initdb -D $PG_HOME/data sed -i \u0026#39;1i host all all 0.0.0.0/0 md5\\n\u0026#39; $PG_HOME/data/pg_hba.conf echo \u0026#34;host replication all 0.0.0.0/0 md5\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/pg_hba.conf cp -r $PG_HOME/data $PG_HOME/data1 echo \u0026#34; wal_level=logical max_replication_slots=4 max_wal_senders=4 max_worker_processes=8 max_logical_replication_workers=32 listen_addresses=\u0026#39;*\u0026#39; port=64000 max_connections=1000 password_encryption=md5 shared_buffers = 100GB max_wal_size= 10GB work_mem = 1GB maintenance_work_mem = 4GB effective_cache_size = 500GB wal_buffers = 1GB checkpoint_timeout = 55min \u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf echo \u0026#34; wal_level=logical max_replication_slots=4 max_wal_senders=4 max_worker_processes=8 max_logical_replication_workers=32 listen_addresses=\u0026#39;*\u0026#39; port=65000 max_connections=1000 password_encryption=md5 shared_buffers = 100GB max_wal_size= 10GB work_mem = 1GB maintenance_work_mem = 4GB effective_cache_size = 500GB wal_buffers = 1GB checkpoint_timeout = 55min \u0026#34; \u0026gt;\u0026gt; $PG_HOME/data1/postgresql.conf rm -f $PG_HOME/log $PG_HOME/log1 pg_ctl start -D $PG_HOME/data -l $PG_HOME/log pg_ctl start -D $PG_HOME/data1 -l $PG_HOME/log1 psql -d postgres -p 64000 -c \u0026#34;CREATE DATABASE pubdb;\u0026#34; psql -d postgres -p 64000 -c \u0026#34;CREATE USER pu1 REPLICATION SUPERUSER PASSWORD \u0026#39;pu1.12345\u0026#39;;\u0026#34;; psql -d postgres -p 65000 -c \u0026#34;CREATE DATABASE pubdb\u0026#34;; psql -d postgres -p 65000 -c \u0026#34;CREATE USER pu1 REPLICATION SUPERUSER PASSWORD \u0026#39;pu1.12345\u0026#39;;\u0026#34;; -- tpcc load data ------------------------------ ./toolbm create pub psql -d pubdb -p 65000 -f ~/tpcc/benchmarksql-5.0/run/sql.common/tableCreates.sql psql -d pubdb -p 65000 -f ~/tpcc/benchmarksql-5.0/run/sql.common/indexCreates.sql -- tpcc load data ------------------------------ psql -d pubdb -p 64000 -c \u0026#34;CREATE PUBLICATION pub1 FOR all tables;\u0026#34; psql -d pubdb -p 64000 -c \u0026#34; SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;);\u0026#34; psql -d pubdb -p 65000 -c \u0026#34;CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=localhost port=64000 dbname=pubdb user=pu1 password=pu1.12345\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = true, streaming=on);\u0026#34; psql -d pubdb -p 64000 -c \u0026#34;\\d+\u0026#34; \u0026amp;\u0026amp; psql -d pubdb -p 65000 -c \u0026#34;\\d+\u0026#34; psql -d postgres -p 64000 -c \u0026#34;SELECT rep_stat(\u0026#39;show\u0026#39;)\u0026#34; \u0026amp;\u0026amp; psql -d postgres -p 65000 -c \u0026#34;SELECT rep_stat(\u0026#39;show\u0026#39;)\u0026#34; \u0026gt; $PG_HOME/start psql -d postgres -p 64000 -c \u0026#34;SELECT rep_stat(\u0026#39;show\u0026#39;) AS ppp\u0026#34; \u0026amp;\u0026amp; psql -d postgres -p 65000 -c \u0026#34;SELECT rep_stat(\u0026#39;show\u0026#39;) AS sss\u0026#34; \u0026amp;\u0026amp; sleep 3 \u0026amp;\u0026amp; psql -d postgres -p 64000 -c \u0026#34;SELECT rep_stat(\u0026#39;show\u0026#39;) AS ppp\u0026#34; \u0026amp;\u0026amp; psql -d postgres -p 65000 -c \u0026#34;SELECT rep_stat(\u0026#39;show\u0026#39;) AS sss\u0026#34; ./toolbm run pub psql -d pubdb -p 64000 -c \u0026#34;SELECT count(*) FROm bmsql_order_line\u0026#34; \u0026amp;\u0026amp; psql -d pubdb -p 65000 -c \u0026#34;SELECT count(*) FROm bmsql_order_line\u0026#34; 3 原理 3.1 消息格式 # WalSndPrepareWriterHelper +-----------+------------+ | data type | data body | ------------+------------+ # part 1: data type +-----+-----------+------------+-----------+ | \u0026#39;w\u0026#39; | data_lsn | walend_lsn | sendtime | +-----+-----------+------------+-----------+ 1 8 8 8 # part 2: data body: message # 1. begin (logicalrep_write_begin) +-----+-----------+-------------+----------+----------+ | \u0026#39;B\u0026#39; | final_lsn | commit_time | xid | (csn) | +-----+-----------+-------------+----------+----------+ 1 8 8 8 8 # 2. commit +-----+-------+------------+----------+-------------+ | \u0026#39;C\u0026#39; | flags | commit_lsn | end_lsn | commit_time | +-----+-------+------------+----------+-------------+ 1 1 8 8 8 remote_lsn # 3. insert +-----+-------+--------------+ | \u0026#39;I\u0026#39; | relid | \u0026#39;N\u0026#39; | tuple | +-----+-------+--------------+ 1 4 1 .. # 4. delete +-----+-------+------------+--------+ | \u0026#39;D\u0026#39; | relid | \u0026#39;O\u0026#39; or \u0026#39;K\u0026#39; | tuple | +-----+-------+------------+--------+ 1 4 1 .. 3.2 关键系统表 -- 订阅端 SELECT * FROM pg_subscription; SELECT * FROM pg_subscription_rel; -- 发布端 SELECT pg_current_wal_lsn(); SELECT txid_current(); SELECT * FROM pg_publication; SELECT * FROM pg_publication_rel; SELECT * FROM pg_replication_slots; 3.2 关键逻辑 leader() { for (;;) msg = receive() switch (msgtype) { case \u0026#39;B\u0026#39;: txn_wkr.send(msg) case \u0026#39;C\u0026#39;: txn_wkr.send(msg) txn_wkr.send(ask_fdbk) recv(txn_wkr) case \u0026#39;S\u0026#39;: stm_wkr.alloc() if () } } while True: msg = receive() if \u0026#39;B\u0026#39;: 3.3 基本概念 csn (commit sequence number) 概念：提交序列号。xid表示事务开始顺序，csn表示事务提交顺序 用途：csn可替代传统snapshot，csn snapshot只需记录当前最大的csn即可 存储：tupe-header中，存储csn。xid与csn一起记录在提交日志clog中 3.4 维护复制位置 ======+===================================== | create slot 发布端：创建复制槽\nSELECT pg_current_wal_lsn(); SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); SELECT * FROM pg_get_replication_slots(); -- 从ReplicationCtl中获取状态 -- slot_name -- xmin -- cofirmed_flush : 已发送，已回放 -- restart_lsn : 根据cofirmed_flush，自动计算多余保留已回放的（例如cofirmed_flush=100， restart_lsn=50） 订阅端：维护复制位置\n断线重连时，订阅端决定复制位置\nCREATE SUBSCRIPTION .. SELECT * FROM pg_show_replication_origin_status(); -- 从repStateShm共享内存中获取状态，实际存储在 pg_replorigin/ 文件中（内存定期同步到文件中） -- local_id -- remote_lsn : 已接收，已回放（发布端的lsn） -- local_lsn : 已接收，已回放（订阅端的lsn） 订阅端：记录物化复制位置（发给发布端记录）\n# 提示：有的场景，不要求事务持久性，可以开启事务异步提交，比如存储日志的表 # 记录位置 apply_handle_commit apply_handle_commit_internal replorigin_session_origin_lsn = commit_data-\u0026gt;end_lsn # remote CommitTransactionCommand RecordTransactionCommit replorigin_session_advance(replorigin_session_origin_lsn, XactLastRecEnd) # (用于持久化) remote_lsn, local_lsn curRepState == repStatesShm = .. store_flush_position # (用于反馈发布端) remote_lsn, local_lsn dlist_push_tail(lsnMapping) # 反馈位置 send_feedback get_flush_position dlist_foreach_modify(lsnMapping) # 有个异步提交事务的参数 walrcv_send # 存储位置 CreateCheckPoint CheckPointReplicationOrigin disk_state.remote_lsn = repStatesShm-\u0026gt;remote_lsn == curRepState write(disk_state) 发布端：接收复制位置\n# 存储位置 CreateCheckPoint LogStandbySnapshot LogCurrentRunningXacts record-\u0026gt;self_lsn = XLogInsert(XLOG_RUNNING_XACTS) SnapBuildProcessRunningXacts(record-\u0026gt;self_lsn) SnapBuildSerialize LogicalIncreaseRestartDecodingForSlot slot-\u0026gt;candidate_restart_lsn = last_serialized_snapshot = record-\u0026gt;self_lsn # 发布端：更新位置 @pg-16 StartLogicalReplication WalSndLoop for (;;) ProcessRepliesIfAny ProcessStandbyMessage ProcessStandbyReplyMessage LogicalConfirmReceivedLocation slot-\u0026gt;confirmed_flus = fdbk.flush_lsn slot-\u0026gt;restart_lsn = slot-\u0026gt;candidate_restart_lsn # 发布端：使用位置 StartLogicalReplication CreateDecodingContext XLogBeginRead(slot-\u0026gt;restart_lsn) 订阅端：使用物理复制位置\n# 读取位置 StartupXLOG StartupReplicationOrigin read(\u0026#39;pg_logical/replorigin_checkpoint\u0026#39;) repStateShm-\u0026gt;states = disk_state.remote_lsn # 使用位置 ApplyWorkerMain replorigin_session_get_progress remote_lsn = curRepState.remote_lsn == repStatesShm.remote_lsn walrcv_startstreaming sub_startstreaming StartRemoteStreaming 问题1：apply xid=1, xid=2，checkpoint记录到xid=1，发生故障，重启后，会重复apply xid=2吗？\nCommitTransaction RecordTransactionCommit XactLogCommitRecord xl_origin.origin_lsn = replorigin_session_origin_lsn XLogInsert 3.5 维护数据基线（ TableSyncWorker） # 发布端 CREATE PUBLICATION pub1 FOR $tables; # 订阅端 CREATE SUBSCRIPTION ... CreateSubscription parse_subscription_options heap_open(\u0026#39;pg_subscription\u0026#39;) # catalog 1 simple_heap_insert replorigin_create heap_open(\u0026#39;pg_replication_origin\u0026#39;) # catalog 2: roident, roname check_publications # 检查publication是否存在 check_publications_origin walrcv_exec(\u0026#39;SELECT .. pg_get_publication_tables\u0026#39;) # 从发布端获取表信息 foreach (fetch_table_list) AddSubscriptionRelState(\u0026#39;pg_subscription_rel\u0026#39;) # catalog 3 # table_state = copy_data ? INIT : READY; ApplyLauncherWakeupAtCommit # send signal to apply-launcher 发布端：建表、导数（数据1）\n订阅端：建表、导数（数据2）\n订阅端：同步数据（复制数据1）\n-- 发布端：(create slog时，会创建snapshot，copy时会使用这个snapshot) lsn 1 2 3 4 5 6 7 ---------------------------\u0026gt; data a b c d e f g - lsn 3： - apply-worker：开始apply - table-sync-worker：开始copy lsn 1-3，表状态 init -\u0026gt; datasync -\u0026gt; finishedcopy - lsn 4: - apply-worker：发现lsn 4对应的表，还没copy完，不是r状态，等待 - table-sync-worker：copy 到 lsn 3后，开始进入追赶状态，追赶 lsn 3-4 init -\u0026gt; datasync -\u0026gt; finishedcopy -\u0026gt; (begin sync)waitsync -\u0026gt; catchup -\u0026gt; syncdone -\u0026gt; ready - lsn 5： - apply-worker：从lsn 5正常apply 1个synctable-worker处理1个表，发布端对应1个wal sender dispatch时，先处理commit，在处理sync table。sync时，根据已commit的lns。\nApplyWorkerMain start_table_sync # 1个进程，1个rel LogicalRepSyncTableStart UpdateSubscriptionRelState(\u0026#39;SUBREL_STATE_DATASYNC\u0026#39;) walrcv_exec(\u0026#39;BEGIN READ ONLY ISOLATION LEVEL REPEATABLE READ\u0026#39;) walrcv_create_slot(remote_lsn) # 创建slot copy_table logicalrep_relmap_update walrcv_exec(\u0026#39;COPY xx.xx (colname, ..) TO STDOUT\u0026#39;) walrcv_exec(\u0026#39;COMMIT\u0026#39;) UpdateSubscriptionRelState(\u0026#39;SUBREL_STATE_FINISHEDCOPY\u0026#39;) wait_for_worker_state_change(\u0026#39;SUBREL_STATE_CATCHUP\u0026#39;) publisher worker syncworker -------------------------------------------------------------- insert 1,10 create slot, lsn=10 insert 11 start rep, lsn=10 apply_dispatch 10 apply commit lsn=10 start table sync start sync lsn=10 apply lsn=11, skip copy lsn=10 state=syncwait wakeup syncworker wait state=syncdone sync lsn=11 阿芳滚动升级 # 0 获取旧安装包、补丁包 # 1 安装旧包 bash -x installcluster.sh -c A -k Vastbase-G100-3.0_Build9_30126-Linux-kunpeng920-no_mot-202601162225.tar.gz -H HAS-G100-3.6_7129-Linux-kunpeng920-202601141008_release.tar.gz -u sunwf -g sunwf -X /home/sunwf/setting.xml -p k8snode@123 -G 172.16.103.254 # 查看状态 cm_ctl query -Cvid vsql -d vastbase -r # 2 跑tpcc # 3 执行升级 rm -rf patch bash -x upgradecluster.sh -b xxx -u sunwf -g sunwf -X /home/sunwf/setting.xml -i n -l 100MB -p y -s y # 4 卸载集群 cd script ./gs_uninstall --delete-data --clear-disk # 看失败日志 3.6 定位死锁 SELECT usename, application_name, query_start, state, locktype, mode, granted, relation::regclass, query FROM pg_locks l JOIN pg_stat_activity a ON l.pid = a.pid WHERE NOT granted; WITH waiting AS ( SELECT l.pid AS waiting_pid, l.locktype, l.transactionid AS waiting_xid, l.mode AS waiting_mode FROM pg_locks l WHERE NOT l.granted AND l.locktype = \u0026#39;transactionid\u0026#39; ) SELECT w.waiting_pid, a.pid, a.usename, a.application_name, a.query_start, a.state, l.transactionid, l.mode, a.query FROM waiting w JOIN pg_locks l ON w.locktype = l.locktype AND w.waiting_xid = l.transactionid AND l.granted JOIN pg_stat_activity a ON l.pid = a.pid; 发布端，多个事务，如果没冲突，发布端可以并行，订阅端也可以并行\n第一次发送位置 @pg-16 # 发布端：更新位置 @pg-16 exec_replication_command if \u0026#39;CREATE SLOT\u0026#39;: CreateReplicationSlot elif \u0026#39;START REPLICATION\u0026#39; StartLogicalReplication ReplicationSlotAcquire MyReplicationSlot # 1. 读取slot CreateDecodingContext StartupDecodingContext AllocateSnapshotBuilder # 2. 初始化发送位置 builder-\u0026gt;start_decoding_at = start_lsn reorder-\u0026gt;begin = begin_cb_wrapper # 3. 注册回调函数 XLogBeginRead WalSndLoop(XLogSendLogical) for (;;) ProcessRepliesIfAny send_data -\u0026gt; XLogSendLogical XLogReadRecord # 4. 读取wal record LogicalDecodingProcessRecord GetRmgr rmgr.rm_decode if \u0026#39;xact\u0026#39;: xact_decode if \u0026#39;COMMIT\u0026#39;: ParseCommitRecord DecodeCommit SnapBuildCommitTxn if DecodeTXNNeedSkip: SnapBuildXactNeedsSkip ptr \u0026lt; start_decoding_at ReorderBufferForget ReorderBufferCommit ReorderBufferReplay ReorderBufferProcessTXN pgoutput_begin_txn elif \u0026#39;ABORT\u0026#39;: elif \u0026#39;\u0026#39; elif \u0026#39;heap\u0026#39;: if \u0026#39;INSERT/UPDATE/DELETE\u0026#39;: change_cb_wrapper pgoutput_change is_publishable_relation # 检查 RelationIdGetRelation ExecStoreHeapTuple MakeTupleTableSlot pgoutput_row_filter logicalrep_write_insert @g100 4 事务正确性 4.1 事务冲突场景 写-写场景\n2个事务，操作同一条数据，此时，2个事务的begin，commit顺序，可能会影响最终结果\n类型 INSERT UPDATE DELETE INSERT I-I I-U I-D UPDATE U-I U-U U-D DELETE D-I D-U D-D 写-写冲突问题\n写-写 已存在的数据。例如，已存在数据0，事务1操作数据0，事务2也操作数据0\n写-写 INSERT UPDATE DELETE INSERT I-I I-U I-D UPDATE U-I U-U(冲突) U-D(冲突，等价于U-U) DELETE D-I D-U(冲突，等价于U-U) D-D（冲突，等价与U-U） 写-写 新生成的数据。例如，事务1产生数据1，事务2操作数据1\n写-写 INSERT UPDATE DELETE INSERT I-I I-U（冲突） I-D（冲突，等价于I-U） UPDATE U-I U-U(冲突，等价于I-U) U-D(冲突，等价于I-U) DELETE D-I D-U D-D 写-写冲突示例\n写-写 已存在的数据\n-- 前置条件 create table t(c text); insert into t values(\u0026#39;0\u0026#39;); -- @事务x1 -- @事务x2 begin; -- 1 insert into t values(\u0026#39;-\u0026#39;); -- 2 begin; -- 3 insert into t values(\u0026#39;-\u0026#39;); -- 4 update t set c = \u0026#39;1\u0026#39; where c = \u0026#39;0\u0026#39;; -- 5 update t set c = \u0026#39;2\u0026#39; where c = \u0026#39;0\u0026#39;; -- 6 (与5冲突，阻塞，等待事务x1) commit; -- 7 commit; -- 8 写-写 新生成的数据\n-- 前置条件 create table t(c1 text); -- @事务x1 @-- 事务2 begin; -- 1 (先开始) insert into t values(\u0026#39;1\u0026#39;); -- 2 begin; -- 3 insert into t values(\u0026#39;-\u0026#39;); -- 4 commit; -- 5 update t set c1 = \u0026#39;2\u0026#39; where c1 = \u0026#39;1\u0026#39;; -- 6 (读已提交) commit; -- 7 4.2 事务并行分析 4.2.1 写-写 已存在的数据 执行顺序\n在read-commited隔离级别中，以下2种场景，结果一致。\n场景一：\n-- 前置条件 create table t(c text); insert into t values(\u0026#39;0\u0026#39;); -- @事务x1 -- @事务x2 begin; -- 1 insert into t values(\u0026#39;-\u0026#39;); -- 2 begin; -- 3 insert into t values(\u0026#39;-\u0026#39;); -- 4 update t set c = \u0026#39;1\u0026#39; where c = \u0026#39;0\u0026#39;; -- 5 update t set c = \u0026#39;2\u0026#39; where c = \u0026#39;0\u0026#39;; -- 6 (与5冲突，阻塞，等待事务x1) commit; -- 7 commit; -- 8 场景二：[1、2、3、4]的顺序，对结果无影响。[4、5]与[7、8]的顺序，对结果有影响。\n-- 前置条件 create table t(c text); insert into t values(\u0026#39;0\u0026#39;); -- @事务x1 -- @事务x2 begin; -- 1 insert into t values(\u0026#39;-\u0026#39;); -- 2 begin; -- 3 insert into t values(\u0026#39;-\u0026#39;); -- 4 update t set c = \u0026#39;1\u0026#39; where c = \u0026#39;0\u0026#39;; -- 5 update t set c = \u0026#39;2\u0026#39; where c = \u0026#39;0\u0026#39;; -- 6 (与5冲突，阻塞，等待事务x1) commit; -- 7 commit; -- 8 WAL日志顺序\n场景一\nlogic-lsn: 1 2 3 4 5 6 7 8 +---+---+---+---+----+---+----+---+ x1 | B | I | | | U1 | C | | | x2 | | | B | I | | | U2 | C | +---+---+---+---+----+---+----+---+ 场景二\nlogic-lsn: 1 2 3 4 5 6 7 8 +---+---+---+---+----+---+----+---+ x1 | | | B | I | U1 | C | | | x2 | B | I | | | | | U2 | C | +---+---+---+---+----+---+----+---+ 逻辑复制顺序\n场景一\n# send x1 +------+---+----+---+ | B-x1 | I | U1 | C | +------+---+----+---+ # send x2 +------+---+----+---+ | B-x2 | I | U2 | C | +------+---+----+---+ 场景二\n# send x1 +------+---+----+---+ | B-x1 | I | U1 | C | +------+---+----+---+ # send x2 +------+---+----+---+ | B-x2 | I | U2 | C | +------+---+----+---+ 4.2.2 写-写 新生成的数据 执行顺序\n场景一\n-- 前置条件 create table t(c1 text); -- @事务x1 -- @事务x2 begin; -- 1 (先开始) insert into t values(\u0026#39;1\u0026#39;); -- 2 begin; -- 3 insert into t values(\u0026#39;-\u0026#39;); -- 4 commit; -- 5 update t set c1 = \u0026#39;2\u0026#39; where c1 = \u0026#39;1\u0026#39;; -- 6 (读已提交) commit; -- 7 场景二\n-- 前置条件 create table t(c1 text); -- @事务x1 -- @事务x2 begin; -- 1 (先开始) insert into t values(\u0026#39;-\u0026#39;); -- 2 begin; -- 3 insert into t values(\u0026#39;1\u0026#39;); -- 4 commit; -- 5 update t set c1 = \u0026#39;2\u0026#39; where c1 = \u0026#39;1\u0026#39;; -- 6 (读已提交) commit; -- 7 WAL日志顺序\n为节约篇幅，此处不再详细展开分析，结论与上一章节一致。\n逻辑复制顺序\n同上。\nrel-1 1 2 3 4 5 commit C I ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/3-13-vb-rep/","summary":"\u003ch1 id=\"2-使用\"\u003e2 使用\u003c/h1\u003e\n\u003ch2 id=\"21-发布端\"\u003e2.1 发布端\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e配置\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# vb\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;wal_level=logical\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;max_replication_slots=4\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;max_wal_senders=4\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# echo \u0026#34;max_worker_processes=8\u0026#34; \u0026gt;\u0026gt; $GAUSSHOME/data/postgresql.conf\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;max_logical_replication_workers=32\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;listen_addresses=\u0026#39;*\u0026#39;\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esed -i \u003cspan class=\"s1\"\u003e\u0026#39;1i host all all 0.0.0.0/0 md5\\n\u0026#39;\u003c/span\u003e \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data/pg_hba.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;host replication all 0.0.0.0/0 md5\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data/pg_hba.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# host all all 0.0.0.0/0 md5\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epsql -d postgres -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT name,setting FROM pg_settings WHERE name in\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003e    (\u0026#39;wal_level\u0026#39;, \u0026#39;max_replication_slots\u0026#39;, \u0026#39;max_wal_senders\u0026#39;, \u0026#39;max_worker_processes\u0026#39;, \u0026#39;max_logical_replication_workers\u0026#39;)\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e创建基表\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epubdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ept1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ept2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ept1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;data1-1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;data1-2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ept1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;data2-1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;data2-2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e创建发布用户\u003c/p\u003e","title":"PostgreSQL 3-13 Vastbase 逻辑复制"},{"content":" 2025-11-21：持续更新中…\n1 需求概述 1.1 原始需求 主备部署模式下，滚动升级时，可能存在主节点未升级，备节点已升级的情况。在该条件下，客户要求主节点持续执行事务，并且主节点及时将数据同步至备节点。目前，存在一下问题：\n物理复制无法使用：由于主节点、备节点版本不一致，主节点生成的wal，备节点可能无法使用。因此，只能使用逻辑复制方案。 逻辑复制性能较低：主节点作为发布端，解码wal。备节点作为订阅端，接收loggic-wal，并且回放logic-wal，可解决主备版本不一致的问题。但是，目前Vastbase的逻辑复制功能性能较低，无法满足及时同步数据的要求。 本需求将针对上述场景，端到端优化逻辑复制功能，让逻辑复制性能整体提升5倍以上，达到100m/s的要求。\n需求来源：https://doc.weixin.qq.com/doc/w3_AYsAjQYkADwCNecwqsBM8ShS9YejB?scode=AHUAfwdSAA8UDeKla8AdwAfAa7AFk\u0026amp;roomid=Person%3A1688855660690652%3A1688855164259723\u0026amp;version=5.0.2.6008\u0026amp;platform=win 1.2 问题分析 逻辑复制分为多个阶段，openGauss和PostgreSQL在部分阶段中做了优化，但未端到端优化。因此，本文将以早期逻辑复制为基础，指出优化设计。\n版本一：串行复制 在postgresql 13以及之前版本，逻辑复制的关键设计如下：\n发布端： 解码日志：wal-sender进程，持续读取wal，串行对wal进行decode，生成logic-wal，并将不同事务的logic-wal，分别存放。 发送日志：对wal进行decode时，如果是事务提交产生的wal，则将该事务的所有logic-wal打包，并发送到订阅端。 订阅端： 回放日志：apply-worker进程，一次接收同一事务的一批logic-wal，串行回放本批logic-wal后，重新等待下一个事务的logic-wal。 整体方案如下：\n以上设计，存在多项性能瓶颈，以常见的tpcc测试为例，可能有400+postgres进程在执行事务，实时产生wal日志。但是，只有1个wal-sender进程在串行解码日志，只有1个apply-workder在串行回放日志。\n1.3 方案设计 版本二：发布端并行解码 在openGauss中，针对发布端的解码日志阶段，进行了优化，引入多个decoder线程，并行解码wal生成logic-wal。方案设计如下：\n但是，在订阅端，每次对一个事务的一批logica-wal全部回放后，才会接收下一个事务的logic-wal。仅引入并发解码机制，对性能提升较小。发布端和订阅端，均存在负载不均衡的问题，例如，订阅端回放完一个事务的logic-wal之后，需等待下一个事务的logic-wal。\n版本三：流氏复制协议 在postgrsql 14版本，针对发布端发送日志阶段，进行了优化，引入流式复制协议，即无需一次发送完一个事务完整的一批logic-wal，而是随时发送logic-wal，即使事务未提交。可解决发布端、订阅端负载不均衡的问题。\n但是，在订阅端，tpcc场景，发布端400+postgres进程执行事务，订阅端1个apply-worker进程回放日志，仍是瓶颈。\n版本四：订阅端并行回放 在postgrsql 16版本，针对订阅端回放日志阶段，进行了优化，引入多个apply进程，并行回放logic-wal。方案设计如下：\n版本五：并行复制 结论：本需求参考性能测试结果，认为需同时结合：并行解码、流式复制、并行回放机制，才能提升逻辑复制端到端性能。 优先级：其中，流式复制、并行回放机制，对性能影响较大，优先级较高。可独立地、优先地实现。 其他工作：同时采用上述3个机制，需合理控制发布端解码速率、订阅端回放速率，在实现负载均衡的同事，避免logic-wal堆积。 2 设计分析 2.1 必要性 根据postgrsql-16的性能测试结果，流式复制和并行回放机制，可达到70Mb/s的复制速度。\n一、测试场景 测试机器： IP：172.16.103.90 硬件：CPU：鲲鹏920-ARM-128核。缓存L1-L2-L3：8M/64M/256M。内存：760G。磁盘：NVME 系统：openEuler tpcc测试场景（为了快速测试，不太标准） 数据量：100 warhouse 并发：400 执行时间：1 min 逻辑复制配置： 部署：发布端、订阅端在同一台机器（找不到2台性能机） 订阅：创建1个publiction，涵盖所有table 二、测试数据 由于机器、时间等限制，测试未严格控制变量，但是，和准确结果应该有80%以上符合度。\n版本 配置 tpmc 发布端-wal写入速度 逻辑复制速度（峰值） 逻辑复制速度（平均值） postgrsql-14 串行解码、非流式复制、串行回放 约65w 207 Mb/s - 16 Mb/s postgresql-16 串行解码、流式复制、串行回放 约65w 212 Mb/s 117 Mb/s 55 Mb/s postgresql-16 串行解码、流式复制、并行回放(4) 约65w 197 Mb/s 113 Mb/s 71 Mb/s 测试：贾旭辉 详细数据和结论见wiki：https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007526 尝试修改源码，让订阅端只接受日志，不apply，确定发布端解码和发送的瓶颈，但是，测试结果有点奇怪，有空再继续。 2.2 可行性 并行解码：openGauss已引入 流式复制：postgreql-16版本已成熟 并行回放：postgreql-16版本已成熟 2.3 潜在风险 一、数据有一致性 写写冲突\n-- 前提 create table t1(c1 text); insert into t1 values(\u0026#39;a\u0026#39;), (\u0026#39;b\u0026#39;), (\u0026#39;c\u0026#39;); -- 事务1 begin; insert into t1 values(\u0026#39;d\u0026#39;); -- 事务2 begin; delete from t1 where c1 = \u0026#39;b\u0026#39;; -- 事务1 update t1 set c1 = \u0026#39;b1\u0026#39; where c1 = \u0026#39;b\u0026#39;; -- 阻塞 写读无冲突\n-- 前提 create table t1(c1 text); insert into t1 values(\u0026#39;a\u0026#39;), (\u0026#39;b\u0026#39;), (\u0026#39;c\u0026#39;); -- 事务1 begin; insert into t1 values(\u0026#39;d\u0026#39;); -- 事务2 begin; insert into t1 values(\u0026#39;e\u0026#39;); -- 事务1 select * from t1; 并行回放：需验证数据最值一致性，不同事务语句的执行顺序，可能影响发布端、订阅端表数据的一致性。 2.4 工作量 3 详细设计 4 参考资料 逻辑复制架构：https://www.cnblogs.com/wy123/p/18946661 GaussDB并行逻辑解码：https://developer.huawei.com/consumer/cn/forum/topic/0201165508224221138 pg16并行回放：https://www.webkt.com/article/7715 openGauss并行解码测试：https://www.cnblogs.com/jerrywang1983/articles/18375212 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/3-13-replication/","summary":"\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003e2025-11-21：持续更新中…\u003c/strong\u003e\u003c/p\u003e\u003c/blockquote\u003e\n\u003ch1 id=\"1-需求概述\"\u003e1 需求概述\u003c/h1\u003e\n\u003ch2 id=\"11-原始需求\"\u003e1.1 原始需求\u003c/h2\u003e\n\u003cp\u003e主备部署模式下，滚动升级时，可能存在主节点未升级，备节点已升级的情况。在该条件下，客户要求主节点持续执行事务，并且主节点及时将数据同步至备节点。目前，存在一下问题：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e物理复制无法使用：由于主节点、备节点版本不一致，主节点生成的wal，备节点可能无法使用。因此，只能使用逻辑复制方案。\u003c/li\u003e\n\u003cli\u003e逻辑复制性能较低：主节点作为发布端，解码wal。备节点作为订阅端，接收loggic-wal，并且回放logic-wal，可解决主备版本不一致的问题。但是，目前Vastbase的逻辑复制功能性能较低，无法满足及时同步数据的要求。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e本需求将针对上述场景，端到端优化逻辑复制功能，让逻辑复制性能整体提升5倍以上，达到100m/s的要求。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e需求来源：\u003ca href=\"https://doc.weixin.qq.com/doc/w3_AYsAjQYkADwCNecwqsBM8ShS9YejB?scode=AHUAfwdSAA8UDeKla8AdwAfAa7AFk\u0026amp;roomid=Person:1688855660690652:1688855164259723\u0026amp;version=5.0.2.6008\u0026amp;platform=win\"\u003ehttps://doc.weixin.qq.com/doc/w3_AYsAjQYkADwCNecwqsBM8ShS9YejB?scode=AHUAfwdSAA8UDeKla8AdwAfAa7AFk\u0026amp;roomid=Person%3A1688855660690652%3A1688855164259723\u0026amp;version=5.0.2.6008\u0026amp;platform=win\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"12-问题分析\"\u003e1.2 问题分析\u003c/h2\u003e\n\u003cp\u003e逻辑复制分为多个阶段，openGauss和PostgreSQL在部分阶段中做了优化，但未端到端优化。因此，本文将以早期逻辑复制为基础，指出优化设计。\u003c/p\u003e\n\u003ch3 id=\"版本一串行复制\"\u003e版本一：串行复制\u003c/h3\u003e\n\u003cp\u003e在postgresql 13以及之前版本，逻辑复制的关键设计如下：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e发布端：\n\u003cul\u003e\n\u003cli\u003e解码日志：wal-sender进程，持续读取wal，串行对wal进行decode，生成logic-wal，并将不同事务的logic-wal，分别存放。\u003c/li\u003e\n\u003cli\u003e发送日志：对wal进行decode时，如果是事务提交产生的wal，则将该事务的所有logic-wal打包，并发送到订阅端。\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e订阅端：\n\u003cul\u003e\n\u003cli\u003e回放日志：apply-worker进程，一次接收同一事务的一批logic-wal，串行回放本批logic-wal后，重新等待下一个事务的logic-wal。\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e整体方案如下：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"pg-13\" loading=\"lazy\" src=\"/images/PostgreSQL/3-13-replication/pg-13.png\"\u003e\u003c/p\u003e\n\u003cp\u003e以上设计，存在多项性能瓶颈，以常见的tpcc测试为例，可能有400+postgres进程在执行事务，实时产生wal日志。但是，只有1个wal-sender进程在串行解码日志，只有1个apply-workder在串行回放日志。\u003c/p\u003e\n\u003ch2 id=\"13-方案设计\"\u003e1.3 方案设计\u003c/h2\u003e\n\u003ch3 id=\"版本二发布端并行解码\"\u003e版本二：发布端并行解码\u003c/h3\u003e\n\u003cp\u003e在openGauss中，针对发布端的解码日志阶段，进行了优化，引入多个decoder线程，并行解码wal生成logic-wal。方案设计如下：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"og\" loading=\"lazy\" src=\"/images/PostgreSQL/3-13-replication/og.png\"\u003e\u003c/p\u003e\n\u003cp\u003e但是，在订阅端，每次对一个事务的一批logica-wal全部回放后，才会接收下一个事务的logic-wal。仅引入并发解码机制，对性能提升较小。发布端和订阅端，均存在负载不均衡的问题，例如，订阅端回放完一个事务的logic-wal之后，需等待下一个事务的logic-wal。\u003c/p\u003e\n\u003ch3 id=\"版本三流氏复制协议\"\u003e版本三：流氏复制协议\u003c/h3\u003e\n\u003cp\u003e在postgrsql 14版本，针对发布端发送日志阶段，进行了优化，引入流式复制协议，即无需一次发送完一个事务完整的一批logic-wal，而是随时发送logic-wal，即使事务未提交。可解决发布端、订阅端负载不均衡的问题。\u003c/p\u003e\n\u003cp\u003e但是，在订阅端，tpcc场景，发布端400+postgres进程执行事务，订阅端1个apply-worker进程回放日志，仍是瓶颈。\u003c/p\u003e\n\u003ch3 id=\"版本四订阅端并行回放\"\u003e版本四：订阅端并行回放\u003c/h3\u003e\n\u003cp\u003e在postgrsql 16版本，针对订阅端回放日志阶段，进行了优化，引入多个apply进程，并行回放logic-wal。方案设计如下：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"pg-16\" loading=\"lazy\" src=\"/images/PostgreSQL/3-13-replication/pg-16.png\"\u003e\u003c/p\u003e\n\u003ch3 id=\"版本五并行复制\"\u003e版本五：并行复制\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e结论：本需求参考性能测试结果，认为需同时结合：并行解码、流式复制、并行回放机制，才能提升逻辑复制端到端性能。\u003c/li\u003e\n\u003cli\u003e优先级：其中，流式复制、并行回放机制，对性能影响较大，优先级较高。可独立地、优先地实现。\u003c/li\u003e\n\u003cli\u003e其他工作：同时采用上述3个机制，需合理控制发布端解码速率、订阅端回放速率，在实现负载均衡的同事，避免logic-wal堆积。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-设计分析\"\u003e2 设计分析\u003c/h1\u003e\n\u003ch2 id=\"21-必要性\"\u003e2.1 必要性\u003c/h2\u003e\n\u003cp\u003e根据postgrsql-16的性能测试结果，流式复制和并行回放机制，可达到70Mb/s的复制速度。\u003c/p\u003e\n\u003ch3 id=\"一测试场景\"\u003e一、测试场景\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e测试机器：\n\u003cul\u003e\n\u003cli\u003eIP：172.16.103.90\u003c/li\u003e\n\u003cli\u003e硬件：CPU：鲲鹏920-ARM-128核。缓存L1-L2-L3：8M/64M/256M。内存：760G。磁盘：NVME\u003c/li\u003e\n\u003cli\u003e系统：openEuler\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003etpcc测试场景（为了快速测试，不太标准）\n\u003cul\u003e\n\u003cli\u003e数据量：100 warhouse\u003c/li\u003e\n\u003cli\u003e并发：400\u003c/li\u003e\n\u003cli\u003e执行时间：1 min\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e逻辑复制配置：\n\u003cul\u003e\n\u003cli\u003e部署：发布端、订阅端在同一台机器（找不到2台性能机）\u003c/li\u003e\n\u003cli\u003e订阅：创建1个publiction，涵盖所有table\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"二测试数据\"\u003e二、测试数据\u003c/h2\u003e\n\u003cp\u003e由于机器、时间等限制，测试未严格控制变量，但是，和准确结果应该有80%以上符合度。\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e版本\u003c/th\u003e\n          \u003cth\u003e配置\u003c/th\u003e\n          \u003cth\u003etpmc\u003c/th\u003e\n          \u003cth\u003e发布端-wal写入速度\u003c/th\u003e\n          \u003cth\u003e逻辑复制速度（峰值）\u003c/th\u003e\n          \u003cth\u003e逻辑复制速度（平均值）\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003epostgrsql-14\u003c/td\u003e\n          \u003ctd\u003e串行解码、非流式复制、串行回放\u003c/td\u003e\n          \u003ctd\u003e约65w\u003c/td\u003e\n          \u003ctd\u003e207 Mb/s\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003e16 Mb/s\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003epostgresql-16\u003c/td\u003e\n          \u003ctd\u003e串行解码、流式复制、串行回放\u003c/td\u003e\n          \u003ctd\u003e约65w\u003c/td\u003e\n          \u003ctd\u003e212 Mb/s\u003c/td\u003e\n          \u003ctd\u003e117 Mb/s\u003c/td\u003e\n          \u003ctd\u003e55 Mb/s\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003epostgresql-16\u003c/td\u003e\n          \u003ctd\u003e串行解码、流式复制、并行回放(4)\u003c/td\u003e\n          \u003ctd\u003e约65w\u003c/td\u003e\n          \u003ctd\u003e197 Mb/s\u003c/td\u003e\n          \u003ctd\u003e113 Mb/s\u003c/td\u003e\n          \u003ctd\u003e71 Mb/s\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cblockquote\u003e\n\u003cul\u003e\n\u003cli\u003e测试：贾旭辉\u003c/li\u003e\n\u003cli\u003e详细数据和结论见wiki：\u003ca href=\"https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007526\"\u003ehttps://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007526\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\u003c/blockquote\u003e\n\u003cul\u003e\n\u003cli\u003e尝试修改源码，让订阅端只接受日志，不apply，确定发布端解码和发送的瓶颈，但是，测试结果有点奇怪，有空再继续。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"22-可行性\"\u003e2.2 可行性\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e并行解码：openGauss已引入\u003c/li\u003e\n\u003cli\u003e流式复制：postgreql-16版本已成熟\u003c/li\u003e\n\u003cli\u003e并行回放：postgreql-16版本已成熟\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"23-潜在风险\"\u003e2.3 潜在风险\u003c/h2\u003e\n\u003ch3 id=\"一数据有一致性\"\u003e一、数据有一致性\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e写写冲突\u003c/p\u003e","title":"PostgreSQL 3-13 逻辑复制性能优化"},{"content":"1 逻辑复制背景 1.1 逻辑复制场景 在使用数据库时，为提高整个系统的可靠性，或实现不同部门数据同步等场景，很多客户的部署模型存在：一主多备、异构数据库等特点，在保证性能的前提下，常见部署模型如下：\n+-------------+ sql +---------------------+ wal +--------------------+ | application | --------\u0026gt; | postgresql (master) | -------\u0026gt; | postgresql (slave) | +-------------+ +---------------------+ +--------------------+ | | | decoded-wal +--------------------+ +---------------------\u0026gt; | mysql, oracle, .. | +--------------------+ 1.2 逻辑复制功能 1.3 逻辑复制基础 首先，需自行了解一些存储的基本知识，包括事务特性、mvcc机制，表的物理存储格式：filenode、page、tuple等。\n此处，以一个例子，介绍什么wal日志的特点。需了解一些\n应用执行事务\n假设同一时间，有2个事务，事务id分别为10和11。\n时间 应用1 应用2 0 CREATE TABLE t1 (c1 INT,c2 INT) - 1 CREATE TABLE t2 (c1 INT,c2 INT) - 2 BEGIN (xid=10) - 3 INSERT INTO t1 VALUES(10, 1) - 4 - BEGIN (xid=11) 5 - INSERT INTO t1 VALUES (11, 1) 6 INSERT INTO t2 VALUES (10, 2) - 7 COMMIT 8 - DELETE FROM t1 WHERE c1 = 10 9 - INSERT INTO t2 VALUES (11, 2) 10 - COMMIT 内核产生wal日志\n所有表的wal日志，按生成wal的顺序，组织在一起。上述示例中，产生的wal如下：（此处仅列举关键信息）\n顺序 type xid filenode offset data 1 insert 10 (t1) xx,xx ‘10,1’ 2 insert 11 (t1) xx,xx ‘11,1’ 3 insert 10 (t2) xx,xx ‘10,2’ 4 commit 10 - - - 5 delete 11 (t1) xx,xx - 6 insert 11 (t2) xx,xx ‘11,2’ 7 commit 11 - - - 1.4 物理复制区别 一、物理复制 在复制模型中，分为主节点、备节点。\n主节点 备节点：与主节点相比，数据库版本相同，表的数量相同，表的的物理信息相同，表中数据相同。回放wal日志时，可直接使用wal日志中的[filenode, offset]等信息。 用户执行SQL：INSERT INTO t1 VALUES(1, 'data1')时，wal的内容大概如下：\n[0, [1700, 1800], [8, 3], [10, \u0026#39;1 data1\u0026#39;]] 解释： - 0 : insert - 1700 : directory name (database oid) - 1800 : file name (filenode) - 8 : page index number - 3 : tuple index number - 10 : transcation id 二、逻辑复制 在复制模型中，分为发布端、订阅端。\n发布端： 订阅端： 异构订阅端：数据库类型不同 同源订阅端：数据库类型相同，但是，以下内容可能存在差异： 数据库版本 表的数量 表的物理信息 表中数据 与物理复制相比，逻辑复制存在一些差异，包括：\n发布端：生成wal时，wal中信息更多一些 发布端：读取wal时，解码wal，生成decoded-wal 发布端：发送wal时，不按wal顺序发送decoded-wal，而是根据事务顺序，一次发送由同一事务生成的多条wal 订阅端：回放wal时，根据decoded-wal，获取操作、数据等信息，调用heapam接口，例如heap_insert, heap_delete等，重放decoded-wal，生成新的wal 2 使用逻辑复制 2.1 发布端 配置\n# pg14 echo \u0026#34;wal_level=logical\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf echo \u0026#34;max_replication_slots=4\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf echo \u0026#34;max_wal_senders=4\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf echo \u0026#34;max_worker_processes=8\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf echo \u0026#34;max_logical_replication_workers=4\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf echo \u0026#34;listen_addresses=\u0026#39;*\u0026#39;\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf sed -i \u0026#39;1i host all all 0.0.0.0/0 md5\\n\u0026#39; $PG_HOME/data/pg_hba.conf # host all all 0.0.0.0/0 md5 psql -d postgres -c \u0026#34;SELECT name,setting FROM pg_settings WHERE name in (\u0026#39;wal_level\u0026#39;, \u0026#39;max_replication_slots\u0026#39;, \u0026#39;max_wal_senders\u0026#39;, \u0026#39;max_worker_processes\u0026#39;, \u0026#39;max_logical_replication_workers\u0026#39;)\u0026#34; 创建基表\nCREATE DATABASE pubdb; \\c pubdb CREATE TABLE pt1(c1 INT,c2 TEXT); CREATE TABLE pt2(c1 INT, c2 TEXT); INSERT INTO pt1 VALUES (1,\u0026#39;data1-1\u0026#39;), (2,\u0026#39;data1-2\u0026#39;); INSERT INTO pt1 VALUES (1,\u0026#39;data2-1\u0026#39;), (2,\u0026#39;data2-2\u0026#39;); 创建发布信息\nCREATE PUBLICATION pub1 FOR TABLE pt1,pt2; -- SELECT * FROM pg_publication; -- SELECT * FROM pg_publication_rel; -- 设置发布状态 SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); -- SELECT * FROM pg_replication_slots; -- SELECT * FROM pg_stat_replication_slots; -- 检查数据 -- SELECT * FROM pg_logical_slot_peek_changes(\u0026#39;pslot1\u0026#39;, NULL, NULL); -- 删除slot -- SELECT pg_drop_replication_slot(\u0026#39;pslot1\u0026#39;); 创建发布用户\n-- 订阅端通过pu1用户来连接发布端，以接收数据 CREATE USER pu1 REPLICATION PASSWORD \u0026#39;pu1.12345\u0026#39;; GRANT CONNECT ON DATABASE pubdb TO pu1; GRANT USAGE ON SCHEMA public TO pu1; GRANT ALL ON pt1,pt2 TO pu1; 验证\npsql -h 172.16.100.134 -p 5432 -d pubdb -U pu1 -W pu1.12345 其他参考语法\nALTER SUBSCRIPTION sub1 DISABLE; ALTER SUBSCRIPTION sub1 ENABLE; ALTER PUBlication pub1 ADD TABLE new_tbl; 2.2 订阅端 配置\n作为客户端访问发布端，无需配置任何guc参数\n# 如果发布端、订阅端在同一机器，确保二者端口不同 echo \u0026#34;port=5433\u0026#34; \u0026gt;\u0026gt; $PG_HOME/datas/postgresql.conf 创建基表，与发布端表定义一致\n-- psql -p 5433 -d postgres CREATE DATABASE subdb; \\c subdb CREATE TABLE pt1(c1 INT,c2 TEXT); CREATE TABLE pt2(c1 INT, c2 TEXT); 创建订阅信息\nCREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=5432 dbname=pubdb user=pu1 password=pu1.12345\u0026#39; PUBLICATION pub1 WITH (create_slot = false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = true); -- SELECT * FROM pg_subscription; -- SELECT * FROM pg_subscription_rel; -- SELECT * FROM pg_stat_subscription; 查看表数据\nSELECT * FROM pt1; -- 向发布端表写数据，订阅端也会收到数据 其他操作\n-- 暂停接受数据 ALTER SUBSCRIPTION sub1 DISABLE; 2.3 订阅端并行apply # pg17 echo \u0026#34;max_parallel_apply_workers_per_subscription=4\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf ALTER SUBSCRIPTION sub1 SET (parallel_apply = true); 2.3 计算逻辑复制速度 计算xlog生成速度\n-- 测试前，获取xlog写入位置 DROP TABLE IF EXISTS tlsn; SELECT pg_current_wal_lsn() AS lsn1 INTO tlsn; -- 测试后，获取当前xlog写入位置，并计算xlog差值 SELECT pg_wal_lsn_diff(pg_current_wal_lsn(), (SELECT lsn1 FROM tlsn)); -- 参考：转换为10进制 -- SELECT (\u0026#39;x\u0026#39; || lpad(replace(pg_current_wal_lsn()::text, \u0026#39;/\u0026#39;, \u0026#39;\u0026#39;), 16, \u0026#39;0\u0026#39;))::bit(64)::bigint AS decimal_lsn; 插入数据\ntpcc写入\nALTER SYSTEM SET password_encryption=\u0026#39;md5\u0026#39;; SELECT pg_reload_conf(); 3 逻辑复制原理 3.1 进程类型 以下是逻辑复制的进程模型与工作流程：\n# pg-17 [发布端] [订阅端] postmaster postgres wal-writer wal-sender wal-file postmaster apply-launch apply-worker +-------------------+------------------------------+------------+---------------------------+---+---------------------------+---------------------------+----------------------+ | 1 receive connect | | | | | | | | 2 fork postgres -\u0026gt;| | | | | | | | | 3 receive sql | | | | | | | | delete .. t1 .. c1=10 | | | | | | | | 4 scan tuple from t1 | | | | | | | | 5 get tuple pointer | | | | | | | | 6 mark tuple deleted | | | | | | | | 7 generate wal | | | | | | | | type=delete,xid=11 | | | | | | | | filenode=1700,offset=8-3 | | | | | | | | data=\u0026#39;10\u0026#39;,column=1 | | | | | | | | 8 copy wal to wal-buffer ---\u0026gt;| | | | | | | | 9 write wal---------------------------\u0026gt;| | | | | | | | 10 startp | | | | | | 11 startup apply-launch -\u0026gt;| | | | | | | 12 read suscription | | | | | | 13 calucate worker num | | | | | \u0026lt;-------------------------| 14 register worker info | | | | | 15 read bgworker info | | | | | 16 startup apply-worker -----------------------------\u0026gt;| | \u0026lt;-------------------------------------------------------------+---------------------------+-----------------------------------------------------------| 17 ask publliction | 18 receive connect | | | | 19 fork postgres as wal-sender ------------------------------\u0026gt;| | | | 20 read wal \u0026lt;-------------| | | 21 decod to decode-wal | | 22 send decoded-wal -----------------------------------------------------------------\u0026gt;| | 23 receive decoded-wal | 24 apply decoded-wal | (if is postgresql) | 25 scan tuple from t1 | 26 get tuple pointer | 27 mark tuple deleted | 28 generate wal 3.2 复制流程 application postgres wal-file wal-sender +-----------------------+---------------------------+-----------------------+ 1 begin (xid=10) ----\u0026gt; | 2 insert t1 (10,1) ---\u0026gt; | | 3 write wal | [10, insert \u0026#39;10,1\u0026#39;] --\u0026gt; | | | | \u0026lt;- | 4 read wal | | [10, insert \u0026#39;10,1\u0026#39;] | | 5 decode wal | 6 put to list (xid=10) 3 begin (xid=11) ------\u0026gt;| （待继续补充） 4 逻辑复制源码 4.2 关键设计 一、流复制 # 发布端 @ pg-17 WalSndLoop for (;;) # 持续读取、解码、发送 xlog XLogSendLogical pq_sendbyte(\u0026amp;output_message, \u0026#39;w\u0026#39;); XLogReadRecord # 读取1条record，放入logical_decoding_ctx ReadPageInternal DecodeXLogRecord LogicalDecodingProcessRecord # 开始解码 ReorderBufferAssignChild rmgr.rm_decode # hook: RmgrTable [heap_decode, xact_decode] heap_decode ReorderBufferProcessXid ReorderBufferTXNByXid # 为事务申请链表 if XLOG_HEAP_INSERT: DecodeInsert ReorderBufferGetChange # 申请一个node DecodeXLogTuple ReorderBufferQueueChange # 将node放入list ReorderBufferTXNByXid dlist_push_tail ReorderBufferProcessPartialChange # 流复制 ReorderBufferStreamTXN ReorderBufferProcessTXN # 发送数据 ReorderBufferIterTXNNext stream_start stream_start_cb_wrapper stream_start_cb pgoutput_stream_start logicalrep_write_stream_start \u0026#39;LOGICAL_REP_MSG_STREAM_START xid is_first_sedment\u0026#39; OutputPluginWrite write WalSndWriteData pq_flush_if_writable ReorderBufferApplyChange stream_change stream_change_cb_wrapper stream_change_cb pgoutput_change OutputPluginPrepareWrite # 数据头 prepare_write WalSndPrepareWrite pq_sendbyte(ctx-\u0026gt;out, \u0026#39;w\u0026#39;) pgoutput_send_begin # 消息头 + 消息 logicalrep_write_begin \u0026#39;LOGICAL_REP_MSG_BEGIN final_lsn commit_time xid\u0026#39; if REORDER_BUFFER_CHANGE_INSERT: logicalrep_write_insert \u0026#39;LOGICAL_REP_MSG_INSERT xid relid N nattr len value\u0026#39; if REORDER_BUFFER_CHANGE_DELETE logicalrep_write_delete OutputPluginWrite (WalSndWriteDataHelper) write ReorderBufferIterTXNFinish stream_stop stream_stop_cb_wrapper stream_stop_cb pgoutput_stream_stop logicalrep_write_stream_stop \u0026#39;LOGICAL_REP_MSG_STREAM_STOP\u0026#39; OutputPluginWrite write ReorderBufferSaveTXNSnapshot UpdateDecodingStats ReorderBufferCheckMemoryLimit elif XLOG_HEAP_DELETE: DecodeDelete ReorderBufferGetChange DecodeXLogTuple ReorderBufferQueueChange xact_decode if XLOG_XACT_COMMIT: DecodeCommit SnapBuildCommitTxn ReorderBufferCommit ReorderBufferTXNByXid ReorderBufferReplay ReorderBufferStreamCommit ReorderBufferStreamTXN stream_commit pgoutput_stream_commit logicalrep_write_stream_commit OutputPluginWrite UpdateDecodingStats # 订阅端 @ pg-17 ApplyWorkerMain SetupApplyOrSyncWorker GetSubscription run_apply_worker walrcv_connect walrcv_identify_system walrcv_startstreaming start_apply LogicalRepApplyLoop for (;;) walrcv_receive for (;;) if \u0026#39;w\u0026#39; apply_dispatch if LOGICAL_REP_MSG_STREAM_START: \u0026#39;S\u0026#39; apply_handle_stream_start logicalrep_read_stream_start pa_allocate_worker get_transaction_apply_action if TRANS_LEADER_SEND_TO_PARALLEL: pa_send_data elif LOGICAL_REP_MSG_INSERT: \u0026#39;I\u0026#39; apply_handle_insert handle_streamed_transaction get_transaction_apply_action pa_find_worker if TRANS_LEADER_SEND_TO_PARALLEL: pa_send_data shm_mq_send elif LOGICAL_REP_MSG_STREAM_STOP: \u0026#39;E\u0026#39; apply_handle_stream_stop get_transaction_apply_action pa_find_worker elif LOGICAL_REP_MSG_COMMIT: \u0026#39;C\u0026#39; apply_handle_commit walrcv_receive walrcv_endstreaming # 订阅端 parallel-worker pa_allocate_worker pa_launch_parallel_worker ParallelApplyWorkerMain logicalrep_worker_attach LogicalParallelApplyLoop for (;;) shm_mq_receive apply_dispatch if LOGICAL_REP_MSG_INSERT: begin_replication_step logicalrep_read_insert logicalrep_rel_open apply_handle_insert_internal 4.1 完整流程 # 前置 ReplicationSlotCreate # Postmaster进程 StartupXLOG StartupReplicationSlots RestoreSlotFromDisk # 读取slot文件 OpenTransientFile memcpy(ReplicationSlotCtl) # postgres进程 INSERT heap_insert XLogInsert XLogRecordAssemble XLogInsertRecord CopyXLogRecordTowal # 订阅端 apply-worker @pg.14 # postmaster进程 PostmasterMain checkDatadir checkControlFile ApplyLauncherRegister RegisterBackgroundWorker(\u0026#39;ApplyLauncherMain\u0026#39;) slist_push_head # 加入全局list BackgroundWorkerList reset_shared SysLogger_Start maybe_start_bgworkers do_start_bgworker # 暂时不启动 ServerLoop for ;; ConnCreate BackendStartup BackendRun PostgresMain maybe_start_bgworkers do_start_bgworker InitPostmasterChild fork # fork 新进程 StartBackgroundWorker LookupBackgroundWorkerFunction # 获取回调函数 ApplyLauncherMain entrypt -\u0026gt; ApplyLauncherMain # 新进程主函数：ApplyLauncherMain # apply-launch进程 ApplyLauncherMain for (;;) get_subscription_list # 从系统表中，获取所有subscription table_beginscan_catalog(\u0026#39;pg_subscription\u0026#39;) heap_getnext foreach logicalrep_worker_find logicalrep_worker_launch RegisterDynamicBackgroundWorker(\u0026#39;ApplyWorkerMain\u0026#39;) # 加入全局BackgroundWorkerData，postmaster进程在ServerLoop中检查该结构体 WaitForReplicationWorkerAttach # 等待postmaster进程fork apply-worker进程 # fork成功，自动调用 entrypt -\u0026gt; ApplyWorkerMain # 订阅端 CREATE SUBSCRIPTION CreateSubscription CatalogTupleInsert(\u0026#39;pg_subscription\u0026#39;) replorigin_create CatalogTupleInsert(\u0026#39;pg_replication_origin\u0026#39;) check_publications # 与发布端通信，检查publication状态 check_publications_origin fetch_table_list # 读取发布端表基本信息 AddSubscriptionRelState CatalogTupleInsert(\u0026#39;pg_subscription\u0026#39;) # 系统表srsubstate= (copy_data ? \u0026#39;i\u0026#39; : \u0026#39;r\u0026#39;) ApplyLauncherWakeupAtCommit # 启动apply-worker process_syncing_tables process_syncing_tables_for_apply process_syncing_tables_for_apply wait_for_relation_state_change GetSubscriptionRelState # 获取系统表 srsubstate logicalrep_worker_find # 查找与等待 sync 进程 apply-launch 只启动apply-worker类型进程 # apply-worker进程 ApplyWorkerMain GetSubscription SearchSysCache1(\u0026#39;pg_subscription\u0026#39;) if am_tablesync_worker LogicalRepSyncTableStart # 追赶？ GetSubscriptionRelState SearchSysCache1(\u0026#39;pg_subscription\u0026#39; and \u0026#39;pg_subscription_rel\u0026#39;) LogicalRepApplyLoop for (;;) walrcv_receive # 接收发布端数据 for (;;) pq_getmsgbyte if \u0026#39;w\u0026#39;: apply_dispatch # 回放数据 pq_getmsgbyte if LOGICAL_REP_MSG_BEGIN: apply_handle_begin if LOGICAL_REP_MSG_COMMIT: apply_handle_commit if LOGICAL_REP_MSG_INSERT: apply_handle_insert logicalrep_read_insert logicalrep_rel_open create_edata_for_relation slot_store_data apply_handle_insert_internal ExecOpenIndices ExecSimpleRelationInsert simple_table_tuple_insert table_tuple_insert hook: tuple_insert heapam_tuple_insert heap_insert heap_prepare_insert RelationGetBufferForTuple RelationPutHeapTuple XLogInsert ExecInsertIndexTuples ExecCloseIndices elif \u0026#39;k\u0026#39;: send_feedback walrcv_receive send_feedback maybe_reread_subscription walrcv_endstreaming # 并行apply apply_dispatch(LOGICAL_REP_MSG_STREAM_START) apply_handle_stream_start pa_allocate_worker pa_launch_parallel_worker logicalrep_worker_launch if TRANS_LEADER_SEND_TO_PARALLEL pa_send_data shm_mq_send # 发布端（由订阅端触发） @pg.14 PostmasterMain ServerLoop BackendStartup BackendInitialize # 处理连接参数 ProcessStartupPacket if conn is \u0026#39;replication\u0026#39;: am_walsender = true BackendRun # 处理SQL语句 PostgresMain for (;;) ReadCommand if am_walsender: if exec_replication_command StartLogicalReplication CreateDecodingContext # 创建全局变量 logical_decoding_ctx，包括reader和re-order StartupDecodingContext hook: reorder.begin = begin_cb_wrapper hook: reorder.apply_change = change_cb_wrapper hook: write = WalSndWriteData WalSndLoop for (;;) # 持续读取、解码、发送 xlog XLogSendLogical XLogReadRecord # 读取1条record，放入logical_decoding_ctx ReadPageInternal DecodeXLogRecord LogicalDecodingProcessRecord # 开始解码 DecodeHeapOp DecodeInsert XLogRecGetBlockData DecodeXLogTuple ReorderBufferQueueChange ReorderBufferTXNByXid # 根据xid，获取buffer dlist_push_tail DecodeXactOp DecodeCommit ReorderBufferCommit ReorderBufferTXNByXid ReorderBufferReplay ReorderBufferProcessTXN while ReorderBufferIterTXNNext # 处理 INSERT ReorderBufferApplyChange hook: apply_change change_cb_wrapper hook: change_cb pgoutput_change # 暂存，不发送 logicalrep_write_insert logicalrep_write_tuple OutputPluginWrite hook: write WalSndWriteData pq_flush_if_writable socket_flush_if_writable .. send # 系统调用 send hook: commit # 处理 COMMIT commit_cb_wrapper hook: commit_cb pgoutput_commit_txn # 一起发送 logicalrep_write_commit OutputPluginWrite .. send else: exec_simple_query else: exec_simple_query # 发布端：流式复制 ReorderBufferReplay ReorderBufferStreamCommit ReorderBufferStreamTXN ReorderBufferProcessTXN stream_start_cb_wrapper hook: stream_start_cb _PG_output_plugin_init pgoutput_stream_start logicalrep_write_stream_start pq_sendbyte(LOGICAL_REP_MSG_STREAM_START) 4.3 并行解码 # @reader # read wal LogicalReadRecordMain while (true) XLogReadRecord # read record ParseProcessRecord # parse record ParseXactOp # parse xact if \u0026#39;XLOG_XACT_COMMIT\u0026#39;: ParseCommitXlog ParallelReorderBufferGetChange # alloc a change-item PutChangeQueue # send change-item ParseHeapOp # parse heap if \u0026#39;XLOG_HEAP_INSERT\u0026#39;: ParseInsertXlog ParallelReorderBufferGetChange # alloc a change-item DecodeXLogTuple # fill change-item (wal -\u0026gt; change-itme) PutChangeQueue # send change-item LogicalQueuePut(decoder[x]-\u0026gt;changeQueue) elif \u0026#39;XLOG_HEAP_DELETE\u0026#39;: ParseDeleteXlog # @decoder # decode change ParallelDecodeWorkerMain while (true) LogicalQueueTop # recv change-item ParallelDecodeChange # decode change-item if \u0026#39;PARALLEL_REORDER_BUFFER_CHANGE_COMMIT\u0026#39;: ParallelDecodeCommitOrAbort GetLogicalLog if \u0026#39;PARALLEL_REORDER_BUFFER_CHANGE_INSERT\u0026#39;: getIUDLogicalLog # make log (change-item -\u0026gt; log) LogicalQueuePut(decoder-\u0026gt;LogicalLogQueue) # put log to log-queue LogicalQueuePop # pop change-item, it\u0026#39;s finished # @sender # send log WalSndLoop for (;;) XLogSendParallelLogical for (;; decoder.id++) # get decoder one by one LogicalQueueTop # recv log from current decoder LogicalLogHandle # if \u0026#39;LOGICAL_LOG_DML\u0026#39;: ParallelReorderBufferQueueChange ParallelReorderBufferTXNByXid # find txn-list from txn-pool dlist_push_tail # push log to txn-list ParallelReorderBufferUpdateMemory # check memory elif \u0026#39;LOGICAL_LOG_COMMIT\u0026#39;: LogicalLogHandleAbortOrCommit ParallelReorderBufferTXNByXid # find txn-list from txn-pool ParallelReorderBufferCommit # send all log in txn-list ParallelOutputBegin ParallelHandleBatch while (ParallelReorderBufferIterTXNNext) # get log one by one ParallelOutputBegin ParallelHandleBatch ParallelOutputCommit ParallelReorderBufferCleanupTXN # clean txn-list LogicalQueuePop # remove log 参考资料 逻辑复制架构：https://www.cnblogs.com/wy123/p/18946661 GaussDB并行逻辑解码：https://developer.huawei.com/consumer/cn/forum/topic/0201165508224221138 pg16并行回放：https://www.webkt.com/article/7715 openGauss并行解码测试：https://www.cnblogs.com/jerrywang1983/articles/18375212 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/3-13-publication/","summary":"\u003ch1 id=\"1-逻辑复制背景\"\u003e1 逻辑复制背景\u003c/h1\u003e\n\u003ch2 id=\"11-逻辑复制场景\"\u003e1.1 逻辑复制场景\u003c/h2\u003e\n\u003cp\u003e在使用数据库时，为提高整个系统的可靠性，或实现不同部门数据同步等场景，很多客户的部署模型存在：一主多备、异构数据库等特点，在保证性能的前提下，常见部署模型如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e+-------------+    sql    +---------------------+    wal    +--------------------+\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e application \u003cspan class=\"p\"\u003e|\u003c/span\u003e --------\u0026gt; \u003cspan class=\"p\"\u003e|\u003c/span\u003e postgresql \u003cspan class=\"o\"\u003e(\u003c/span\u003emaster\u003cspan class=\"o\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e  -------\u0026gt; \u003cspan class=\"p\"\u003e|\u003c/span\u003e postgresql \u003cspan class=\"o\"\u003e(\u003c/span\u003eslave\u003cspan class=\"o\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e+-------------+           +---------------------+           +--------------------+\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e   decoded-wal         +--------------------+\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    +---------------------\u0026gt; \u003cspan class=\"p\"\u003e|\u003c/span\u003e mysql, oracle, ..  \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                            +--------------------+\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"12-逻辑复制功能\"\u003e1.2 逻辑复制功能\u003c/h2\u003e\n\u003ch2 id=\"13-逻辑复制基础\"\u003e1.3 逻辑复制基础\u003c/h2\u003e\n\u003cp\u003e首先，需自行了解一些存储的基本知识，包括事务特性、mvcc机制，表的物理存储格式：filenode、page、tuple等。\u003cbr\u003e\n此处，以一个例子，介绍什么wal日志的特点。需了解一些\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e应用执行事务\u003cbr\u003e\n假设同一时间，有2个事务，事务id分别为10和11。\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e时间\u003c/th\u003e\n          \u003cth\u003e应用1\u003c/th\u003e\n          \u003cth\u003e应用2\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e0\u003c/td\u003e\n          \u003ctd\u003eCREATE TABLE t1 (c1 INT,c2 INT)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e1\u003c/td\u003e\n          \u003ctd\u003eCREATE TABLE t2 (c1 INT,c2 INT)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e2\u003c/td\u003e\n          \u003ctd\u003eBEGIN (xid=10)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e3\u003c/td\u003e\n          \u003ctd\u003eINSERT INTO t1 VALUES(10, 1)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e4\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eBEGIN (xid=11)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e5\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eINSERT INTO t1 VALUES (11, 1)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e6\u003c/td\u003e\n          \u003ctd\u003eINSERT INTO t2 VALUES (10, 2)\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e7\u003c/td\u003e\n          \u003ctd\u003eCOMMIT\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eDELETE FROM t1 WHERE c1 = 10\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e9\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eINSERT INTO t2 VALUES (11, 2)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e10\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eCOMMIT\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e内核产生wal日志\u003cbr\u003e\n所有表的wal日志，按生成wal的顺序，组织在一起。上述示例中，产生的wal如下：（此处仅列举关键信息）\u003c/p\u003e","title":"PostgreSQL 3-13 Publication"},{"content":"1 物理复制基本原理 1.1 使用场景 介绍为什么需要物理复制\n1.2 相关原理 介绍什么是wal，wal是用来干嘛的\n1.3 实现思路 介绍如何基于wal，实现物理复制，并解决1.1中的问题\n2 物理复制使用方式 2.1 使用物理复制 3 物理复制工作流程 3.1 整体架构 包括Postgres生成wal，walwriter存储wal，walsender发送wal，walreceive接收wal，startup重放wal，checkpoint/bgwriter等。\n3.2 工作流程 参考2.1，梳理完整的工作流程，从主机执行SQL语句开始，到最终备机达到同样效果\n4 物流复制实现源码 参考2.1，介绍每一阶段的关键原理，另外，包括wal日志格式等\n你好，我要基本当前目录下的代码，生成一份流复制的skill，所以，接下来的对话，都和这件事有关。\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/3-14-physical-replication/","summary":"\u003ch1 id=\"1-物理复制基本原理\"\u003e1 物理复制基本原理\u003c/h1\u003e\n\u003ch2 id=\"11-使用场景\"\u003e1.1 使用场景\u003c/h2\u003e\n\u003cp\u003e介绍为什么需要物理复制\u003c/p\u003e\n\u003ch2 id=\"12-相关原理\"\u003e1.2 相关原理\u003c/h2\u003e\n\u003cp\u003e介绍什么是wal，wal是用来干嘛的\u003c/p\u003e\n\u003ch2 id=\"13-实现思路\"\u003e1.3 实现思路\u003c/h2\u003e\n\u003cp\u003e介绍如何基于wal，实现物理复制，并解决1.1中的问题\u003c/p\u003e\n\u003ch1 id=\"2-物理复制使用方式\"\u003e2 物理复制使用方式\u003c/h1\u003e\n\u003ch2 id=\"21-使用物理复制\"\u003e2.1 使用物理复制\u003c/h2\u003e\n\u003ch1 id=\"3-物理复制工作流程\"\u003e3 物理复制工作流程\u003c/h1\u003e\n\u003ch2 id=\"31-整体架构\"\u003e3.1 整体架构\u003c/h2\u003e\n\u003cp\u003e包括Postgres生成wal，walwriter存储wal，walsender发送wal，walreceive接收wal，startup重放wal，checkpoint/bgwriter等。\u003c/p\u003e\n\u003ch2 id=\"32-工作流程\"\u003e3.2 工作流程\u003c/h2\u003e\n\u003cp\u003e参考2.1，梳理完整的工作流程，从主机执行SQL语句开始，到最终备机达到同样效果\u003c/p\u003e\n\u003ch1 id=\"4-物流复制实现源码\"\u003e4 物流复制实现源码\u003c/h1\u003e\n\u003cp\u003e参考2.1，介绍每一阶段的关键原理，另外，包括wal日志格式等\u003c/p\u003e\n\u003cp\u003e你好，我要基本当前目录下的代码，生成一份流复制的skill，所以，接下来的对话，都和这件事有关。\u003c/p\u003e","title":"PostgreSQL 3-14 物理复制"},{"content":"深信服支持pg scram-sha256需求 需求目标 本需求的根本目标时，当vastbase server要求使用sha256算法进行身份认证时，postgresql client能与vastbase server建立连接。\n该需求目前仅合入深信服分支\n需求分析 身份认证的详细流程有点复杂，此处简要概述为2个阶段：\n标识：新建用户时，server计算并存储密码哈希值 鉴别：用户登录时，server向client发送计算密码哈希值的关键信息，client计算并向server发送密码哈希值，server校验其是否符合存储的值 vastbase和postgresql对比，server计算密码哈希值的算法不同，server向client发送关键信息也不同。为解决pg-client能够连接vb-server的问题，需解决问题如下：\nvb-server计算并存储与pg-server一致的密码哈希值 vb-server向pg-client发送密码哈希值关键信息时，需要pg-server一致 postgreql的标识与鉴别机制，符合标准RFC-5802，涉及的算法与协议，本文统一称为scram-sha256。vastbase涉及的算法与协议，本文统一称为sha256。\n需求实现 密码存储：新建用户时，修改存储用户密码的值\n修改前：guc参数password_encrypt_type，取值1时，vb-server存储密码的[sha256, md5]值；取值为2时，存储密码的[sha256]值\nSELECT rolpassword FORM pgauthid; -- 示例：长度为209 rolpassword -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- sha256af99537f242c661a88acea99ac626a2cf8fe196ac5671db6f02ed6818b420cf84e7ada61d66602c6eb5bf4ced40911d3f51865959784ebc3b0d385ca4c08f3398f05e16268fe9acc95a2d662bf5033b15d53abd1f835c1a3f1e96343a5cbf800ecdfecefade 修改后：guc参数password_encrypt_type，取值1时，vb-server存储密码的[sha256, md5, scram-sha256]值；取值为2时，存储密码的[sha256, scram-sha256]值\nSELECT rolpassword FORM pgauthid; -- 示例：长度342 (新增长度：133) rolpassword -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- sha256af99537f242c661a88acea99ac626a2cf8fe196ac5671db6f02ed6818b420cf84e7ada61d66602c6eb5bf4ced40911d3f51865959784ebc3b0d385ca4c08f3398f05e16268fe9acc95a2d662bf5033b15d53abd1f835c1a3f1e963SCRAM-SHA-256$4096:sp5V1hrLKzLsS4HtQgqTuA==$QO/UVdrXxIypzBEGqEuIWe96A80elghFQs25ZbdPsLg=:J4lPXmXPANtTMOkaHokMjmM19K1Di7fU6WRWuZ5VmS0= 认证协议：用户登录时，修改向客户端发送的密码哈希值关键信息\n修改前：\n# 身份认证协议 1. client \u0026lt;-\u0026gt; server : tcp connect 2. client --\u0026gt; server : send [消息类型:0, 协议版本:3.51，连接参数:user_name, databse, ...] 3. server --\u0026gt; client : send [消息类型:R, 哈希算法:10, 系统表存储的密码的算法:2, 计算密码哈希关键信息：salt,token,iteration] 4. client \u0026lt;-\u0026gt; server : # 省略3次交互 修改后：\n# 身份认证协议 1. client \u0026lt;-\u0026gt; server : tcp connect 2. client --\u0026gt; server : send [消息类型:0, 协议版本:3.51，连接参数:user_name, databse, ...] # postgreql的client，发送的协议版本是3.0，旧版和最新版都是如此 3. server --\u0026gt; client : if 协议版本 \u0026lt; 3.51: send [消息类型:R, 哈希算法:10, 算法名称:\u0026#34;SCRAM-SHA256\u0026#34;] # scram-sha256协议的内容 4. client \u0026lt;-\u0026gt; server # 省略3次交互，省略的交互中，postgresql与vastbase差异也很大 if 协议版本 \u0026gt;= 3.51: # opengauss的机制：opengauss的client，都会设置协议版本大于3.50 send [消息类型:R, 哈希算法:10, 系统表存储的密码的算法:2, 计算密码哈希关键信息：salt,token,iteration] 4. client \u0026lt;-\u0026gt; server : # 省略3次交互 客户使用 设置密码加密类型\nvb_guc set -D $数据目录 -c \u0026#34;password_encryption_type=1\u0026#34; # 取值为1和2都行 修改已有用户的密码（无需使用postgresql client的无需修改）\nALTER USER u1 PASSWORD \u0026#39;old_password\u0026#39;; 配置pg_hba.conf的认证方式为sha256\nvb_guc set -D $数据目录 -h \u0026#34;host all all 0.0.0.0/0 sha256\u0026#34; # 第1列host表示是远程连接，如果是local表示本机连接。如果改成local，初始用户也要输密码。 使用postgresql client与数据建立连接，可连接成功\n测试 gs_guc reload -D $GAUSSHOME/data -c \u0026#34;password_encryption_type=0\u0026#34; gsql -d postgres -c \u0026#34;CREATE USER u0 PASSWORD \u0026#39;u0.password\u0026#39;\u0026#34; gs_guc reload -D $GAUSSHOME/data -c \u0026#34;password_encryption_type=1\u0026#34; gsql -d postgres -c \u0026#34;CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;\u0026#34; gs_guc reload -D $GAUSSHOME/data -c \u0026#34;password_encryption_type=2\u0026#34; gsql -d postgres -c \u0026#34;CREATE USER u2 PASSWORD \u0026#39;u2.password\u0026#39;\u0026#34; gs_guc reload -D $GAUSSHOME/data -c \u0026#34;password_encryption_type=3\u0026#34; gsql -d postgres -c \u0026#34;CREATE USER u3 PASSWORD \u0026#39;u3.password\u0026#39;\u0026#34; gsql -d postgres -c \u0026#34;SELECT rolname,length(rolpassword),rolpassword FROM pg_authid WHERE rolname in (\u0026#39;u0\u0026#39;, \u0026#39;u1\u0026#39;, \u0026#39;u2\u0026#39;, \u0026#39;u3\u0026#39;)\u0026#34; gs_guc reload -D $GAUSSHOME/data -h \u0026#34;local all all sha256\u0026#34; gsql -d postgres -U u0 -W \u0026#39;u0.password\u0026#39; -c \u0026#34;SELECT 1\u0026#34; gsql -d postgres -U u1 -W \u0026#39;u1.password\u0026#39; -c \u0026#34;SELECT 1\u0026#34; gsql -d postgres -U u2 -W \u0026#39;u2.password\u0026#39; -c \u0026#34;SELECT 1\u0026#34; gsql -d postgres -U u3 -W \u0026#39;u3.password\u0026#39; -c \u0026#34;SELECT 1\u0026#34; psql -d postgres -U u0 -W \u0026#39;u0.password\u0026#39; -c \u0026#34;SELECT 1\u0026#34; psql -d postgres -U u1 -W \u0026#39;u1.password\u0026#39; -c \u0026#34;SELECT 1\u0026#34; psql -d postgres -U u2 -W \u0026#39;u2.password\u0026#39; -c \u0026#34;SELECT 1\u0026#34; psql -d postgres -U u3 -W \u0026#39;u3.password\u0026#39; -c \u0026#34;SELECT 1\u0026#34; gs_guc reload -D $GAUSSHOME/data -c \u0026#34;password_encryption_type=2\u0026#34; gsql -d postgres -c \u0026#34;CREATE USER u0 PASSWORD \u0026#39;u2.password\u0026#39;\u0026#34; gsql -d postgres -c \u0026#34;CREATE USER u1 PASSWORD \u0026#39;u2.password\u0026#39;\u0026#34; gsql -d postgres -c \u0026#34;CREATE USER u2 PASSWORD \u0026#39;u2.password\u0026#39;\u0026#34; gsql -d postgres -c \u0026#34;CREATE USER u3 PASSWORD \u0026#39;u2.password\u0026#39;\u0026#34; gsql -d postgres -c \u0026#34;SELECT rolname,length(rolpassword),rolpassword FROM pg_authid WHERE rolname in (\u0026#39;u0\u0026#39;, \u0026#39;u1\u0026#39;, \u0026#39;u2\u0026#39;, \u0026#39;u3\u0026#39;)\u0026#34; 操作流程 当前版本，主要支持的场景是：除了md5认证外，postgresql驱动可通过其他认证方式连接vastbase。为支持该需求，vastbase服务端新增一种认证方式：scram-sha256，该方式与原来的 sha256 存在多个差异，可看做是一种全新的认证方式。\n生成 scram-sha256 密码\n方式一：通过guc控制\ngs_guc reload -D $PGDATA -c \u0026#34;password_encryption_type=4\u0026#34; # 4 表示使用 scram-sha256 加密，加密结果与原型的 sha256 差异较大 CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; 方式二：通过语法控制\nCREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39; STORED \u0026#39;scram-sha256\u0026#39;; 在pg_authid中，u1的密码将使用scram-sha256加密存储。使用vastbase的客户端，无法登录u1用户（暂未适配，如有需求，可适配）。只有postgresql的客户端，才能登录u1用户。\nSELECT rolname,rolpassword FROM pg_authid; rolname | rolpassword -------------------------+------------------------------------------------------------------------------------------------------------------------------------------------- sha256_user | sha256af99537f242c661a88acea99ac626a2cf8fe196ac5671db6f02ed6818b420cf84e7ada61d66602c6eb5bf4ced40911d3f51865959784ebc3b0d385ca4c08f3398f05e16268fe9acc95a2d662bf5033b15d53abd1f835c1a3f1e96343a5cbf800ecdfecefade scram_sha256_user | SCRAM-SHA-256$4096:sp5V1hrLKzLsS4HtQgqTuA==$QO/UVdrXxIypzBEGqEuIWe96A80elghFQs25ZbdPsLg=:J4lPXmXPANtTMOkaHokMjmM19K1Di7fU6WRWuZ5VmS0= 配置 scram-sha256 认证\n用户需主动在pg_hba.conf中，配置scram-sha256认证。\n当有客户端与vastbase建立连接时，vastbase无法识别客户端属于vastbase还是postgresql。因此，只有pg_hba.conf中配置scram-sha256时，客户端才会与指定用户采用scram-sha256认证方式。\ngs_guc reload -D $PGDATA -h \u0026#34;local all u1 scram-sha256\u0026#34; 使用 scram-sha256 连接\n使用scram-sha256时，需确保三者保持配套关系：生成的密码类型、pg_hba.conf配置、数据库驱动端类型\n服务端类型 CREET USER 密码类型 pg_hba.conf 认证类型 客户端类型（vsql or psql） 结果 备注 vastbase sha256 sha256 vastbase 成功 标准场景 vastbase scram-sha256 scram-sha256 postgresql 成功 新增需求，除了md5算法外，postgresql可连接vastbase vastbase sha256 sha256 postgresql 失败 客户现状，除了md5算法外，postgresql驱动无法连接vastbase vastbase sha256 scram-sha256 postgresql 失败 需求约束，客户已有sha256密码，仅配置pg_hba.conf，无法使用postgresql驱动连vastbase vastbase scram-sha256 sha256 postgresql 失败 需求约束，即使生成scram-sha256密码，未配置pg_hba.conf，vastbase无法自动识别驱动类型 vastbase sha256 scram-sha256 vastbase 失败 需求约束，vastbase驱动暂未支持scram-sha256算法 vastbase scram-sha256 sha256 vastbase 失败 需求约束，vastbase驱动暂未支持scram-sha256算法 vastbase scram-sha256 scram-sha256 vastbase 失败 需求约束，vastbase驱动暂未支持scram-sha256算法（如有需求，可支持） vastbse 身份认证协议\nclient (vastbase libpq) +-------+---------------------+-----------------+---------------------------------------------------------------------------+ | int 0 | int protocolversion | string user database replication [backend_version] options [connect_timeout] [env] [其他参数]| --\u0026gt; +-------+---------------------+---------------------------------------------------------------------------------------------+ server (vastbase sha256)：从pg_hba.conf中，选择认证方式 +----------+--------+-------+-----------------+-----------------+---------------+ \u0026lt;--- | char \u0026#39;R\u0026#39; | int 10 | int 2 | string(32) salt | string(8) token | int iteration | +----------+--------+-------+-----------------+-----------------+---------------+ 1 2 3 4 - 1 - 2：使用的算法类型：10 表示 sha256 - 3: 系统表中存储的算法类型：2 表示 sha256 - 4 postgresql 身份认证协议\nclient (postgresql libpq) +-----------------------------+-----------------+----------------------------------------+ | int 0 | int protocolversion | string user database replication options [env] [其他参数] | --\u0026gt; --------+---------------------+----------------------------------------------------------+ server (postgresql scram-sha256)：从pg_hba.conf中，选择认证方式 +----------+--------+-------------------------+ \u0026lt;--- | char \u0026#39;R\u0026#39; | int 10 | string \u0026#39;SCRAM-SHA256\u0026#39; | +----------+--------+------+------------------+ 验证 gs_guc reload -D $GAUSSHOME/data -c \u0026#34;password_encryption_type=2\u0026#34; gs_guc reload -D $GAUSSHOME/data -h \u0026#34;local all all sha256\u0026#34; CREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; SELECT rolname,rolpassword FROM pg_authid; psql -d postgres -U u1 -W \u0026#39;u1.pass1\u0026#39; rfc 5802 # 阶段一：生成密码 client server ----------------------------------------+---------------- | 1. send(password) ---\u0026gt; | | 2. salt = generate() | 3. saltpass = sha256(password, salt, iteration=4096) | 4. clientkey = hmac(saltpass, \u0026#39;Client Key\u0026#39;) | 5. storedkey = sha256(clientkey) | 6. serverkey = hmac(saltpass, \u0026#39;Server Key\u0026#39;) | 7. store(salt, iteration, storedkey, serverkey) | # \u0026#39;SCRAM-SHA-256$iteration:base64(salt)$base64(storedkey):serverkey\u0026#39; # 阶段二：验证密码 client server --------------------------------------------------------+---------------- | 1. generate(clientnonce) | | 2. send(clientnonce) ---\u0026gt; | | 3. find(salt, iteration, storedkey, serverkey) | 4. generate(servernonce) | 5. \u0026lt;--- send(servernonce, salt, iteration) | | 6. saltpass = sha256(password, salt, iteration=4096) | 7. clientkey = hmac(saltpass, \u0026#39;Client Key\u0026#39;) | 8. storedkey = sha256(clientkey) | 9. clientsign = hmac(storedkey, clientnonce, servernonce) | 10. clientproof = xor(clientkey, clientsign) | 11. send(clientproof) ---\u0026gt; | | 12. clientsign = clientsign = hmac(storedkey, clientnonce, servernonce) | 13. _clientkey = xor(clientproof, clientsign) | 14. _storedkey = sha256(_clientkey) | 15. check(storedkey, _storedkey) postgresql 使用sha256 password_encryption = \u0026#39;scram-sha-256\u0026#39; sha256格式 CreateRole encrypt_password get_password_type pg_be_scram_build_verifier pg_saslprep # 1 处理非ascii字符 pg_is_ascii_string pg_backend_random # 生成16字节随机数，作为salt scram_build_verifier scram_SaltedPassword # 使用sha256(password，salt)，计算hmac，迭代4096次，等于PBKDF2，输出saltpass， scram_HMAC_init scram_HMAC_update scram_ClientKey # 使用(saltpass，\u0026#39;Client Key\u0026#39;)，计算hmac，输出storedkey scram_HMAC_update scram_H # 计算storedkey的sha256，仍输出storedkey pg_sha256_update scram_ServerKey # 使用 (saltpass, \u0026#39;Server Key\u0026#39;)，计算hmac，输出serverkey scram_HMAC_update # 拼接结果 # SCRAM-SHA-256${迭代次数}:base64(salt)$base(storedkey):serverkey 示例：\nSELECT rolpassword FROM pg_authid WHERE rolname = \u0026#39;u1\u0026#39;; rolpassword --------------------------------------------------------------------------------------------------------------------------------------- SCRAM-SHA-256$4096:s44zkBNiF7EYfIjemotD3w==$Rl9Pr4CbgF1UkLgJuMKyhmzn3lVaBI6JCfpB8yF9hc4=:GD3dLK/+DpyVxJRLJnUWtbgzl/S2JXkCETSB5pDNF7A= 类型 内容 算法标识 SCRAM-SHA-256 拼接符 $ 迭代次数 4096 拼接符 : base64格式的salt（16字节随机数） s44zkBNiF7EYfIjemotD3w== 拼接符 $ base格式的sha256(hmac(PBKDF2(salt, password, 迭代次数), ‘Client Key’)) Rl9Pr4CbgF1UkLgJuMKyhmzn3lVaBI6JCfpB8yF9hc4= 拼接符 : base格式的hmac(PBKDF2(salt, password, 迭代次数), ‘Server Key’) GD3dLK/+DpyVxJRLJnUWtbgzl/S2JXkCETSB5pDNF7A= # pg10 PostmasterMain # postmaster 线程 ServerLoop ConnCreate BackendStartup BackendInitialize BackendRun PostgresMain # postgres 线程 InitPostgres PerformAuthentication ClientAuthentication hba_getauthmethod CheckPWChallengeAuth get_role_password # 从pg_authid系统表中查询ropassword get_password_type # 从rolpassword中获取前缀 CheckSCRAMAuth sendAuthRequest pg_be_scram_init parse_scram_verifier # 从rolpassword中，根据拼接符，依次获取各个子参数，并进行base64解码 strtok pg_b64_decode pq_getbyte(\u0026#39;p\u0026#39;) # 接受客户端消息 pg_be_scram_exchange read_client_first_message build_server_first_message sendAuthRequest for (;;) ReadCommand vasebase 阶段一：存储密码 CreateRole RAND_priv_bytes # 生成32字节salt calculate_encrypted_password pg_sha256_encrypt # 计算 sha256(salt, password, 迭代次数)，迭代次数可配置，默认为10000 PKCS5_PBKDF2_HMAC # PBKDF2(password, salt, 迭代次数)，使用sha1算法，输出k CRYPT_hmac HMAC # 计算sha256(k, \u0026#39;Sever Key\u0026#39;)，输出serverkey CRYPT_hmac HMAC # 计算sha256(k, \u0026#39;Client Key\u0026#39;)，输出clientkey EVP_Digest # 计算 sha256(client_key)，输出stored_key # 拼接结果 # sha256{hex(salt)}{hex(serverkey)}{hex(stored_key)} encode_iteration # 在结果后拼接 hex(迭代次数) client server +-----------------------------------------------------+ | send($username) | $mechanism = find(\u0026#39;pg_authid\u0026#39;) send($are1=AUTH_REQ_SASL, $mechanism) | | preprocess($password) | $cleintnoce = random(18) | $client_first_message_bare = (\u0026#39;n=,r=%s\u0026#39;, $clientnonce) | send(\u0026#39;p\u0026#39;, \u0026#39;SCRAM-SHA-256\u0026#39;, \u0026#39;n,,n=,r=%s\u0026#39;, $clientnonce) | server_first_message = (\u0026#39;r=%s,s=%s,i=%s\u0026#39;, servernoce, salt, iteration) send(areq=AUTH_REQ_SASL_CONT, $server_first_message) | client_final_message_without_proof [c=biws,r=fhbF8xOmYuU9fjiMvMq/7sDjWMoEswVp/GzaslfJ7psvSGKx] 阶段二：验证密码 # pg PQconnectdb PQconnectStart connectOptions1 connectOptions2 connectDBStart PQconnectPoll keep_going: if CONNECTION_NEEDED: # 1 建立连接 connect set CONNECTION_STARTED elif CONNECTION_STARTED: # 2 获取连接信息 getsockopt getsockname set CONNECTION_MADE elif CONNECTION_MADE: # 3 填充用户信息：user, database等 pqBuildStartupPacket3 build_startup_packet pqPacketSend set CONNECTION_AWAITING_RESPONSE elif CONNECTION_AWAITING_RESPONSE # 走到该状态好几次 pqGetc # get R or E, R是身份认证 pqGetInt # get length pqGetInt # get auth type: [AUTH_REQ_OK, AUTH_REQ_MD5, AUTH_REQ_PASSWORD, AUTH_REQ_SASL, AUTH_REQ_SASL_CONT, AUTH_REQ_SASL_FIN, AUTH_REQ_SCM_CREDS] pg_fe_sendauth if AUTH_REQ_SASL: pg_SASL_init pqGets # get mechanism, only support: \u0026#34;SCRAM-SHA-256\u0026#34; pg_fe_scram_init pg_saslprep # 处理password中的特殊字符为 UTF-8 pg_fe_scram_exchange # 第一次调用，仅处理build_client_first_message build_client_first_message # 1 生成客户端 clientnonce pg_frontend_random # 生成18字节随机数 clientnonce pg_b64_enc_len # 编码 clientnonce client_first_message_bare = snprintf(\u0026#34;n,n=,r=%s\u0026#34;, clientnonce) elif AUTH_REQ_SASL_CONT or AUTH_REQ_SASL_FIN: pg_SASL_continue pg_fe_scram_exchange read_server_first_message # 2 接受服务端 (servernoce, salt, iteration) server_first_message = receive(\u0026#39;r=%s%s,s=%s,i=%u\u0026#39;, clientnoce, servernoce, salt, iteration) read_attr_value(\u0026#39;r\u0026#39;) # 获取服务端 servernoce read_attr_value(\u0026#39;s\u0026#39;) # 获取服务端 salt read_attr_value(\u0026#39;i\u0026#39;) # 获取服务端 iteration build_client_final_message # 结算 appendPQExpBuffer(\u0026#39;c=biws,r=%s\u0026#39;, servernoce) client_final_message_without_proof = (\u0026#39;c=biws,r=%s\u0026#39;, servernoce) calculate_client_proof scram_SaltedPassword hmac(password, salt, iteration) # 生成 saltpass scram_ClientKey hmac(saltpass, \u0026#39;Client Key\u0026#39;) # 生成 clientkey scram_H pg_sha256_update(clientkey) # 生成 storedkey scram_HMAC_update(storedkey, client_first_message_bare, server_first_message, client_final_message_without_proof) # 生成 clientsign clientproof = clientkey ^ clientsign appendPQExpBuffer(\u0026#39;,p=%s\u0026#39;, clientproof) read_server_final_message read_attr_value(\u0026#39;v\u0026#39;) # 获取服务端 serversign verify_server_signature scram_ServerKey pg_sha256_update(saltpass) # 输出serverkey scram_HMAC_update(serverkey, client_first_message_bare, server_first_message, client_final_message_without_proof) # 输出 _serversign memcpy(_serversign, servergin) # 比较 serversign与_serversign pqPacketSend elif AUTH_REQ_SCM_CREDS: pg_local_sendauth set CONNECTION_AUTH_OK connectDBComplete # pg PostmasterMain # postmaster 线程 ServerLoop ConnCreate StreamConnection BackendStartup PostgresMain # postgres 线程 InitBackendWorker InitSession CheckAuthentication PerformAuthentication port-\u0026gt;protocol_config-\u0026gt;fn_authenticate ClientAuthentication hba_getauthmethod check_hba g_instance.libpq_cxt_comm_parsed_hba_lines # 读取缓存的hba if init_user: get_default_auth_method else: check_hostname sendAuthRequest recv_and_check_password_packet # 接收客户端的password crypt_verify for (;;) ReadCommand exec_simple_query(\u0026#39;SQL\u0026#39;) ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/4-requirement-scram-sha256/","summary":"\u003ch1 id=\"深信服支持pg-scram-sha256需求\"\u003e深信服支持pg scram-sha256需求\u003c/h1\u003e\n\u003ch2 id=\"需求目标\"\u003e需求目标\u003c/h2\u003e\n\u003cp\u003e本需求的根本目标时，当vastbase server要求使用sha256算法进行身份认证时，postgresql client能与vastbase server建立连接。\u003cbr\u003e\n该需求目前仅合入深信服分支\u003c/p\u003e\n\u003ch2 id=\"需求分析\"\u003e需求分析\u003c/h2\u003e\n\u003cp\u003e身份认证的详细流程有点复杂，此处简要概述为2个阶段：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e标识：新建用户时，server计算并存储密码哈希值\u003c/li\u003e\n\u003cli\u003e鉴别：用户登录时，server向client发送计算密码哈希值的关键信息，client计算并向server发送密码哈希值，server校验其是否符合存储的值\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003evastbase和postgresql对比，server计算密码哈希值的算法不同，server向client发送关键信息也不同。为解决pg-client能够连接vb-server的问题，需解决问题如下：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003evb-server计算并存储与pg-server一致的密码哈希值\u003c/li\u003e\n\u003cli\u003evb-server向pg-client发送密码哈希值关键信息时，需要pg-server一致\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003epostgreql的标识与鉴别机制，符合标准RFC-5802，涉及的算法与协议，本文统一称为scram-sha256。vastbase涉及的算法与协议，本文统一称为sha256。\u003c/p\u003e\n\u003ch2 id=\"需求实现\"\u003e需求实现\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e密码存储：新建用户时，修改存储用户密码的值\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e修改前：guc参数password_encrypt_type，取值1时，vb-server存储密码的[sha256, md5]值；取值为2时，存储密码的[sha256]值\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erolpassword\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eFORM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgauthid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 示例：长度为209\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003erolpassword\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e--------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003esha256af99537f242c661a88acea99ac626a2cf8fe196ac5671db6f02ed6818b420cf84e7ada61d66602c6eb5bf4ced40911d3f51865959784ebc3b0d385ca4c08f3398f05e16268fe9acc95a2d662bf5033b15d53abd1f835c1a3f1e96343a5cbf800ecdfecefade\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e修改后：guc参数password_encrypt_type，取值1时，vb-server存储密码的[sha256, md5, scram-sha256]值；取值为2时，存储密码的[sha256, scram-sha256]值\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erolpassword\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eFORM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgauthid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 示例：长度342 (新增长度：133)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003erolpassword\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e--------------------------------------------------------------------------------------------------------------------------------------------------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003esha256af99537f242c661a88acea99ac626a2cf8fe196ac5671db6f02ed6818b420cf84e7ada61d66602c6eb5bf4ced40911d3f51865959784ebc3b0d385ca4c08f3398f05e16268fe9acc95a2d662bf5033b15d53abd1f835c1a3f1e963SCRAM\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eSHA\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e256\u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"mi\"\u003e4096\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"n\"\u003esp5V1hrLKzLsS4HtQgqTuA\u003c/span\u003e\u003cspan class=\"o\"\u003e==\u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eQO\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003eUVdrXxIypzBEGqEuIWe96A80elghFQs25ZbdPsLg\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"n\"\u003eJ4lPXmXPANtTMOkaHokMjmM19K1Di7fU6WRWuZ5VmS0\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e认证协议：用户登录时，修改向客户端发送的密码哈希值关键信息\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e修改前：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 身份认证协议\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e1. client \u0026lt;-\u0026gt; server : tcp connect\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e2. client --\u0026gt; server : send \u003cspan class=\"o\"\u003e[\u003c/span\u003e消息类型:0, 协议版本:3.51，连接参数:user_name, databse, ...\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e3. server --\u0026gt; client : send \u003cspan class=\"o\"\u003e[\u003c/span\u003e消息类型:R, 哈希算法:10, 系统表存储的密码的算法:2, 计算密码哈希关键信息：salt,token,iteration\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e4. client \u0026lt;-\u0026gt; server : \u003cspan class=\"c1\"\u003e# 省略3次交互\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e修改后：\u003c/p\u003e","title":"海量 4 需求 scram-sha256"},{"content":"https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001006330\n3 异常参数 3.1 DES encrypt 封装函数\nCREATE OR REPLACE FUNCTION desencrypt(hex_plain VARCHAR2, hex_key VARCHAR2) RETURN VARCHAR2 IS cipher RAW(100); BEGIN dbms_obfuscation_toolkit.desencrypt(hextoraw(hex_plain), hextoraw(hex_key), encrypted_data=\u0026gt;cipher); RETURN rawtohex(cipher); END; / 函数格式\ndesencrypt(plain, key, cipher); 约束：\n构造用例\n明文长度 密钥长度 输出：密文长度 示例 结果 一、正常用例 8 8 8 desencrypt() abc 16 8 16 desencrypt() abc 一、明文长度异常 0 8 16 desencrypt() 明文不是8的倍数 1 8 - desencrypt() 明文不是8的倍数 7 8 - desencrypt() 明文不是8的倍数 15 8 - desencrypt() 明文不是8的倍数 二、密钥长度异常 8 0 8 desencrypt() 密钥长度不是8 8 1 8 desencrypt() 密钥长度不是8 8 15 8 desencrypt() 密钥长度不是8 8 16 8 desencrypt() 密钥长度不是8 3.2 DES decrypt 3.3 3DES encrypt 封装函数\nCREATE OR REPLACE FUNCTION des3encrypt(hex_plain VARCHAR2, hex_key VARCHAR2, hex_iv VARCHAR2, key_mode INT) RETURN VARCHAR2 IS cipher RAW(100); BEGIN dbms_obfuscation_toolkit.des3encrypt(input=\u0026gt;hextoraw(hex_plain), key=\u0026gt;hextoraw(hex_key), encrypted_data=\u0026gt;cipher, which=\u0026gt;key_mode, iv=\u0026gt;hextoraw(hex_iv)); RETURN rawtohex(cipher); END; / 函数格式\ndes3encrypt(plain, key, iv, mode, cipher); 构造用例\n7 oracle 加密函数 7.1 DES 函数格式\ndbms_obfuscation_toolkit.desencrypt(plain, key, cipher); 前置知识\n-- varchar --\u0026gt; raw SELECT utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;) FROM dual; -- raw --\u0026gt; varchar SELECT utl_raw.cast_to_varchar2(hextoraw(\u0026#39;3131313131313131\u0026#39;)) FROM dual; -- raw -\u0026gt; hex SELECT rawtohex(\u0026#39;11111111\u0026#39;) FROM dual; SELECT hextoraw(\u0026#39;3131313131313131\u0026#39;) FROM dual; 加密函数\n示例1\nSET SERVEROUTPUT ON; DECLARE cipher RAW(100); BEGIN dbms_obfuscation_toolkit.desencrypt(hextoraw(\u0026#39;3131313131313131\u0026#39;), hextoraw(\u0026#39;3131313131313131\u0026#39;), encrypted_data=\u0026gt;cipher); dbms_output.put_line(rawtohex(cipher)); END; / 示例2\nCREATE OR REPLACE FUNCTION desencrypt(hex_plain VARCHAR2, hex_key VARCHAR2) RETURN VARCHAR2 IS cipher RAW(100); BEGIN dbms_obfuscation_toolkit.desencrypt(hextoraw(hex_plain), hextoraw(hex_key), encrypted_data=\u0026gt;cipher); RETURN rawtohex(cipher); END; / SELECT desencrypt(\u0026#39;3131313131313131\u0026#39;, \u0026#39;3131313131313131\u0026#39;) FROM dual; -- 输出 655EA628CF62585F SELECT desencrypt(\u0026#39;31313131313131313131313131313131\u0026#39;, \u0026#39;3131313131313131\u0026#39;) FROM dual; -- 输出 655EA628CF62585F20D3B8A6E657876B 解密函数\n示例2\nCREATE OR REPLACE FUNCTION desdecrypt(hex_cipher VARCHAR2, hex_key VARCHAR2) RETURN VARCHAR2 IS plain RAW(100); BEGIN dbms_obfuscation_toolkit.desdecrypt(hextoraw(hex_cipher), hextoraw(hex_key), decrypted_data=\u0026gt;plain); RETURN rawtohex(plain); END; / SELECT desdecrypt(\u0026#39;655EA628CF62585F\u0026#39;, \u0026#39;3131313131313131\u0026#39;) FROM dual; -- 输出 3131313131313131 SELECT desdecrypt(\u0026#39;655EA628CF62585F20D3B8A6E657876B\u0026#39;, \u0026#39;3131313131313131\u0026#39;) FROM dual; -- 输出 31313131313131313131313131313131 7.2 3DES 函数格式\ndbms_obfuscation_toolkit.DESencrypt(plain, key, mode); which的含义：\n0：2密钥格式，k1 = k3 1：3密钥格式 加密函数\nCREATE OR REPLACE FUNCTION des3encrypt(hex_plain VARCHAR2, hex_key VARCHAR2, hex_iv VARCHAR2, key_mode INT) RETURN VARCHAR2 IS cipher RAW(100); BEGIN dbms_obfuscation_toolkit.des3encrypt(input=\u0026gt;hextoraw(hex_plain), key=\u0026gt;hextoraw(hex_key), encrypted_data=\u0026gt;cipher, which=\u0026gt;key_mode, iv=\u0026gt;hextoraw(hex_iv)); RETURN rawtohex(cipher); END; / SELECT des3encrypt(\u0026#39;3131313131313131\u0026#39;, \u0026#39;31313131313131313131313131313131\u0026#39;，\u0026#39;31313131313131313131313131313131\u0026#39;, 0) FROM dual; SELECT des3encrypt(\u0026#39;31313131313131\u0026#39;, \u0026#39;31313131313131313131313131313131\u0026#39;，NULL, 0) FROM dual; -- 废弃 SELECT rawtohex(dbms_obfuscation_toolkit.des3encrypt(hextoraw(\u0026#39;3131313131313131\u0026#39;), hextoraw(\u0026#39;31313131313131313131313131313131\u0026#39;), 0)) FROM dual; SELECT dbms_obfuscation_toolkit.des3encrypt(hextoraw(\u0026#39;3131313131313131\u0026#39;), hextoraw(\u0026#39;3131313131313131\u0026#39;), 0) FROM dual; 其他\n示例1\nselect utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, key_string=\u0026gt;010199010401050110974949, which=\u0026gt;0)) from dual; -- 输出： E7E14DFD9E0DED3B 验证\n-- 3des select utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, key_string=\u0026gt;010199010401050110974949, which=\u0026gt;0)) from dual; -- 密钥长度为12字节，实际只用了10字节，后面的被截断扔了 -- 明文为8字节，密文为8字节 -- 输出： E7E14DFD9E0DED3B -- 明文7，9字节都不行，只能是8的整数倍 -- 明文16字节 select utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;1111111111111111\u0026#39;, key_string=\u0026gt;010199010401050110974949, which=\u0026gt;0)) from dual; -- 输出： E7E14DFD9E0DED3B D80084E1EDD76DF1 -- 密钥截断 select utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, key_string=\u0026gt;010199010401050110, which=\u0026gt;0)) from dual; -- 输出： E7E14DFD9E0DED3B -- 最低为18位，后几位没用，实际为14位 select utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, key_string=\u0026gt;010199010401050000, which=\u0026gt;0)) from dual; -- 输出： E7E14DFD9E0DED3B -- 18字节密钥，截断6位，明文变长 select utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;1111111111111111\u0026#39;, key_string=\u0026gt;010199010401050000, which=\u0026gt;0)) from dual; -- 输出： E7E14DFD9E0DED3B D80084E1EDD76DF1 -- 14最后一位变化也不影响 select utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, key_string=\u0026gt;010199010401040000, which=\u0026gt;0)) from dual; -- 输出： E7E14DFD9E0DED3B select utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, key_string=\u0026gt;010199010401030000, which=\u0026gt;0)) from dual; -- 输出 C725C0228F108C77 -- 20也是 C725C0228F108C77 select utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, key_string=\u0026gt;010199010401010000, which=\u0026gt;0)) from dual; -- 输出 69AB538F1542F919 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/4-oracle-security/","summary":"\u003cp\u003e\u003ca href=\"https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001006330\"\u003ehttps://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001006330\u003c/a\u003e\u003c/p\u003e\n\u003ch1 id=\"3-异常参数\"\u003e3 异常参数\u003c/h1\u003e\n\u003ch2 id=\"31-des-encrypt\"\u003e3.1 DES encrypt\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e封装函数\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eREPLACE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFUNCTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehex_plain\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eVARCHAR2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ehex_key\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eVARCHAR2\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eRETURN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eVARCHAR2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIS\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003ecipher\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eRAW\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e100\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003edbms_obfuscation_toolkit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehextoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehex_plain\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ehextoraw\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ehex_key\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eencrypted_data\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ecipher\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eRETURN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erawtohex\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ecipher\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eEND\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e函数格式\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003edesencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eplain\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecipher\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e约束：\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e构造用例\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e明文长度\u003c/th\u003e\n          \u003cth\u003e密钥长度\u003c/th\u003e\n          \u003cth\u003e输出：密文长度\u003c/th\u003e\n          \u003cth\u003e示例\u003c/th\u003e\n          \u003cth\u003e结果\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e一、正常用例\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003edesencrypt()\u003c/td\u003e\n          \u003ctd\u003eabc\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e16\u003c/td\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003e16\u003c/td\u003e\n          \u003ctd\u003edesencrypt()\u003c/td\u003e\n          \u003ctd\u003eabc\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e一、明文长度异常\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e0\u003c/td\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003e16\u003c/td\u003e\n          \u003ctd\u003edesencrypt()\u003c/td\u003e\n          \u003ctd\u003e明文不是8的倍数\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e1\u003c/td\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003edesencrypt()\u003c/td\u003e\n          \u003ctd\u003e明文不是8的倍数\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e7\u003c/td\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003edesencrypt()\u003c/td\u003e\n          \u003ctd\u003e明文不是8的倍数\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e15\u003c/td\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003edesencrypt()\u003c/td\u003e\n          \u003ctd\u003e明文不是8的倍数\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e二、密钥长度异常\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003e0\u003c/td\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003edesencrypt()\u003c/td\u003e\n          \u003ctd\u003e密钥长度不是8\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003e1\u003c/td\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003edesencrypt()\u003c/td\u003e\n          \u003ctd\u003e密钥长度不是8\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003e15\u003c/td\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003edesencrypt()\u003c/td\u003e\n          \u003ctd\u003e密钥长度不是8\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003e16\u003c/td\u003e\n          \u003ctd\u003e8\u003c/td\u003e\n          \u003ctd\u003edesencrypt()\u003c/td\u003e\n          \u003ctd\u003e密钥长度不是8\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"32-des-decrypt\"\u003e3.2 DES decrypt\u003c/h2\u003e\n\u003ch2 id=\"33-3des-encrypt\"\u003e3.3 3DES encrypt\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e封装函数\u003c/p\u003e","title":"数据库安全 Oracle"},{"content":" 摘要：介绍常见数据库安全机制的原理：\n1.身份认证\n2.安全传输\n3.安全审计\n4.访问控制\n5.数据发现\n6.数据防篡改\n7.加密函数\n8.透明加密\n9.数据脱敏\n10.全密态加密\n11.机密计算\n1 数据库安全概述 1.1 数据库基本功能 本文讨论数据库安全，为方便理解，将大部分软件架构简化为2个主体：应用端与数据库端。\n应用：实现业务逻辑，收集业务数据，将数据发送至数据库，由数据库提供数据存储功能，并且，要求数据库提供数据查询功能 数据库：存储业务数据，向应用提供SQL接口，接收应用发送的SQL语句，并处理SQL语句。同时，解决高并发、高性能、高可靠的问题 大部分场景中，应用与数据库部署于不同主机上，以下是一个应用使用数据库实现数据存储与查询的示例流程：\n建立连接：应用与数据库建立网络连接\n定义数据：应用向数据库发送以下SQL语句，创建1个表\nCREATE TABLE t1 (c1 INT, c2 TEXT); 存储数据：应用向数据库发送以下SQL语句，向表中存储数据\nINSERT INTO t1 VALUES (1, \u0026#39;abc\u0026#39;); 查询数据：应用向数据库发送以下SQL语句，从表中查询数据\nSELECT * FROM t1; 1.2 数据库基本架构 数据库架构较复杂，此处先将数据库架构简单划分为以下3个部分：\n数据库驱动：集成到应用内部，向应用提供编程接口，常见接口有：连接数据库、执行SQL语句等 计算模块：解析SQL语句，并按合理地执行流程处理SQL语句中的请求，调用存储模块接口实现数据存储与读取 存储模块：合理组织数据，调用IO接口，实现磁盘读写操作。向计算模块提供接口 1.3 数据库安全威胁 在应用使用数据库的过程中，攻击者可能对整个系统造成恶意攻击，攻击的最终目标是：\n破坏业务数据：窃取、伪造、篡改、损坏等 破坏业务系统：拒绝服务等 攻击者针对多个系统薄弱点进行功能：\n数据库网络：协议等 数据库应用：身份认证机制等 数据库主机：操作系统、软件（除数据库外的其他软件）、硬件等 假设应用与数据库部署在不同主机，分为是下图中的主机c和主机z，常见安全威胁的架构图如下：\n1.4 数据安全架构 针对各类威胁，数据库提供多种安全机制，保护数据与数据库安全，常见的安全机制如下：\n身份认证：阻止非法用户与数据库建立网络连接 安全传输：阻止非法用户窃取、篡改、伪造、..传输数据 安全审计：记录非法/合法用户对数据库的操作 访问控制：缩小非法用户对数据库的访问范围 数据发现：协助合法用户识别敏感数据 数据防篡改：识别非法用户篡改、伪造、..存储数据 加密函数：协助合法用户加密存储数据 透明加密：阻止非法用户窃取、篡改、伪造、..存储数据 数据脱敏：缩小非法用户对数据内容的访问范围 全密态加密：阻止非法用户窃取、篡改、伪造、..传输、计算、存储数据 机密计算：阻止非法用户窃取、篡改、伪造计算数据 按对数据处理的顺序，各安全机制的架构如下图所示：\n2 数据库安全特性 2.1 身份认证 2.2 安全传输 2.3 安全审计 2.4 访问控制 2.5 数据发现 2.6 数据防篡改 2.7 加密函数 2.8 透明加密 2.9 数据脱敏 2.10 全密态加密 2.11 机密计算 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/4-0-database-security/","summary":"\u003cblockquote\u003e\n\u003cp\u003e摘要：介绍常见数据库安全机制的原理：\u003cbr\u003e\n1.身份认证\u003cbr\u003e\n2.安全传输\u003cbr\u003e\n3.安全审计\u003cbr\u003e\n4.访问控制\u003cbr\u003e\n5.数据发现\u003cbr\u003e\n6.数据防篡改\u003cbr\u003e\n7.加密函数\u003cbr\u003e\n8.透明加密\u003cbr\u003e\n9.数据脱敏\u003cbr\u003e\n10.全密态加密\u003cbr\u003e\n11.机密计算\u003c/p\u003e\u003c/blockquote\u003e\n\u003ch1 id=\"1-数据库安全概述\"\u003e1 数据库安全概述\u003c/h1\u003e\n\u003ch2 id=\"11-数据库基本功能\"\u003e1.1 数据库基本功能\u003c/h2\u003e\n\u003cp\u003e本文讨论数据库安全，为方便理解，将大部分软件架构简化为2个主体：应用端与数据库端。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e应用：实现业务逻辑，收集业务数据，将数据发送至数据库，由数据库提供数据存储功能，并且，要求数据库提供数据查询功能\u003c/li\u003e\n\u003cli\u003e数据库：存储业务数据，向应用提供SQL接口，接收应用发送的SQL语句，并处理SQL语句。同时，解决高并发、高性能、高可靠的问题\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e大部分场景中，应用与数据库部署于不同主机上，以下是一个应用使用数据库实现数据存储与查询的示例流程：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e建立连接：应用与数据库建立网络连接\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e定义数据：应用向数据库发送以下SQL语句，创建1个表\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e存储数据：应用向数据库发送以下SQL语句，向表中存储数据\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;abc\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e查询数据：应用向数据库发送以下SQL语句，从表中查询数据\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"12-数据库基本架构\"\u003e1.2 数据库基本架构\u003c/h2\u003e\n\u003cp\u003e数据库架构较复杂，此处先将数据库架构简单划分为以下3个部分：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e数据库驱动：集成到应用内部，向应用提供编程接口，常见接口有：连接数据库、执行SQL语句等\u003c/li\u003e\n\u003cli\u003e计算模块：解析SQL语句，并按合理地执行流程处理SQL语句中的请求，调用存储模块接口实现数据存储与读取\u003c/li\u003e\n\u003cli\u003e存储模块：合理组织数据，调用IO接口，实现磁盘读写操作。向计算模块提供接口\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"13-数据库安全威胁\"\u003e1.3 数据库安全威胁\u003c/h2\u003e\n\u003cp\u003e在应用使用数据库的过程中，攻击者可能对整个系统造成恶意攻击，攻击的最终目标是：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e破坏业务数据：窃取、伪造、篡改、损坏等\u003c/li\u003e\n\u003cli\u003e破坏业务系统：拒绝服务等\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e攻击者针对多个系统薄弱点进行功能：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e数据库网络：协议等\u003c/li\u003e\n\u003cli\u003e数据库应用：身份认证机制等\u003c/li\u003e\n\u003cli\u003e数据库主机：操作系统、软件（除数据库外的其他软件）、硬件等\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e假设应用与数据库部署在不同主机，分为是下图中的主机c和主机z，常见安全威胁的架构图如下：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"risk\" loading=\"lazy\" src=\"/images/Security/4-0-database-security/risk.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"14-数据安全架构\"\u003e1.4 数据安全架构\u003c/h2\u003e\n\u003cp\u003e针对各类威胁，数据库提供多种安全机制，保护数据与数据库安全，常见的安全机制如下：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e身份认证：阻止非法用户与数据库建立网络连接\u003c/li\u003e\n\u003cli\u003e安全传输：阻止非法用户窃取、篡改、伪造、..传输数据\u003c/li\u003e\n\u003cli\u003e安全审计：记录非法/合法用户对数据库的操作\u003c/li\u003e\n\u003cli\u003e访问控制：缩小非法用户对数据库的访问范围\u003c/li\u003e\n\u003cli\u003e数据发现：协助合法用户识别敏感数据\u003c/li\u003e\n\u003cli\u003e数据防篡改：识别非法用户篡改、伪造、..存储数据\u003c/li\u003e\n\u003cli\u003e加密函数：协助合法用户加密存储数据\u003c/li\u003e\n\u003cli\u003e透明加密：阻止非法用户窃取、篡改、伪造、..存储数据\u003c/li\u003e\n\u003cli\u003e数据脱敏：缩小非法用户对数据内容的访问范围\u003c/li\u003e\n\u003cli\u003e全密态加密：阻止非法用户窃取、篡改、伪造、..传输、计算、存储数据\u003c/li\u003e\n\u003cli\u003e机密计算：阻止非法用户窃取、篡改、伪造计算数据\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e按对数据处理的顺序，各安全机制的架构如下图所示：\u003c/p\u003e","title":"数据库安全 0 整体架构"},{"content":"1 图的介绍 1.1 定义 G = (V, E)\n一组节点V 一组边E 节点的度：相邻节点的数量 完备图：所有节点都有n-1个相邻节点，即任意2节点间可达 1.2 分类 根据边分类 无向图\nn1 ---- n2 | | | | n3 ---- n4 有向图\n--\u0026gt; n2 n1 --\u0026gt; n4 --\u0026gt; n3 带权有向图\n3 ---\u0026gt; n2 6 n1 ---\u0026gt; n4 ---\u0026gt; n3 5 图的性质分类 同构图：G和H，通过重新标记G的节点产生H。阶相等，顶点度数相等 异构图 1.3 表示 邻接矩阵\n如果节点间ni,nj之间有弧，则[ni, nj] = 1\nn1 n2 n3 n4 +------------+ n1 | 0 1 1 0 | n2 | 0 0 0 1 | n3 | 0 0 0 1 | n4 | 0 0 0 0 | +------------+ 无向图的斜下半部分是多余的\n#define MAX_NODE_NUM typedef struct { int node_cnt; int edge_matrix[MAX_NODE_NUM][MAX_NODE_NUM]; int node_visit[MAX_NODE_NUM][MAX_NODE_NUM]; } Graph; 邻接表\n[1] -\u0026gt; [2, 3] [2] -\u0026gt; [4] [3] -\u0026gt; [4] [4] -\u0026gt; [] typedef struct Node { int val; int weight; struct Node *next; } Node; typedef struct { int val; Node *next; } GraphNode; GraphNode graph[] = {0}; 弧表示法\n-----+---------------+ 起点 | 1 | 1 | 2 | 3 | 终点 | 2 | 3 | 4 | 4 | 权重 | | | | | -----+---------------+ 2 图的遍历 #define MAX_NODE_NUM typedef struct { int node_num; int edge_matrix[MAX_NODE_NUM][MAX_NODE_NUM]; int node_visit[MAX_NODE_NUM][MAX_NODE_NUM]; } Graph; typedef struct { int x; int y; } NodePlace; void graph_dfs(Graph *graph, NodePlace node) { int i; int j; for (i = 0; i \u0026lt; graph-\u0026gt;node_cnt; i++) { . } } ","permalink":"https://my-blog.j8465383071.workers.dev/posts/algorithm/4-graph/","summary":"\u003ch1 id=\"1-图的介绍\"\u003e1 图的介绍\u003c/h1\u003e\n\u003ch2 id=\"11-定义\"\u003e1.1 定义\u003c/h2\u003e\n\u003cp\u003eG = (V, E)\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e一组节点V\u003c/li\u003e\n\u003cli\u003e一组边E\u003c/li\u003e\n\u003cli\u003e节点的度：相邻节点的数量\u003c/li\u003e\n\u003cli\u003e完备图：所有节点都有n-1个相邻节点，即任意2节点间可达\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"12-分类\"\u003e1.2 分类\u003c/h2\u003e\n\u003ch3 id=\"根据边分类\"\u003e根据边分类\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e无向图\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-fallback\" data-lang=\"fallback\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003en1 ---- n2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e|       |\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e|       |\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003en3 ---- n4\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e有向图\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-fallback\" data-lang=\"fallback\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   --\u0026gt; n2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003en1       --\u0026gt; n4\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   --\u0026gt; n3\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e带权有向图\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-fallback\" data-lang=\"fallback\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    3\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   ---\u0026gt; n2  6\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003en1         ---\u0026gt; n4\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   ---\u0026gt; n3\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    5\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"图的性质分类\"\u003e图的性质分类\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e同构图：G和H，通过重新标记G的节点产生H。阶相等，顶点度数相等\u003c/li\u003e\n\u003cli\u003e异构图\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"13-表示\"\u003e1.3 表示\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e邻接矩阵\u003cbr\u003e\n如果节点间ni,nj之间有弧，则[ni, nj] = 1\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-fallback\" data-lang=\"fallback\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e     n1 n2 n3 n4\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   +------------+\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003en1 | 0  1  1  0 |\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003en2 | 0  0  0  1 |\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003en3 | 0  0  0  1 |\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003en4 | 0  0  0  0 |\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   +------------+\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e无向图的斜下半部分是多余的\u003c/p\u003e","title":"数据结构与算法 4 图"},{"content":"1 使用pgaudt 1.1 常见SQL -- 1 ddl CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; CREATE TABLE t1(c1 INT, c2 TEXT); CREATE TABLE t2 (c1 INT, c2 TEXT); CREATE INDEX i1 ON t1(c2); -- 2 dml INSERT INTO t1 VALUES (1, \u0026#39;aaa\u0026#39;), (2, \u0026#39;bbb\u0026#39;), (3, \u0026#39;ccc\u0026#39;); INSERT INTO t2 VALUES (1, \u0026#39;aaa\u0026#39;), (5, \u0026#39;bbb\u0026#39;); UPDATE t1 SET c2 = \u0026#39;ddd\u0026#39; WHERE c1 \u0026lt; 3; DELETE FROM t1 WHERE c1 = 2; -- 3 select SELECT * FROM t1; -- 4 function SELECT c2 || \u0026#39;_oper\u0026#39; FROM t1; SELECT concat(c2, \u0026#39;_func\u0026#39;) FROM t1; INSERT INTO t1 VALUES (5, concat(\u0026#39;aaa\u0026#39;, \u0026#39;_func\u0026#39;)), (6, concat(\u0026#39;aaa\u0026#39;, \u0026#39;_func\u0026#39;)); -- 5 multi INSERT INTO t1 SELECT * FROM t2; SELECT * FROM t1 JOIN t2 ON t1.c1 = t2.c1; CREATE TABLE t3 AS SELECT * FROM t2; DROP TABLE t1,t2,t3; 1 安装pgaudit 1.1 安装postgresql # 1 配置环境变量 echo \u0026#39;export BUILD_ROOT=`pwd`\u0026#39; \u0026gt; pgenv echo \u0026#39;export PG_HOME=$BUILD_ROOT/install\u0026#39; \u0026gt;\u0026gt; pgenv echo \u0026#39;export PATH=\u0026#34;$PG_HOME/bin:$PATH\u0026#34;\u0026#39; \u0026gt;\u0026gt; pgenv source pgenv # 2 下载源码 wget https://ftp.postgresql.org/pub/source/v14.18/postgresql-14.18.tar.gz tar -zxvf postgresql-14.18.tar.gz cd postgresql-14.18.tar.gz # 3 编译源码 (不开启debug模式，提高性能) #./configure --prefix=$PG_HOME --enable-debug=yes ./configure --prefix=$PG_HOME --enable-debug=no --enable-cassert=no make -sj make install -sj # ========================================== cd $BUILD_ROOT/pg14/contrib/pgaudit make install USE_PGXS=1 PG_CONFIG=$PG_HOME/bin/pg_config cd - # ========================================== # 4 初始化集群 initdb -D $PG_HOME/data # 4 配置集群 # echo \u0026#34;port = 54000\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf # echo \u0026#34;max_connections = 1000\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf # ========================================== echo \u0026#34;logging_collector = on\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf echo \u0026#34;shared_preload_libraries = \u0026#39;pgaudit\u0026#39;\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf echo \u0026#34;pgaudit.log = \u0026#39;ALL\u0026#39;\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf echo \u0026#34;pgaudit.log_catalog = true\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf echo \u0026#34;pgaudit.log_client = true\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf echo \u0026#34;pgaudit.log_parameter = true\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf echo \u0026#34;pgaudit.log_relation = true\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf echo \u0026#34;pgaudit.log_rows = true\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf echo \u0026#34;pgaudit.log_statement = true\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf # ========================================== # 5 启动集群 pg_ctl start -D $PG_HOME/data # ========================================== DROP EXTENSION pgaudit; CREATE EXTENSION pgaudit; CREATE UNLOGGED TABLE adt(c1 TEXT); CREATE TABLE t1 (c1 INT); INSERT INTO t1 VALUES (1); \\! ls $PG_HOME/data/log \\! tail $PG_HOME/data/log/ # ========================================== 1.2 tpcc优化 echo \u0026#34; shared_buffers = 200GB work_mem = 1GB maintenance_work_mem = 4GB effective_cache_size = 500GB wal_buffers = 1GB checkpoint_timeout = 55min \u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf show shared_buffers; show work_mem; show maintenance_work_mem; show effective_cache_size; show wal_buffers; show checkpoint_timeout; 1.3 安装pgaudit # 1 下载源码 wget https://codeload.github.com/pgaudit/pgaudit/tar.gz/refs/tags/1.6.2 -O pgaudit-1.6.2.tar.gz tar -zxvf pgaudit-1.6.2.tar.gz # 2 编译 cd pgaudit-1.6.2 make install USE_PGXS=1 PG_CONFIG=$PG_HOME/bin/pg_config # 3 验证编译成功 ll $PG_HOME/share/extension cat $PG_HOME/data/postgresql.conf | grep shared_preload_libraries # 4 开启日志功能 echo \u0026#34;logging_collector = on\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf echo \u0026#34;log_statement = all\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf # 5 开启 pgaudit echo \u0026#34;shared_preload_libraries = \u0026#39;pgaudit\u0026#39;\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf echo \u0026#34; pgaudit.log = \u0026#39;ALL\u0026#39;\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf -- 1 安装pgaudit CREATE EXTENSION pgaudit; -- 2 查看配置参数 SHOW pgaudit.log; -- ALL -- READ: SELECT -- WRITE: INSERT, UPDATE, DELETE -- ROLE -- DDL -- FUNCTION -- MISC -- MISC_SET SHOW pgaudit.role; SHOW pgaudit.log_level; -- 查看审计文件 SHOW log_directory; SHOW log_filename; 审计策略：客户 优先3.0\n2 pgaudit工作原理 E100 pgaudit性能测试（pg-14） 配置：arm 128核，内存700G，1000仓，调整内存相关guc参数，其他guc参数默认（导数据约1h） 测试（不开审计）：cpu 60%，30min，500并发，tpmc = 35.68w 测试（开pgaudit全审计）：cpu 100%，30min，500并发，tpmc = 1.02w 测试（开pgaudit全审计，优化：不通过ereport记录日志，记录到unlogged table中）：cpu 60%，30min，500并发，tmpc = 预计20w (有1点点提升空间) E100客户要求： 功能：E100审计所有SQL语句 性能：性能劣化不高（内部认为20-30%可能能接收） 交付：尽量6月上旬，内核开发约2周 E100审计方案： 4种方案：\n迁移G100审计功能（不建议） 功能：非常多 性能：开启1个审计线程，与pgaudit接近。开启48个审计线程，劣化20% 交付：工作量较大。G100与E100代码差异非常大，比如进程/线程架构。且G100审计代码：质量差、较分散、逻辑乱，不过2周应该可搞定 使用pgaudit（排除：性能非常低） 功能：支持DML，DDL，FUNCTION等，不支持用户登录、登出 性能：不开审计35.68w（cpu 60%），开审计1.05w (cpu 99%) 交付：工作量最小 优化pgaudit（日志存到TABLE，可花1天开发demo并验证性能） 功能：支持DML，DDL，FUNCTION等 日志收集：参考pgaudit 日志存储：UNLOGGED TABLE（备机是否需要审计日志？） 日志传输：Postgres进程 –\u0026gt; ShareBuffer –\u0026gt; BgWriter/CheckPointer进程 性能：不好评估，30%有点悬 交付：工作量适中 优化pgaudit（日志存到文件，可花2天开发demo并验证性能） 功能：支持DML，DDL，FUNCTION等 日志收集：参考pgaudit 日志存储：新增审计文件（发生故障时，比如突然断电，允许丢失小部分日志吗，比如8k） 日志传输：Postgres进程 –\u0026gt; 新增共享内存、信号量 –\u0026gt; 新增日志进程 性能：不好评估，比方案3好一些 交付：工作量适中，2周应该可以搞懂 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/4-1-pgaudit/","summary":"\u003ch1 id=\"1-使用pgaudt\"\u003e1 使用pgaudt\u003c/h1\u003e\n\u003ch2 id=\"11-常见sql\"\u003e1.1 常见SQL\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 1 ddl\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINDEX\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ei1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2 dml\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aaa\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;bbb\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;ccc\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aaa\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;bbb\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eUPDATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSET\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;ddd\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDELETE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 select\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 4 function\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e||\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;_oper\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003econcat\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;_func\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003econcat\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aaa\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;_func\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003econcat\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aaa\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;_func\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 5 multi\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eJOIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003et2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003et3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"1-安装pgaudit\"\u003e1 安装pgaudit\u003c/h1\u003e\n\u003ch2 id=\"11-安装postgresql\"\u003e1.1 安装postgresql\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 1 配置环境变量\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;export BUILD_ROOT=`pwd`\u0026#39;\u003c/span\u003e \u0026gt; pgenv\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;export PG_HOME=$BUILD_ROOT/install\u0026#39;\u003c/span\u003e \u0026gt;\u0026gt; pgenv\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;export PATH=\u0026#34;$PG_HOME/bin:$PATH\u0026#34;\u0026#39;\u003c/span\u003e \u0026gt;\u0026gt; pgenv\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003esource\u003c/span\u003e pgenv\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 2 下载源码\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ewget https://ftp.postgresql.org/pub/source/v14.18/postgresql-14.18.tar.gz\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etar -zxvf postgresql-14.18.tar.gz\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e postgresql-14.18.tar.gz\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 3 编译源码 (不开启debug模式，提高性能)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#./configure --prefix=$PG_HOME --enable-debug=yes\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e./configure --prefix\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e --enable-debug\u003cspan class=\"o\"\u003e=\u003c/span\u003eno --enable-cassert\u003cspan class=\"o\"\u003e=\u003c/span\u003eno\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emake -sj\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emake install -sj\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# ==========================================\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e \u003cspan class=\"nv\"\u003e$BUILD_ROOT\u003c/span\u003e/pg14/contrib/pgaudit\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emake install \u003cspan class=\"nv\"\u003eUSE_PGXS\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e \u003cspan class=\"nv\"\u003ePG_CONFIG\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/bin/pg_config\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e -\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# ==========================================\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 4 初始化集群\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003einitdb -D \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 4 配置集群\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# echo \u0026#34;port = 54000\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# echo \u0026#34;max_connections = 1000\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# ==========================================\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;logging_collector = on\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;shared_preload_libraries = \u0026#39;pgaudit\u0026#39;\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;pgaudit.log = \u0026#39;ALL\u0026#39;\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;pgaudit.log_catalog = true\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;pgaudit.log_client = true\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;pgaudit.log_parameter = true\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;pgaudit.log_relation = true\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;pgaudit.log_rows = true\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;pgaudit.log_statement = true\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# ==========================================\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 5 启动集群\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epg_ctl start -D \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# ==========================================\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eDROP EXTENSION pgaudit\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eCREATE EXTENSION pgaudit\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eCREATE UNLOGGED TABLE adt\u003cspan class=\"o\"\u003e(\u003c/span\u003ec1 TEXT\u003cspan class=\"o\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eCREATE TABLE t1 \u003cspan class=\"o\"\u003e(\u003c/span\u003ec1 INT\u003cspan class=\"o\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eINSERT INTO t1 VALUES \u003cspan class=\"o\"\u003e(\u003c/span\u003e1\u003cspan class=\"o\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"se\"\u003e\\!\u003c/span\u003e ls \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/log\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"se\"\u003e\\!\u003c/span\u003e tail \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/log/\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# ==========================================\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"12-tpcc优化\"\u003e1.2 tpcc优化\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003eshared_buffers = 200GB\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003ework_mem = 1GB\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003emaintenance_work_mem = 4GB\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003eeffective_cache_size = 500GB\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003ewal_buffers = 1GB\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003echeckpoint_timeout = 55min\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eshow shared_buffers\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eshow work_mem\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eshow maintenance_work_mem\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eshow effective_cache_size\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eshow wal_buffers\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eshow checkpoint_timeout\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"13-安装pgaudit\"\u003e1.3 安装pgaudit\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 1 下载源码\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ewget https://codeload.github.com/pgaudit/pgaudit/tar.gz/refs/tags/1.6.2 -O pgaudit-1.6.2.tar.gz\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etar -zxvf pgaudit-1.6.2.tar.gz\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 2 编译\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e pgaudit-1.6.2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emake install \u003cspan class=\"nv\"\u003eUSE_PGXS\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e \u003cspan class=\"nv\"\u003ePG_CONFIG\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/bin/pg_config\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 3 验证编译成功\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ell \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/share/extension\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecat \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/postgresql.conf \u003cspan class=\"p\"\u003e|\u003c/span\u003e grep shared_preload_libraries\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 4 开启日志功能\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;logging_collector = on\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;log_statement = all\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 5 开启 pgaudit\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;shared_preload_libraries = \u0026#39;pgaudit\u0026#39;\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34; pgaudit.log = \u0026#39;ALL\u0026#39;\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 1 安装pgaudit\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eEXTENSION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgaudit\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2 查看配置参数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSHOW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgaudit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elog\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- ALL\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- READ: SELECT\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- WRITE: INSERT, UPDATE, DELETE\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- ROLE\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- DDL\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- FUNCTION\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- MISC\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- MISC_SET\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSHOW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgaudit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"k\"\u003erole\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSHOW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epgaudit\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elog_level\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 查看审计文件\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSHOW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003elog_directory\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSHOW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003elog_filename\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col\u003e\n\u003cli\u003e审计策略：客户\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e优先3.0\u003c/p\u003e","title":"PostgreSQL 4-1 pgaudit"},{"content":" 摘要：从5个方面，介绍PostgreSQL身份认证特性：背景、原理、使用、设计、实现\n1 身份认证概述 1.1 非法访问风险 数据库进程\n数据库运行时，本质是一个服务器进程，在特定的主机上，监听特定端口。应用如果知道IP和端口，都可与数据库进程建立TCP连接，并进行数据交互，包括发送SQL语句、接收查询结果等。 数据泄露风险\n为避免非法用户访问数据库，构造特殊数据，造成数据损坏、数据泄露等问题，数据库接收应用建立TCP的请求，并成功建立TCP连接后，需先确认应用的身份是否合法，再接收应用的其他数据，比如接收SQL语句等。 1.2 身份认证机制 在信息系统中，身份认证是一种常见的机制，身份认证的概念较成熟，本文不详细介绍相关概念。身份认证分为标识与鉴别两个部分：\n标识：用户向系统声明自己的身份，系统标识用户 鉴别：系统验证用户提供的信息，确认用户是否是已标识的用户 按照认证因素，可将身份认证划分为3类：\n知识因素：用户知道某些秘密，比如口令、密码等 拥有因素：用户拥有某些实物，比如钥匙、证书、令牌等 生物因素：用户拥有某些特征，比如指纹、面部、虹膜、签名等 1.3 PostgrSQL的身份认证 PostgreSQL的认证方式有很多种，包括：密码认证、Ident认证、Peer认证、证书认证、LDAP认证等。本文仅介绍最常见的方案。\n在大部分场景中，PostgreSQL采用以下2层认证机制：\n主机认证： 标识：在PostgreSQL的配置文件中，配置IP白名单 鉴别：PostgreSQL与应用建立连接后，检查应用的IP是否在白名单内，判断应用是否合法 口令认证： 标识：PostgreSQL已存在的用户，创建新用户，为其设置用户信息，以及口令 备注：第一次安装PostgreSQL时，PostgreSQL要求用户创建初始用户 鉴别：在主机认证后，PostgreSQL先要求应用提供用户信息，再要求应用提供对应的口令，判断应用是否合法 2 身份认证的使用流程 2.1 基本流程 PostgreSQL中，从用户的角度观察，使用身份认证的流程可简单理解为：\n用户：已存在的用户使用CRATE USER {username} .. PASSWORD {password} ..语法，创建新用户并设置口令 数据库：数据库先对口令进行哈希，再存储口令的哈希值，目前的版本中，默认哈希算法为sha256算法，用户可通过GUC参数配置哈希算法类型 用户：用户与数据建立连接，将{username}与{password}的哈希值发送给数据库，数据库比较用户发送的哈希值与系统表中的哈希值，判断{password}是否合法 具体实现中，第3步的验证过程较为复杂，RFC5 802协议提供了一套安全的交互流程。后文介绍内部实现的详细流程。\n3 身份认证的实现 3.1 基于IP的身份认证 标识：访问者的IP\n鉴别：数据库遍历IP白名单，判断访问者IP是否在白名单中，如果在，则认为访问者合法，允许与数据建立TCP连接。\nPostmasterMain ServerLoop ConnCreate StreamConnection BackendStartup BackendRun PostgresMain InitPostgres PerformAuthentication ClientAuthentication hba_getauthmethod /* 从hba文件中，获取指定ip的认证方式 */ check_hba check_hostname check_ip /* 如果指定ip未获取到认证方式，则返回空 */ switch hba-\u0026gt;auth_method: /* 根据ip采用不同的认证方式 */ case uaReject: case uaImplicitReject: case uaGSS: case uaSSPI: case uaPeer: ... case uaMD5: case uaPassword: case uaCert: case uaTrust: ... 3.2 基于证书的身份认证 创建主体的语法示例如下：\nCREATE USER r1 PASSWORD \u0026#39;r1@12345\u0026#39;; 主体信息存在2个系统表中，pg_authid中存储了所有主体的oid\n-- 查询系统表 SELECT oid,rolname,rolpassword FROM pg_authid; oid | rolename | rolpassword ------+----------+-------------- 16384 | r1 | md5......... -- 查询视图与查询pg_authid结果一致 SELECT * FROM pg_roles; SELECT * FROM pg_user; opengauss身份认证 # 此处以未开启线程池为例 PostgresMain # 第一阶段：接受用户的密码，并进行一系列检查 InitBackendWorker InitSession CheckAuthentication PerformAuthentication port-\u0026gt;protocol_config-\u0026gt;fn_authenticate ClientAuthentication # 1. 从pg_hba.conf中，读取password校验方式 hba_getauthmethod sendAuthRequest # 2. 接收客户端的password，检查password是否正确 recv_and_check_password_packet crypt_verify # 3. 从系统表pg_user_status中，获取rolstatus字段，判断用户是否被锁 GetAccountLockedStatus SearchSysCache1(\u0026#39;pg_user_status\u0026#39;) # 4. 无论密码正确与否，更新与锁定账号相关的参数 if role is lock or unlock: TryUnlockAccount GetPasswordTimeOfTuple transform \u0026#39;password_lock_time\u0026#39; UpdateUnlockAccountTuples # 5. 如果密码失败次数较多，锁定账户 if passwrong: if master: TryLockAccount if \u0026gt; \u0026#39;failed_login_attempts\u0026#39; tableam_tops_modify_tuple(\u0026#39;pg_user_status\u0026#39;) elif standby: UpdateFailCountToHashTable if \u0026gt; \u0026#39;failed_login_attempts\u0026#39; lock # 6. 如果密码正确，检查密码有效期（仅vastbase有此函数） checkPasswordEffect getLeftEffectSpan transform \u0026#39;password_effect_time\u0026#39; if leftday \u0026lt; 0: \u0026#39;ERROR: password expired\u0026#39; # 第二阶段：循环接收用户的其他数据，比如SQL语句 for (;;) ReadCommand # 此处，每接收一条客户端的消息，都会检查一次 session_timeout # 如果开启profile，此处需要缓存该用户的profile idle_time参数，否则，每次都从profile系统表中读取，对性能影响较大 # 理论上，如果无用户更新profile idle_time参数，一个连接缓存一次即可，即一个连接仅需读取一次系统表 if \u0026gt; \u0026#39;session_timeout\u0026#39;: \u0026#39;ERROR: timeout\u0026#39; exec_simple_query(\u0026#39;SQL\u0026#39;) SetSessionAuthorization SetSessionUserId SetUserIdAndSecContext ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/4-1-authentication/","summary":"\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003e摘要\u003c/strong\u003e：从5个方面，介绍PostgreSQL身份认证特性：背景、原理、使用、设计、实现\u003c/p\u003e\u003c/blockquote\u003e\n\u003ch1 id=\"1-身份认证概述\"\u003e1 身份认证概述\u003c/h1\u003e\n\u003ch2 id=\"11-非法访问风险\"\u003e1.1 非法访问风险\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e数据库进程\u003cbr\u003e\n数据库运行时，本质是一个服务器进程，在特定的主机上，监听特定端口。应用如果知道IP和端口，都可与数据库进程建立TCP连接，并进行数据交互，包括发送SQL语句、接收查询结果等。\u003c/li\u003e\n\u003cli\u003e数据泄露风险\u003cbr\u003e\n为避免非法用户访问数据库，构造特殊数据，造成数据损坏、数据泄露等问题，数据库接收应用建立TCP的请求，并成功建立TCP连接后，需先确认应用的身份是否合法，再接收应用的其他数据，比如接收SQL语句等。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"12-身份认证机制\"\u003e1.2 身份认证机制\u003c/h2\u003e\n\u003cp\u003e在信息系统中，身份认证是一种常见的机制，身份认证的概念较成熟，本文不详细介绍相关概念。身份认证分为标识与鉴别两个部分：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e标识：用户向系统声明自己的身份，系统标识用户\u003c/li\u003e\n\u003cli\u003e鉴别：系统验证用户提供的信息，确认用户是否是已标识的用户\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e按照认证因素，可将身份认证划分为3类：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e知识因素：用户知道某些秘密，比如口令、密码等\u003c/li\u003e\n\u003cli\u003e拥有因素：用户拥有某些实物，比如钥匙、证书、令牌等\u003c/li\u003e\n\u003cli\u003e生物因素：用户拥有某些特征，比如指纹、面部、虹膜、签名等\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"13-postgrsql的身份认证\"\u003e1.3 PostgrSQL的身份认证\u003c/h2\u003e\n\u003cp\u003ePostgreSQL的认证方式有很多种，包括：密码认证、Ident认证、Peer认证、证书认证、LDAP认证等。本文仅介绍最常见的方案。\u003c/p\u003e\n\u003cp\u003e在大部分场景中，PostgreSQL采用以下2层认证机制：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e主机认证：\n\u003cul\u003e\n\u003cli\u003e标识：在PostgreSQL的配置文件中，配置IP白名单\u003c/li\u003e\n\u003cli\u003e鉴别：PostgreSQL与应用建立连接后，检查应用的IP是否在白名单内，判断应用是否合法\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e口令认证：\n\u003cul\u003e\n\u003cli\u003e标识：PostgreSQL已存在的用户，创建新用户，为其设置用户信息，以及口令\n\u003cul\u003e\n\u003cli\u003e备注：第一次安装PostgreSQL时，PostgreSQL要求用户创建初始用户\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e鉴别：在主机认证后，PostgreSQL先要求应用提供用户信息，再要求应用提供对应的口令，判断应用是否合法\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-身份认证的使用流程\"\u003e2 身份认证的使用流程\u003c/h1\u003e\n\u003ch2 id=\"21-基本流程\"\u003e2.1 基本流程\u003c/h2\u003e\n\u003cp\u003ePostgreSQL中，从用户的角度观察，使用身份认证的流程可简单理解为：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e用户：已存在的用户使用\u003ccode\u003eCRATE USER {username} .. PASSWORD {password} ..\u003c/code\u003e语法，创建新用户并设置口令\u003c/li\u003e\n\u003cli\u003e数据库：数据库先对口令进行哈希，再存储口令的哈希值，目前的版本中，默认哈希算法为sha256算法，用户可通过GUC参数配置哈希算法类型\u003c/li\u003e\n\u003cli\u003e用户：用户与数据建立连接，将\u003ccode\u003e{username}\u003c/code\u003e与\u003ccode\u003e{password}\u003c/code\u003e的哈希值发送给数据库，数据库比较用户发送的哈希值与系统表中的哈希值，判断\u003ccode\u003e{password}\u003c/code\u003e是否合法\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e具体实现中，第3步的验证过程较为复杂，RFC5 802协议提供了一套安全的交互流程。后文介绍内部实现的详细流程。\u003c/p\u003e\n\u003ch1 id=\"3-身份认证的实现\"\u003e3 身份认证的实现\u003c/h1\u003e\n\u003ch2 id=\"31-基于ip的身份认证\"\u003e3.1 基于IP的身份认证\u003c/h2\u003e\n\u003cp\u003e标识：访问者的IP\u003cbr\u003e\n鉴别：数据库遍历IP白名单，判断访问者IP是否在白名单中，如果在，则认为访问者合法，允许与数据建立TCP连接。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ePostmasterMain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eServerLoop\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eConnCreate\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eStreamConnection\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eBackendStartup\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eBackendRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003ePostgresMain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eInitPostgres\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003ePerformAuthentication\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eClientAuthentication\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003ehba_getauthmethod\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 从hba文件中，获取指定ip的认证方式 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003echeck_hba\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                        \u003cspan class=\"n\"\u003echeck_hostname\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                        \u003cspan class=\"n\"\u003echeck_ip\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                        \u003cspan class=\"cm\"\u003e/* 如果指定ip未获取到认证方式，则返回空 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"k\"\u003eswitch\u003c/span\u003e \u003cspan class=\"n\"\u003ehba\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"nl\"\u003eauth_method\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 根据ip采用不同的认证方式 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003euaReject\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003euaImplicitReject\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003euaGSS\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003euaSSPI\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003euaPeer\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"p\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003euaMD5\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003euaPassword\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003euaCert\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"nl\"\u003euaTrust\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"p\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"32-基于证书的身份认证\"\u003e3.2 基于证书的身份认证\u003c/h2\u003e\n\u003cp\u003e创建主体的语法示例如下：\u003c/p\u003e","title":"数据库安全 1 身份认证"},{"content":" 摘要：从5个方面，介绍openGauss审计特性：背景、原理、使用、设计、实现\n1 审计的背景 1.1 审计的原理 在使用数据库存取数据的大部分场景中，数据库具有以下特点：\n对象多：一个数据库集群中有多个database对象，1个database对象中有多个schema对象，1个schema对象中有多个table、index等对象 用户多：一个数据库中，有多个用户，每个用户可访问的数据库对象不同 应用多：多个应用将数据存储在同一数据库集群中，并同时访问数据库集群 操作多：数据库提供丰富的功能，包括DDL、DML、DCL、运维等 运行久：一个数据库集群，可能会保持数十年运行 审计的主要目的，使记录数据运行过程中发生了哪些事件。审计的3要素是：\n主体：一般指数据库用户 客体：一般指数据库对象，包括：集群、用户、连接、数据对象（database、schema、table、index、function等） 操作：主体对客体的操作，比如某个用户访问了某个表 1.2 审计的目的 审计具有以下重要意义：\n攻击检测：通过检查审计日志，可判断是否发生网络安全攻击事件 例行维护：通过检查审计日志，可跟踪对某个对象的访问信息 故障检测：当数据库出现故障是，协助快速定位问题 合法合规：《网络安全法》等法律法规与表中中，要求应用具备审计功能 … 1.3 审计的功能 审计功能包含以下3个部分：\n设置审计范围：通过数据库配置参数，或者数据库语法，定义哪些对象需要被审计 设置审计存储：通过数据库配置参数，定义审计日志如何存储 生成审计日志：数据库运行过程中，访问某个对象时，记录访问信息 管理审计日志：查询，删除，归档审计日志 1.4 oracle审计 oracle审计的发展：\n- oracle 8i及更早：支持传统审计\n- oracle 12c：新增支持统一审计\n- oracle 23ai：不支持传统审计，仅支持统一审计\noracle统一审计的使用：\n-- 1 创建审计策略 CREATE AUDIT POLICY ap1 PRIVILEGES CREATE TABLE, ALTER USER -- privilege 子句，记录所有使用CreateTable, AlterUser权限的操作 ACTIONS SELECT,INSERT,UPDATE ON t1 -- aciton 子句，记录所有对表t1执行SELECT,INSERT,UPDATE的操作 ROLES r1; -- role 子句，记录所有使用r1角色的操作 -- 2 启用审计策略 AUDIT POLICY ap1; -- 3 查看审计日志 SELECT * FROM UNIFIED_AUDIT_TRAIL; -- DBA_COMMON_AUDIT_TRAIL, DBA_AUDIT_SESSION, DBA_AUDIT_OBJECT, DBA_FGA_AUDIT_TRAIL SELECT * FROM DBA_AUDIT_TRAIL; os_username | username | userhost | terminal | timestamp | owner | obj_name | action | action_name | ------------+----------+----------+----------+-----------+-------+----------+--------+-------------+ | new_owner | new_name | obj_privilege | sys_privilege | admin_option | grantee | audit_option | ses_actions | +----------+----------+---------------+---------------+--------------+---------+--------------+-------------+ logoff_time | logoff_lread | logoff_pwrite | logoff_dlock | comment_text | sessionid | entryid | statementid | returncode | +-----------+--------------+---------------+--------------+--------------+-----------+---------+-------------+------------+ | priv_used | client_id | econtext_id | session_cpu | extended_timestamp | proxy_sessionid | global_uid | instance_number | +-----------+-----------+-------------+-------------+--------------------+-----------------+------------+-----------------+ os_process | transactionid | scn | sql_bind | sql_text | obj_edition_name | dbid | rls_info | current_user | +----------+---------------+-----+----------+----------+------------------+------+----------+--------------+ 其中，可设置的权限、操作等范围如下：\n-- 所有的 PRIVILEGES SELECT NAME FROM SYSTEM_PRIVILEGE_MAP; -- 所有的 ACTION object | actions ---------------------+-------------------------------------------------------------------------------------------------- Directory | AUDIT, GRANT, READ Function | AUDIT, EXECUTE, GRANT Java schema objects | AUDIT, EXECUTE, GRANT Library | EXECUTE, GRANT Materialized views | ALTER, AUDIT, COMMENT, DELETE, INDEX, INSERT, LOCK, SELECT, UPDATE Mining Model | AUDIT, COMMENT, GRANT, RENAME, SELECT Object type | ALTER, AUDIT, GRANT Package | AUDIT, EXECUTE, GRANT Procedure, triggers | AUDIT, EXECUTE, GRANT Sequence | ALTER, AUDIT, GRANT, SELECT Table | ALTER, AUDIT, COMMENT, DELETE, FLASHBACK, GRANT, INDEX, INSERT, LOCK, MERGE, RENAME, SELECT, UPDATE Table or view column | ALL, ALTER, AUDIT, COMMENT, DELETE, GRANT, INDEX, INSERT, SELECT, UPDATE View | AUDIT, COMMENT, DELETE, FLASHBACK, GRANT, INSERT, LOCK, MERGE, RENAME, SELECT, UPDATE -- 完整的 CREATE AUDIT POLICY 语法 CREATE AUDIT POLICY policy_name { {privilege_audit_clause [action_audit_clause ] [role_audit_clause ]} | { action_audit_clause [role_audit_clause ] } | { role_audit_clause } } [WHEN audit_condition EVALUATE PER {STATEMENT|SESSION|INSTANCE}] [ONLY TOPLEVEL] [CONTAINER = {CURRENT | ALL}]; oracle 23官方文档审计功能: https://docs.oracle.com/en/database/oracle/oracle-database/23/dbseg/introduction-to-auditing.html#GUID-94381464-53A3-421B-8F13-BD171C867405\nhttps://docs.oracle.com/en/database/oracle/oracle-database/23/refrn/UNIFIED_AUDIT_TRAIL.html 1.5 openGauss审计 opengauss审计的分类：\n按照审计粒度，可将openGauss的审计功能分为以下两类：\n传统审计：记录对某类客体的操作。在GUC参数中，可设置是否审计某一类对象。 统一审计：记录对某个客体的操作。通过SQL语法，定义是否审计某一个客体（表、角色、列） opengauss传统审计：\nopengauss统一审计：\n3 传统审计 3.1 传统审计的用法 一、设置审计范围 开启传统审计功能\n默认情况下，传统审计功能是开启状态\nshow audit_enable; 查看传统审计范围\n通过以下SQL语句，可查询是否开启对某类对象的审计功能：\nSELECT name,setting FROM pg_settings WHERE name LIKE \u0026#39;%audit%\u0026#39;; -- 默认输出： name | setting -----------------------------+---------- audit_copy_exec | 1 audit_data_format | binary audit_database_process | 1 audit_directory | pg_audit audit_dml_state | 0 audit_dml_state_select | 0 audit_enabled | on audit_file_remain_threshold | 1048576 audit_file_remain_time | 90 audit_function_exec | 0 audit_grant_revoke | 1 audit_login_logout | 7 audit_resource_policy | on audit_rotation_interval | 1440 audit_rotation_size | 10240 audit_set_parameter | 0 audit_space_limit | 1048576 audit_system_function_exec | 0 audit_system_object | 67121159 audit_thread_num | 1 audit_user_locked | 1 audit_user_violation | 0 audit_xid_info | 0 full_audit_users | no_audit_client | (25 rows) 上述列表中，审计相关配置参数较多，可分为2类：\n管理审计日志文件：比如文件目录、生成新文件的条件等 管理审计对象范围：比如是否审计某一类对象 上述表中，与审计对象类相关的参数，功能如下：\n参数名 主体 客体 操作 audit_login_logout 用户 集群 登录、退出 audit_database_process 用户 集群 启动、停止、恢复、切换 audit_user_locked 用户 用户 锁定、解锁 audit_user_violation 用户 多种对象 越权访问 audit_grant_revoke 用户 用户 授权、收权 full_audit_users 用户 用户 各类操作 no_audit_client - - 不审计的客户端名单 audit_system_object 用户 DATABASE / SCHEMA / USER / DATA SOURCE / SQL PATCH CREATE / ALTER / DROP audit_dml_state 用户 TABLE INSERT / UPDATE / DELETE audit_dml_state_select 用户 TABLE SELECT audit_copy_exec 用户 TABLE COPY audit_function_exec 用户 FUNCTION EXECUTE audit_system_function_exec - - 不审计的系统函数名单 audit_set_parameter 用户 SET 各种操作 audit_xid_info 用户 XID 申请 与审计对象类相关的参数，参数的取值是数字，是一个整数，整数有点抽象，将整数转换为2进制后，上述数字的值如下表：\n10进制 2进制 7 111 1440 10110100000 10240 10100000000000 67121159 100000000000011000000000111 参数取值解释为，在一个对象上有很多操作，比如，对与表而言，有INSERT / UPDATE / DELETE等操作，2进制中1个bit代表1种操作，针对不同对象，每个bit代表的操作类型也不同，具体某个参数的某个bit表示什么操作，还得查看参数的具体解释。bit=0，表示不审计该操作，bit=1，表示要审计该操作。\n二、设置审计存储 设置审计日志存储策略\nSELECT name,setting FROM pg_settings WHERE name IN ( \u0026#39;audit_directory\u0026#39;, \u0026#39;audit_resource_policy\u0026#39;, \u0026#39;audit_space_limit\u0026#39;, \u0026#39;audit_file_remain_time\u0026#39;, \u0026#39;audit_file_remain_threshold\u0026#39;); -- 默认结果 name | setting ----------------------------+---------- audit_directory | pg_audit -- 数据库运行日志的相对路径 audit_file_remain_threshold | 1048576 -- 单位：个文件 audit_file_remain_time | 90 -- 单位：天 audit_resource_policy | on audit_space_limit | 1048576 -- 单位：M (5 rows) 查看审计日志的存储路径：\nSELECT setting FROM pg_settings WHERE name in (\u0026#39;data_directory\u0026#39;, \u0026#39;audit_directory\u0026#39;); -- 示例 setting ----------------------------- pg_audit /home/shenkun/install/data1 查看审计文件：\ncd /home/shenkun/install/data1 ls # 输出 0_adt 1_adt 2_adt done index_table_new 其中，0_adt，1_adt, ..为审计日志文件，index_table_new为审计索引文件，后文介绍文件结构\n三、生成审计日志 当数据库中某些事件发生时：\u0026lt;主体\u0026gt;\u0026lt;操作\u0026gt;\u0026lt;客体\u0026gt;，比如发生事件：\u0026lt;用户\u0026gt;\u0026lt;登录\u0026gt;\u0026lt;集群\u0026gt;，如果audit_login_logout参数取值为1，此时，数据库会自动记录审计日志至审计文件中\n四、管理审计日志 查询审计日志\n-- 查询某个时间段内的日志 SELECT pg_query_audit(\u0026#39;2024-07-12 08:00:00\u0026#39;,\u0026#39;2024-07-12 17:00:00\u0026#39;); -- 查询过去10秒的日志 SELECT pg_query_audit(NOW() - INTERVAL \u0026#39;10 seconds\u0026#39;, NOW()); 查询结果示例：\n------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- (\u0026#34;2025-02-11 12:17:12+08\u0026#34;,login_failed,failed,24576,u1,postgres,[unknown]@[local],postgres,\u0026#34;login db(postgres)failed,authentication for user(u1)failed, SSL=off\u0026#34;,node1,139628213434112@792562632014514,5432,null,2dae83e745323eeb280879f49a81cc9ed930009408681c43dfe12f56d7a33831,t) (\u0026#34;2025-01-22 18:31:21+08\u0026#34;,login_success,ok,10,shenkun,postgres,gs_clean@127.0.0.1,postgres,\u0026#34;login db(postgres) success,the current user is:shenkun SSL=off\u0026#34;,node1,139735762728704@790857081014516,5432,41322,cabcf2afc91702332a0dfad789948020ec9a382efdcb2d13b5f2cea9d826f777,t) 删除审计日志\nSELECT pg_delete_audit(\u0026#39;2024-07-12 08:00:00\u0026#39;,\u0026#39;2024-07-12 17:00:00\u0026#39;); 3.2 传统审计的架构 传统审计的线程架构，可简单分为3个：\n主线程：即Postmaster线程，负责启动工作线与审计线程 工作线程：处理用户的请求，如果处理过程中涉及关键资源，比如关键数据库对象，则生成审计日志 审计线程：收集工作线程的审计日志，并将审计日志存储到磁盘 工作线程与应用建立连接后，会进行身份认证，紧接着接收并执行用户的执行请求，在这整个过程中，多个阶段都会产生审计日志。整体架构如下：\n传统审计的工作流程如下：\n配置审计参数：用户通过GUC参数，配置以下功能： 是否开启传统审计功能 审计线程的数据 审计文件的目录、名称、轮换策略等 读取审计参数：Postmaster线程，从GUC参数中读取所有与审计相关的参数 启动审计线程：Postmaster线程，在接收应用的请求之前，启动多个审计线程 等待审计日志：审计线程，启动后，等待工作线程发送审计日志 处理应用请求：工作线程，接收用户请求，比如各类SQL语句、运维操作等，处理应用请求 生成审计日志：工作线程，处理应用请求后，会根据请求类型、处理结果等生成审计日志 发送审计日志：工作线程，工作线程封装审计日志，并通过管道将其发送给审计线程 接收审计日志：审计线程，接收工作线程发送的审计日志 存储审计日志：审计线程，将审计日志存储至磁盘 3.3 传统审计的源码 本章先从功能实现的角度梳理审计日志生成到存储的流程。\n一、主线程：启动审计线程 PostmasterMain # 阶段一、从配置文件中读取所有GUC参数 InitializeGUCOptions # 读取包括audit_enable， audit_thread_num等所有审计相关的GUC参数 # 阶段二、在接收应用的SQL请求之前，先启动多个审计线程 if \u0026#39;开启GUC audit_enable\u0026#39; pgaudit_start_all # 依次启动多个审计线程 for \u0026#39;识别GUC audit_thread_num\u0026#39; pgaudit_start # 启动1个审计线程 initialize_util_thread(AUDITOR) initialize_thread gs_thread_create_ex InternalThreadFunc GetThreadEntry GaussdbThreadGate GaussDbThreadMain(AUDITOR) PgAuditorMain # 审计线程开始运行 for (): WaitLatchOrSocket read(pipe) # 不停通过管道接收 其他线程发送的审计日志 fwrite # 不停落盘 接收的审计日志 ServerLoop # 阶段三、接收并处理应用发送的SQL语句 二、工作线程：收集审计事件 上文提到，openGauss会审计多种事件，比如用户登录集群，用户操作数据对象等。在每个事件发生的地方，需记录审计日志，事件相关代码较分散，因此，审计相关的代码也会较分散。审计的代码，没有统一的命名规律，不容易一次性找到全部审计代码。\n通过审计事件类型，查找审计代码较方便，审计事件有40种类型。\n根据审计事件分类：\n# 用户操作集群 AUDIT_LOGIN_SUCCESS, AUDIT_LOGIN_FAILED, AUDIT_USER_LOGOUT, AUDIT_SYSTEM_START, AUDIT_SYSTEM_STOP, AUDIT_SYSTEM_RECOVER, AUDIT_SYSTEM_SWITCH # 用户操作用户 AUDIT_LOCK_USER, AUDIT_UNLOCK_USER, AUDIT_GRANT_ROLE, UDIT_REVOKE_ROLE, UDIT_USER_VIOLATION # 用户操作对象（DDL类） AUDIT_DDL_DATABASE, AUDIT_DDL_DIRECTORY, AUDIT_DDL_TABLESPACE, AUDIT_DDL_SCHEMA, AUDIT_DDL_USER, AUDIT_DDL_TABLE, AUDIT_DDL_INDEX, AUDIT_DDL_VIEW AUDIT_DDL_TRIGGER, AUDIT_DDL_FUNCTION AUDIT_DDL_RESOURCEPOOL, AUDIT_DDL_WORKLOAD, AUDIT_DDL_SERVERFORHADOOP, AUDIT_DDL_DATASOURCE, AUDIT_DDL_NODEGROUP AUDIT_DDL_SYNONYM, AUDIT_DDL_TYPE, AUDIT_DDL_TEXTSEARCH，AUDIT_DDL_SEQUENCE, AUDIT_DDL_PACKAGE, AUDIT_DDL_MODEL, AUDIT_DDL_PUBLICATION_SUBSCRIPTION, AUDIT_DDL_FOREIGN_DATA_WRAPPER, AUDIT_DDL_SQL_PATCH, AUDIT_DDL_EVENT AUDIT_POLICY_EVENT, MASKING_POLICY_EVENT, AUDIT_DDL_ROWLEVELSECURITY,AUDIT_DDL_KEY # 用户操作对象（DML类） AUDIT_DML_ACTION, AUDIT_DML_ACTION_SELECT, AUDIT_FUNCTION_EXEC, AUDIT_SYSTEM_FUNCTION_EXEC AUDIT_COPY_TO, AUDIT_COPY_FROM # 审计线程内部事件 AUDIT_INTERNAL_EVENT # 用户配置参数 AUDIT_SET_PARAMETER, AUDIT_DDL_GLOBALCONFIG # 其他 SECURITY_EVENT 但是，审计事件类型也很多，按照执行流程，还可继续分为以下3类，其中，DDL和DML类的大部分审计日志收集点比较集中：\n根据功能分类 DDL类 DML类 集群管理类 在代码中，审计事件较多，梳理工作量大，意义小，因此，此处仅介绍几个经典收集点：\n用户操作集群（集群管理类）\n# 记录 \u0026lt;用户操作集群\u0026gt; 事件的代码有好多处，此处为比较经典的调用栈 # user: gsql -h {host} -p {port} -d {database} -U {user} -W {password} PostgresMain InitBackendWorker InitSession CheckAuthentication PerformAuthentication fn_authenticate ClientAuthentication recv_and_check_password_packet recv_password_packet # 首先，进行身份认证 crypt_verify # 然后，记录身份认证结果 pgaudit_user_login audit_report(\u0026#39;audit type\u0026#39;) # 入参为 AUDIT_LOGIN_SUCCESS 或 AUDIT_LOGIN_FAILED # 该函数内部逻辑后面介绍 用户操作对象（DDL类）\n# 记录 \u0026lt;用户操作对象\u0026gt; 事件的代码也很多，此处选择比较经典的调用栈 \u0026lt;用户CREATE TABLE\u0026gt; exec_simple_query(\u0026#34;CREATE TABLE ... / ...\u0026#34;) PortalRun PortalRunMulti PortalRunUtility # 执行 DDL 的主函数 ProcessUtility ProcessUtility_hook pgaudit_ProcessUtility # 首先，进行标准的DDL处理 standard_ProcessUtility # 然后，在收集DDL类型、DDL执行结果等内容 pgaudit_ddl_table pgaudit_ddl_database_object(\u0026#39;audit type\u0026#39;) # 入参为 AUDIT_DDL_TABLE pgaudit_ddl_database_object pgaudit_store_auditstat audit_report(\u0026#39;audit type\u0026#39;) 用户操作对象（DML类）\nexec_simple_query(\u0026#34;INSERT INTO t1 VALUES ... / UPDATE ... / ...\u0026#34;) PortalRun PortalRunMulti ProcessQuery # 执行 DML 的主函数 # 首先，进行标准的DML执行 ExecutorRun ExecutorEnd ExecutorEnd_hook pgaudit_ExecutorEnd # 然后，在执行结束时，收集DML类型、DML执行结果等内容 pgaudit_dml_table pgaudit_store_auditstat(\u0026#39;audit type\u0026#39;) # 入参为 AUDIT_DML_ACTION audit_report(\u0026#39;audit type\u0026#39;) standard_ExecutorEnd 由此可见，收集日志的线程，通常是各个业务线程。\n三、工作线程：发送审计日志 上文提到，业务线程收集审计日志后，统一调用audit_report处理，audit_report函数将审计日志发送审计线程，函数执行流程如下：\n... # 业务线程 业务代码 audit_report # 只封装、发送传统审计日志 # 检查日志内容 audit_status_check_ok audit_type_validcheck audit_get_clientinfo audit_check_client_blacklist # 封装日志内容 initStringInfo appendStringField appendStringField ... # 发送日志内容 write_pipe_chunks # 通过管道，发送传统审计日志给其他线程 write(pipe, \u0026#39;审计日志\u0026#39;) elif .. # 仅记录由审计线程本身产生的审计日志 pgaudit_write_file fwrite(\u0026#39;audit file\u0026#39;) # 文件目录：GUC参数 audit_directory 的值 fflush elif .. # 不知道干嘛 pgaudit_write_policy_audit_file fwrite(\u0026#39;policy audit file\u0026#39;) # 文件目录：GUC参数 audit_directory 的值 fflush 四、审计线程：接收审计日志 审计线程接收与处理审计日志的逻辑如下：\nPgAuditorMain for (): pgaudit_send_data_to_elastic # 发送日志给 elastic search WaitLatchOrSocket # 如果接收到业务线程向管道写数据的行为，则读取审计日志 read(pipe, \u0026#39;审计日志\u0026#39;) process_pipe_input pgaudit_write_file fwrite(\u0026#39;audit file\u0026#39;) # 文件目录：GUC参数 audit_directory 的值 flush_pipe_input 3.5 传统审计的事件完整列表 auditfile_init audit_report(AUDIT_INTERNAL_EVENT, AUDIT_OK) auditfile_rotate audit_report(AUDIT_INTERNAL_EVENT, AUDIT_OK) pgaudit_cleanup audit_report(AUDIT_INTERNAL_EVENT, AUDIT_OK) plpgsql_exec_error_callback audit_report(AUDIT_FUNCTION_EXEC, AUDIT_FAILED) auditExecPLpgSQLFunction audit_report(AUDIT_FUNCTION_EXEC, AUDIT_OK / AUDIT_FAILED) auditExecAnonymousBlock audit_report(AUDIT_FUNCTION_EXEC, AUDIT_OK) AuditPlpythonFunction audit_report(AUDIT_FUNCTION_EXEC, AUDIT_OK / AUDIT_FAILED) DoCopy audit_report(AUDIT_COPY_FROM, AUDIT_OK) audit_report(AUDIT_COPY_TO, AUDIT_OK) inline_function audit_report(AUDIT_FUNCTION_EXEC, AUDIT_OK) pgaudit_system_recovery_ok audit_report(AUDIT_SYSTEM_RECOVER, AUDIT_OK) pgaudit_system_start_ok audit_report(AUDIT_SYSTEM_START， AUDIT_OK) pgaudit_user_login audit_report(AUDIT_LOGIN_FAILED, AUDIT_OK / AUDIT_FAILED) audit_report(AUDIT_LOGIN_SUCCESS, AUDIT_OK / AUDIT_FAILED) pgaudit_user_logout audit_report(AUDIT_USER_LOGOUT, AUDIT_OK) pgaudit_system_stop_ok audit_report(AUDIT_SYSTEM_STOP, AUDIT_OK) pgaudit_system_switchover_ok audit_report(AUDIT_SYSTEM_SWITCH, AUDIT_OK) pgaudit_user_no_privileges audit_report(AUDIT_USER_VIOLATION, AUDIT_FAILED) pgaudit_lock_or_unlock_user audit_report(AUDIT_LOCK_USER, AUDIT_OK / AUDIT_FAILED) audit_report(AUDIT_UNLOCK_USER, AUDIT_OK / AUDIT_FAILED) pgaudit_process_set_parameter audit_report(AUDIT_SET_PARAMETER, AUDIT_OK) audit_system_function audit_report(AUDIT_SYSTEM_FUNCTION_EXEC, AUDIT_OK / AUDIT_FAILED) auditExecSQLFunction audit_report(AUDIT_FUNCTION_EXEC, AUDIT_OK / AUDIT_FAILED) pgaudit_ddl_database_object(audit_type) // 此处audit_type调用点较多 pgaudit_store_auditstat audit_report(audit_type, AUDIT_OK / AUDIT_FAILED) 调用pgaudit_ddl_database_object的函数\npgaudit_ddl_table pgaudit_ddl_database_object(AUDIT_DDL_TABLE, AUDIT_OK) pgaudit_ddl_type pgaudit_ddl_database_object(AUDIT_DDL_TYPE, AUDIT_OK) pgaudit_ddl_user pgaudit_ddl_database_object(AUDIT_DDL_USER, AUDIT_OK) pgaudit_ddl_model pgaudit_ddl_database_object(AUDIT_DDL_MODEL, AUDIT_OK) pgaudit_ddl_view pgaudit_ddl_database_object(AUDIT_DDL_VIEW, AUDIT_OK) pgaudit_ddl_event pgaudit_ddl_database_object(AUDIT_DDL_EVENT, AUDIT_OK) pgaudit_ddl_matview pgaudit_ddl_database_object(AUDIT_DDL_VIEW, AUDIT_OK) pgaudit_ddl_database pgaudit_ddl_database_object(AUDIT_DDL_DATABASE, AUDIT_OK) pgaudit_ddl_directory pgaudit_ddl_database_object(AUDIT_DDL_DIRECTORY, AUDIT_OK) pgaudit_ddl_schema pgaudit_ddl_database_object(AUDIT_DDL_SCHEMA, AUDIT_OK) pgaudit_ddl_tablespace pgaudit_ddl_database_object(AUDIT_DDL_TABLESPACE, AUDIT_OK) pgaudit_ddl_index pgaudit_ddl_database_object(AUDIT_DDL_INDEX, AUDIT_OK) pgaudit_ddl_trigger pgaudit_ddl_database_object(AUDIT_DDL_TRIGGER, AUDIT_OK) pgaudit_ddl_sequence pgaudit_ddl_database_object(AUDIT_DDL_SEQUENCE, AUDIT_OK) pgaudit_ddl_function pgaudit_ddl_database_object(AUDIT_DDL_FUNCTION, AUDIT_OK) pgaudit_ddl_package pgaudit_ddl_database_object(AUDIT_DDL_PACKAGE, AUDIT_OK) pgaudit_ddl_resourcepool pgaudit_ddl_database_object(AUDIT_DDL_RESOURCEPOOL, AUDIT_OK) pgaudit_alter_globalconfig pgaudit_ddl_database_object(AUDIT_DDL_GLOBALCONFIG, AUDIT_OK) pgaudit_drop_globalconfig pgaudit_ddl_database_object(AUDIT_DDL_GLOBALCONFIG, AUDIT_OK) pgaudit_ddl_serverforhardoop pgaudit_ddl_database_object(AUDIT_DDL_SERVERFORHADOOP, AUDIT_OK) pgaudit_ddl_weak_password pgaudit_ddl_database_object(AUDIT_DDL_TABLE, AUDIT_OK) pgaudit_ddl_full_encryption_key pgaudit_ddl_database_object(AUDIT_DDL_KEY, AUDIT_OK) pgaudit_ddl_datasource pgaudit_ddl_database_object(AUDIT_DDL_DATASOURCE, AUDIT_OK) pgaudit_ddl_nodegroup pgaudit_ddl_database_object(AUDIT_DDL_NODEGROUP, AUDIT_OK) pgaudit_ddl_rowlevelsecurity pgaudit_ddl_database_object(AUDIT_DDL_ROWLEVELSECURITY, AUDIT_OK) pgaudit_ddl_synonym pgaudit_ddl_database_object(AUDIT_DDL_SYNONYM, AUDIT_OK) pgaudit_ddl_textsearch pgaudit_ddl_database_object(AUDIT_DDL_TEXTSEARCH, AUDIT_OK) pgaudit_ddl_publication_subscription pgaudit_ddl_database_object(AUDIT_DDL_PUBLICATION_SUBSCRIPTION, AUDIT_OK) pgaudit_ddl_fdw pgaudit_ddl_database_object(AUDIT_DDL_FOREIGN_DATA_WRAPPER, AUDIT_OK) pgaudit_ddl_sql_patch pgaudit_ddl_database_object(DDL_SQL_PATCH, AUDIT_OK) pgaudit_process_set_parameter pgaudit_ddl_database_object(AUDIT_SET_PARAMETER, AUDIT_OK) pgaudit_process_drop_objects pgaudit_ddl_database_object(xxx, AUDIT_OK) 3.6 传统审计的日志存储 一、审计日志记录格式 审计日志格式\n每条审计日志的标准格式如下：\n# 竖着看 +-------------------+--------------------+-------------------+ | | | char[2] signature | | | | uint16 version | | | | uint16 fields | | | AuditMsgHdr hdr | uint16 flags | | | | pg_time_t time | | AuditData adata | | uint32 size | # 总长度 | +--------------------+-------------------+ | | AuditType type | | | AuditResult result | | | char varstr | +-------------------+--------------------+ | char *userid | | char *username | | char *dbname | | char *client_info | | char *object_name | | char *detail_info | | char *nodename | | char *threadid | | char *localport | | char *remoteport | | char *recordsha | +-------------------+ 审计日志来源\n其中，针对不同的审计事件，detail_info的内容也不同：\n此处，以登录失败场景记录的审计日志为例，介绍如何生成detail_info，以及如何生成其他关键信息：\n# 生成审计记录的起点 recv_and_check_password_packet sprintf(details, \u0026#39;login db({database_name})failed with no password\u0026#39;) pgaudit_user_login(false, databasename, details) sprintf(detail_info, \u0026#39;{details}, SSL=on/off\u0026#39;) audit_report(AUDIT_LOGIN_FAILED, AUDIT_FAILED, databasename, detail_info) # databasename即object name # 获取userid, username, dbname, clientinfo, threadinfo, localport, remoteport等 # 所有类型的操作，生成的所有日志，都会统一获取这些参数 # 也就是说是，所有类型的日志，只需调用audit_report传入关键的4条信息即可 eventinfo = audit_get_clientinfo(AUDIT_LOGIN_FAILED, database) # 接下来，将所有元信息封装为一条审计记录即可 # 最后，将审计记录发送给审计线程 write_pipe_chunks 此处，以登录失败场景记录的审计日志为例，完整的审计日志如下：\n(\u0026#34;2025-02-11 12:17:12+08\u0026#34;,login_failed,failed,24576,u1,postgres,[unknown]@[local],postgres,\u0026#34;login db(postgres)failed,authentication for user(u1)failed, SSL=off\u0026#34;,node1,139628213434112@792562632014514,5432,null,2dae83e745323eeb280879f49a81cc9ed930009408681c43dfe12f56d7a33831,t) 二、日志文件管理 配置审计文件\n与审计文件相关的GUC参数：\n参数 含义 默认值 audit_directory 生成审计文件时，审计文件存放的文件夹 pg_audit audit_rotation_interval 生成新审计文件时，间隔的时间 1 day audit_rotation_size 生成新审计文件时，旧文件的大小 10 MB audit_resource_policy 自动删除审计文件时，触发自动删除的策略，达到空间/时间限制时删除 on (off表示时间) audit_space_limit 自动删除审计文件时，空间阈值 1GB audit_file_remain_time 自动删除审计文件时，时间阈值 90 (单位为天) audit_file_remain_threshold 生成审计日志文件时，文件最大数量 1048576 审计文件分类\n在之前的示例中，审计文件分为2种：审计日志文件、审计索引文件\ncd 审计目录 # 可通过 SELECT setting FROM pg_settings WHERE name in (\u0026#39;data_directory\u0026#39;, \u0026#39;audit_directory\u0026#39;); 查询 ls # 示例如下： 0_adt 1_adt 2_adt done index_table_new 审计日志文件生成\n如果有多个审计线程，每个线程都有独立的审计文件。\n假设我有5个审计线程，将生成5个审计日志文件：\n0_adt 1_adt 2_adt 3_adt 4_adt done index_table_new 审计日志文件名的格式如下，如果有多个审计线程，会同时生成多个审计文件：\n\u0026#34;{编号}_adt\u0026#34; 审计索引文件只有1个，名称为index_table_new，在存在多个审计线程的场景中，该文件中会记录每个审计线程正在写的文件，假设有5个审计线程，开始时，审计索引文件记录的关系是：\n线程1 -\u0026gt; 0_adt 线程2 -\u0026gt; 1_adt 线程3 -\u0026gt; 2_adt 线程4 -\u0026gt; 3_adt 线程5 -\u0026gt; 4_adt 如果审计日志达到轮转条件，会再生成1新的审计文件，假设1_adt文件达到轮转条件，则会生成新的文件5_adt，同时，index_table_new中记录的对应关系也将变为：\n线程1 -\u0026gt; 0_adt 线程2 -\u0026gt; 5_adt 线程3 -\u0026gt; 2_adt 线程4 -\u0026gt; 3_adt 线程5 -\u0026gt; 4_adt 审计索引文件格式\n审计索引文件的格式如下：\n# 1个AuditIndexTableNew，多个AuditIndexItem # 1的AuditIndexItem，记录1个审计文件的基本信息 +---------------------+ | AuditIndexTableNew | +---------------------+ | AuditIndexItem | | AuditIndexItem | | ... | +---------------------+ AuditIndexTableNew： uint32 maxnum # 审计线程数 uint32 begidx # 审计线程使用的最小文件编号，上述示例中，是0 uint32 thread_num uint32 latest_idx # 审计线程使用的最大文件编号，上述示例中，是5 uint32 curidx[MAX_AUDIT_NUM] # 数组长最大为48，上述示例中，是 [0, 5, 2, 3, 4] uint32 count pg_time_t last_audit_time AuditIndexItem # 上述示例中，一共5个审计文件，则有6个AuditIndexItem pg_time_t ctime uint32 filenum uint32 filesize 刚开始时，索引文件就非常大。有GUC参数设置审计文件的最大数量，开启审计功能后，便一次性预申请所有的AuditIndexItem的存储空间\n4 统一审计 4.1 统一审计的使用 一、设置审计范围 开启资源标签功能\n首先，查看资源标签功能是否已开启\nshow enable_security_policy; -- 默认值：off 开启资源标签功能\ngs_guc reload -D $GAUSSHOME/data1 -c \u0026#34;enable_security_policy=on\u0026#34; 创建资源标签\nCREATE TABLE t1 (c1 INT, c2 TEXT); CREATE RESOURCE LABEL rl1 ADD TABLE(t1); 创建审计策略\nCREATE AUDIT POLICY ap1 ACCESS all ON LABEL(rl1); 二、查看审计范围 查看有哪些AUDIT POLICY\nSELECT * FROM gs_auditing_policy; -- 示例输出： polname | polcomments | modifydate | polenabled --------+-------------+----------------------------+------------ ap1 | | 2025-01-22 19:01:57.338895 | t 查看AUDIT POLICY中要审计哪些RESOURCE LABEL\nSELECT * FROM gs_auditing_policy_access WHERE labelname = \u0026#39;rl1\u0026#39;; -- 示例输出： accesstype | labelname | policyoid | modifydate -----------+-----------+-----------+---------------------------- copy | rl1 | 16392 | 2025-01-22 19:01:57.343464 deallocate | rl1 | 16392 | 2025-01-22 19:01:57.3451 delete | rl1 | 16392 | 2025-01-22 19:01:57.345217 execute | rl1 | 16392 | 2025-01-22 19:01:57.345253 insert | rl1 | 16392 | 2025-01-22 19:01:57.345281 prepare | rl1 | 16392 | 2025-01-22 19:01:57.345307 reindex | rl1 | 16392 | 2025-01-22 19:01:57.345334 select | rl1 | 16392 | 2025-01-22 19:01:57.345361 truncate | rl1 | 16392 | 2025-01-22 19:01:57.345387 update | rl1 | 16392 | 2025-01-22 19:01:57.345414 查看RESOURCE LABEL中有哪些对象\nSELECT * FORM gs_policy_label WHERE labelname = \u0026#39;rl1\u0026#39;; -- 示例输出 labelname | labeltype | fqdnnamespace | fqdnid | relcolumn | fqdntype -----------+-----------+---------------+--------+-----------+---------- rl1 | resource | 2200 | 16384 | | table rl1 | resource | 2200 | 16387 | | table 三、设置审计存储 这一步有点问题，wsl中无法执行成功\necho \u0026#39;local0.* /var/log/localmessages\u0026#39; \u0026gt;\u0026gt; /etc/rsyslog.conf systemctl restart rsyslog 四、生成审计日志 INSERT INTO t1 VALUES (1, \u0026#39;abc\u0026#39;); SELECT * FROM t1; 五、管理审计日志 由于4.2有问题，无法查看/var/log/localmessages中的日志\n4.2 统计审计的架构 4.3 统一审计的源码 一、定义审计对象 用户通过固定的DDL语法定义统一审计的对象\n# 以下语法的调用栈： # CREATE RESOURCE LABEL rl1 ADD TABLE(t1); # DDL的处理流程 standard_ProcessUtility CreateResourcePool heap_open(\u0026#39;系统表 pg_resource_pool\u0026#39;) simple_heap_insert recordDependencyOnRespool # 以下语法的调用栈： # CREATE AUDIT POLICY ap1 ACCESS all ON LABEL(rl1); # DDL的处理流程 standard_ProcessUtility create_audit_policy heap_open(\u0026#39;系统表 gs_auditing_policy\u0026#39;) load_existing_policies # 检查policy是否已存在 simple_heap_insert handle_alter_add_update_filter 二、收集与存储审计日志 由于统一审计只审计特定的对象，只需要在处理SQL语法的流程中，收集审计日志即可，因此，收集点较传统审计少了很多。DDL与DML的处理流程不同，主要收集点有2个：\nDDL类\n# 触发条件：用户执行与特定对象有关的语法 exec_simple_query PortalRun PortalRunMulti PortalRunUtility # 执行 DDL 的主函数 ProcessUtility ProcessUtility_hook gsaudit_ProcessUtility_hook # 第1步，执行DDL前，先生成并暂存审计日志 check_audit_policy_filter check_access_table # 检查 DDL 是否操作需要记录审计日志的对象 check_audit_policy_access flush_policy_result snprintf(\u0026#39;审计日志 AUDIT EVENT: ...\u0026#39;) save_access_logs Thread.access_logs.push(\u0026#39;审计日志 AUDIT EVENT: ...\u0026#39;) # 第2步，执行DDL standard_ProcessUtility # 第3步，执行DDL后，将保存的审计日志存至syslog中 flush_access_logs gs_audit_issue_syslog_message send_sys_log openlog syslog(Thread.(\u0026#39;审计日志\u0026#39;)) closelog gs_elastic_log DML类\n# 触发条件：用户执行与特定对象有关的语法 exec_simple_query PortalRun PortalRunMulti ProcessQuery # 执行 DML 的主函数 ExecutorStart ExecutorStart_hook gs_audit_executor_start_hook # 第1步，执行DML前，先生成并暂存审计日志 access_audit_policy_run check_audit_policy_filter flush_policy_result snprintf(\u0026#39;审计日志 AUDIT EVENT: ...\u0026#39;) save_access_logs Thread.access_logs.push(\u0026#39;审计日志 AUDIT EVENT: ...\u0026#39;) # 第2步，执行DML standard_ExecutorStart # 第3步，执行DML后，将保存的审计日志存至syslog中 flush_access_logs gs_audit_issue_syslog_message ... syslog(Thread.(\u0026#39;审计日志\u0026#39;)) 4.3 统一审计的日志格式 5 重构审计功能 现在：有审计功能，问题多，不好用，性能低\n5.1 配置审计功能：\nSELECT (CASE WHEN alias IS NOT NULL THEN alias ELSE name END) AS adt_guc FROM pg_settings WHERE name like \u0026#39;%audit%\u0026#39; or name like \u0026#39;audit%\u0026#39; GROUP BY adt_guc; -- 查询结果：43个 审计功能\n参数 功能 audit_enabled 是否开启审计功能 审计范围\n主体\n参数 功能 audit_user 对白名单内的用户进行审计 full_audit_users 对白名单内的用户的所有操作进行审计 no_audit_client 对黑名单内的IP的用户不审计 操作\n参数 功能 audit_copy_exec 是否审计 COPY audit_dml_state 是否审计 INSERT、UPDATE、DELETE audit_dml_state_select 是否审计 SELECT audit_set_parameter 是否审计 SET 操作结果 参数 功能 audit_user_violation 是否越权操作 audit_operation_result 只记录操作：成功、失败、成功和失败 的日志 audit_network_error 是否审计网络连接错误 audit_query_cancel 是否审计用户取消SELECT操作 audit_insufficient_space 是否记录SPACE：达到限额 audit_tool_error 是否审计 vb_dump、vb_dumpall、vb_restore 的异常 客体\n参数 功能 audit_system_object 审计OBJECT的范围：DATABASE、SCHEMA、TABLE、…等CREATE、DROP、ALTER操作 audit_database_process 是否审计CLUSTER：启动、停止、切换和恢复 audit_function_exec 是否审计FUNCTION：执行 audit_systerm_function_exec 是否审计FUNCTION：执行（内核写了一个白名单，共61个，例如pg_stat_activity，pg_switch_xlog等） audit_sequence_enabled 是否审计语句序列 audit_crypt_func 是否审计FUNCION （密码运算函数） audit_security_policy 是否审计POLICY audit_transcation 是否审计TANSCATITON：提交、回滚 audit_login_logout 审计CLUSTER：{登录、注销} x {成功、失败} audit_user_locked 是否审计USER：锁定、解锁 audit_grant_revoke 是否审计USER：赋权、收权 审计线程\n参数 功能 audit_thread_num 写日志的线程数 audit_buffer_size 日志缓存大小 audit_buffer_fflush_interval 日志缓存刷盘间隔 日志格式\n参数 功能 audit_data_format 日志格式，仅支持二进制 audit_hash_enabled 日志中是否记录哈希值 get_acl_for_audit 是否从系统表中，获取当前操作对象的ACL信息 audit_xid_info 日志中是否记录xid 日志文件\n参数 功能 audit_space_limit 文件总空间 audit_directory 文件目录 audit_dump_directory 文件复制目录 audit_backup_directory 文件备份目录 audit_file_remain_threshold 文件数量最大值（问题大） audit_file_remain_time 日志保留时间 audit_rotation_interval 生成新文件的时间间隔 audit_stop_policy 文件大小或时间达到阈值时，删除旧日志，还是停止写新日志 audit_resource_policy 文件阈值类型，大小还是时间 audit_rotation_size 生成新文件的文件大小阈值 vb_audit_space_alarm_threshold 是否对文件大小达到阈值时告警 get_auditindex_file_lock 读取索引文件时，不加锁（只是为了测性能时不加锁） subtype | operate | objtype | audit | subgroup | opresult | objgroup |\n——–+———+———-+——–+————–+—————–+—————+\nuser | create | database | on | all | all | all |\nuser | drop | database | on | all | all | all |\nuser | create | table | off | user_group_1 | succeed, failed | table_group_1 |\nuser | drop | table | off | all | succeed | table_group_1 |\n2025/03/28.19:00:00 shenkun create db1 succeed none 10.44.136.83\n2025/03/28.19:00:00 shenkun drop db1 failed permission_deny 10.44.136.83\n{user_name,user_oid,user_ip,operate_type,operate_time,operate_result,error_type,object_type}\nuser user_name user_ip operate operate_type: {create, drop, insert, select, connect, execute} operate_time: operate_result: succeed, failed error_type: object object_type: {cluster, database, table, function} 5.1 审计关键问题 功能问题（现有问题，预估在30+） 审计文件：文件数量存在上限、文件数量受审计线程数影响 审计线程：线程数量变化影响资源初始化 性能问题 存储日志慢：前公司测试结果： 不开审计，tpmc 40w 开启审计，日志不加密，tpmc 2-4w 查询日志慢 易用性问题 通过GUC配置审计范围、审计日志文件管理\nSELECT count(1) FROM pg_settings WHERE name like \u0026#39;%audit%\u0026#39;; count ------- 60 通过int类型配置审计范围\n参数 功能 取值范围 默认值 取值含义 audit_system_object 审计对象范围：DATABASE、SCHEMA、TABLE等 0～134217727 12295 二进制第0位表示是否审计DATABAE、第1位表示SCHEMA、第…、第28位表示EVENT 至少10+GUC参数，取值类型为int，取值范围{0, 1}，表示{关闭，开启}\n审计文件命名为：1_adt, 2_adt, 3_adt, ..\n传统审计、统一审计功能重复\n代码质量问题 过度封装\nstatic void pgaudit_ddl_table(const char *objectname, const char *cmdtext) { AuditType audit_type = AUDIT_DDL_TABLE; AuditResult audit_result = AUDIT_OK; if (!CHECK_AUDIT_DDL(DDL_TABLE)) { return; } pg_audit_ddl_database_object(audit_type, audit_result, objectname, cmdtext); return; } /* pgaudit_ddl_table类函数，实际代码不到4行，共37个 * 比如：pgaudit_ddl_database、pgaudit_ddl_schema、... */ 可维护性\n5.2 审计问题分析 一、功能问题 审计文件\n旧版本文件\nindex_table_new 1_adt 2_adt 3_adt ... 新版本文件\nadt_desc.meta file_size: oldest_file: newest_file: adt_2025-03-25_12-00-13.log # 年 月 日 时 分 秒 adt_2025-03-25_12-00-13.log adt_2025-03-25_12-00-13.log ... 新增参数\naudit_log_directory = audit_log_remain_size = audit_log_remain_days = create group group1 type user 审计线程：1个线程\n二、性能问题 线程通信机制： 日志存储机制： 日志哈希机制： 日志加密机制： 文件命名机制： 5.3 审计重构方案 audit_group\ngroup type name oid all_user user pg_authid.rolname pg_authid.oid all_table table pg_class.relname pg_class.oid all_database database all_index index all_function function all_column_key column_key CREATE AUDIT_GROUP user_gro1 TYPE user MEMBERS a,b,c; CREATE GROUP all_user TYPE user MEMBERS a,b,c; CREATE GROUP all_user TYPE user MEMBERS a,b,c; audit_map\n| id | subject_type | operate_type | object_type | status | subject_group | object_group |\n| -| -| -| -| -|\n| 1 | login_cluster | user | login | cluster | on | all_user | all |\n| 2 | logout_cluster | user | logout | cluster | off | all_user | all |\n| 3 | start_clust | user | start | cluster | on |\n| 4 | stop_cluster | user | stop | cluster | |\nAUDIT CREATE GROUP user_gro1 TYPE user MEMBERS a,b,c; AUDIT DROP GROUP user_gro1; AUDIT SET POLICY login_cluster TO object = all_user, subject = all_table; SET AUDIT POLICY BY \u0026#34;UPDATE vd_audit_policy SET audit = 1\u0026#34;; 6 PostgreSQL 审计 设置审计参数\nSET logging_collector = on; SET log_destination = \u0026#39;stderr\u0026#39;; SET log_directory = \u0026#39;pg_log\u0026#39;; SET log_filename = \u0026#39;postgresql-%U-%m-%d_%H%M%S.log\u0026#39;; SET log_rotation_size = \u0026#39;10MB\u0026#39;; SET log_rotation_age = \u0026#39;1d\u0026#39;; SET log_connections = off; SET log_disconnections = off; SET log_statement = none; -- none, ddl, mod(ddl+insert/delete/update/..), all 收集审计日志\nPostmasterMain ServerLoop BackendStartup BackendInitialize if (Log_connections) /* log_connections */ ereport(LOG, errmsg(\u0026#34;connection received: host..\u0026#34;)) BackendRun PostgresMain exec_simple_query pg_parse_query check_log_statement(parsetree): GetCommandLogLevel(parsetree) if () /* log_statement */ ereport(LOG, errmsg(\u0026#34;statement ..\u0026#34;)) 参考 openGauss审计功能的介绍：https://docs.opengauss.org/zh/docs/6.0.0/docs/DatabaseAdministrationGuide/%E8%AE%BE%E7%BD%AE%E6%95%B0%E6%8D%AE%E5%BA%93%E5%AE%A1%E8%AE%A1.html vastbase审计GUC参数： https://docs.vastdata.com.cn/zh_CN/VastbaseG100/V3.0.8/1/30bab6de005143258e28a0825bc6cb83 其他 一、设置审计备份目录\ngs_guc set -D $GAUSSHOME/data -c \u0026#34;audit_backup_directory=\u0026#39;$GAUSSHOME/data/abackup\u0026#39;\u0026#34; vrestart pgaudit_write_file auditfile_close file_copy(Audit_backup_directory) PgAuditorMain audit_buffer_init auditfile_init for loop: if rotate: auditfile_rotate auditfile_close file_copy(Audit_backup_directory) 二、审计文件\n文件命名：\n# 旧 1_adt 2_adt 3_adt # 新 file_desc.alog audit.id adt_2025-03-12_12-00-13.alog 2025-03-12-12-00-13.alog 2025-03-12-12-00-13.alog 文件查询：\n日志格式\ntypedef struct { uint64 aln; /* audit log number */ uint8 al_version; uint8 al_flags; uint8 al_len; uint8 subj_id; unit8 op_id; uint8 obj_id; uint8 op_result; uint64 op_time; uint64 subj_ip; uint64 op_errcode; } AdtLogHdr; \u0026#39;1122 | 1 0 68 | shenkun create table | succeed 2025.03.13-10:13 | 192.168.0.1 | - \u0026#39; \u0026#39;1122 | 1 0 68 | user1 create table | failed 2025.03.13-10:13 | 192.168.0.1 | perrmisson denied \u0026#39; \u0026#39;shenkun \u0026#39; 三、关键问题\n功能问题\n并发高：日志线程可调整， 数据多 性能\n问题 存储日志： 线程模型：200+业务线程，1个审计线程（默认1个，最大32个） 通信方式：管道，阻塞（1次管道通信开销、1次IO开销） 加密日志 1条日志生成1条sha256值 1条日志生成 查询日志 优化点 线程通信：自选锁 + 普通堆内存，实现线程通信 异步IO：提交或回滚事务时，检查日志是否落盘 哈希优化： 加密优化： 其他问题 存储完整性 代码质量\n易用性\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/4-3-audit/","summary":"\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003e摘要\u003c/strong\u003e：从5个方面，介绍openGauss审计特性：背景、原理、使用、设计、实现\u003c/p\u003e\u003c/blockquote\u003e\n\u003ch1 id=\"1-审计的背景\"\u003e1 审计的背景\u003c/h1\u003e\n\u003ch2 id=\"11-审计的原理\"\u003e1.1 审计的原理\u003c/h2\u003e\n\u003cp\u003e在使用数据库存取数据的大部分场景中，数据库具有以下特点：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e对象多：一个数据库集群中有多个database对象，1个database对象中有多个schema对象，1个schema对象中有多个table、index等对象\u003c/li\u003e\n\u003cli\u003e用户多：一个数据库中，有多个用户，每个用户可访问的数据库对象不同\u003c/li\u003e\n\u003cli\u003e应用多：多个应用将数据存储在同一数据库集群中，并同时访问数据库集群\u003c/li\u003e\n\u003cli\u003e操作多：数据库提供丰富的功能，包括DDL、DML、DCL、运维等\u003c/li\u003e\n\u003cli\u003e运行久：一个数据库集群，可能会保持数十年运行\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e审计的主要目的，使记录数据运行过程中发生了哪些事件。审计的3要素是：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e主体\u003c/strong\u003e：一般指数据库用户\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e客体\u003c/strong\u003e：一般指数据库对象，包括：集群、用户、连接、数据对象（database、schema、table、index、function等）\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e操作\u003c/strong\u003e：主体对客体的操作，比如某个用户访问了某个表\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"12-审计的目的\"\u003e1.2 审计的目的\u003c/h2\u003e\n\u003cp\u003e审计具有以下重要意义：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e攻击检测：通过检查审计日志，可判断是否发生网络安全攻击事件\u003c/li\u003e\n\u003cli\u003e例行维护：通过检查审计日志，可跟踪对某个对象的访问信息\u003c/li\u003e\n\u003cli\u003e故障检测：当数据库出现故障是，协助快速定位问题\u003c/li\u003e\n\u003cli\u003e合法合规：《网络安全法》等法律法规与表中中，要求应用具备审计功能\u003c/li\u003e\n\u003cli\u003e…\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"13-审计的功能\"\u003e1.3 审计的功能\u003c/h2\u003e\n\u003cp\u003e审计功能包含以下3个部分：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e设置审计范围：通过数据库配置参数，或者数据库语法，定义哪些对象需要被审计\u003c/li\u003e\n\u003cli\u003e设置审计存储：通过数据库配置参数，定义审计日志如何存储\u003c/li\u003e\n\u003cli\u003e生成审计日志：数据库运行过程中，访问某个对象时，记录访问信息\u003c/li\u003e\n\u003cli\u003e管理审计日志：查询，删除，归档审计日志\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"14-oracle审计\"\u003e1.4 oracle审计\u003c/h2\u003e\n\u003cp\u003eoracle审计的发展：\u003cbr\u003e\n- oracle 8i及更早：支持传统审计\u003cbr\u003e\n- oracle 12c：新增支持统一审计\u003cbr\u003e\n- oracle 23ai：不支持传统审计，仅支持统一审计\u003c/p\u003e\n\u003cp\u003eoracle统一审计的使用：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 1 创建审计策略\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eAUDIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePOLICY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eap1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIVILEGES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- privilege 子句，记录所有使用CreateTable, AlterUser权限的操作\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eACTIONS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003eUPDATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- aciton 子句，记录所有对表t1执行SELECT,INSERT,UPDATE的操作\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eROLES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003er1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- role 子句，记录所有使用r1角色的操作\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2 启用审计策略\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eAUDIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePOLICY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eap1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 查看审计日志\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eUNIFIED_AUDIT_TRAIL\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- DBA_COMMON_AUDIT_TRAIL, DBA_AUDIT_SESSION, DBA_AUDIT_OBJECT, DBA_FGA_AUDIT_TRAIL\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDBA_AUDIT_TRAIL\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eos_username\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eusername\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003euserhost\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eterminal\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etimestamp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eowner\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eobj_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eaction\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eaction_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e------------+----------+----------+----------+-----------+-------+----------+--------+-------------+\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003enew_owner\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003enew_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eobj_privilege\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esys_privilege\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eadmin_option\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egrantee\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eaudit_option\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eses_actions\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"c1\"\u003e----------+----------+---------------+---------------+--------------+---------+--------------+-------------+\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003elogoff_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003elogoff_lread\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003elogoff_pwrite\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003elogoff_dlock\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecomment_text\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esessionid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eentryid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatementid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ereturncode\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"c1\"\u003e-----------+--------------+---------------+--------------+--------------+-----------+---------+-------------+------------+\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epriv_used\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eclient_id\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eecontext_id\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esession_cpu\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eextended_timestamp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eproxy_sessionid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eglobal_uid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003einstance_number\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"c1\"\u003e-----------+-----------+-------------+-------------+--------------------+-----------------+------------+-----------------+\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eos_process\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etransactionid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003escn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_bind\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_text\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eobj_edition_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erls_info\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecurrent_user\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"c1\"\u003e----------+---------------+-----+----------+----------+------------------+------+----------+--------------+\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e其中，可设置的权限、操作等范围如下：\u003c/p\u003e","title":"数据库安全 3 安全审计"},{"content":"1 访问控制的背景 在使用数据库存取数据的大部分场景中，数据库具有以下特点：\n对象多：一个数据库集群中有多个database对象，1个database对象中有多个schema对象，1个schema对象中有多个table、index等对象 用户多：一个数据库中，有多个用户，每个用户可访问的数据库对象不同 在该场景中，通过访问控制机制，可限制某个对象访问数据库对象的范围\n2 访问控制的原理 访问控制的模型是：主体、客体、操作。本文不解释基本概念。\n主体 USER 角色：\nSYSADMIN 系统管理员 CREATEROLE 安全管理员 AUDITADMIN 审计管理员 MONADMIN 监控管理员 OPRADMIN 运维管理员 POLADMIN 安全策略管理员 客体 DATABASE SCHEMA TABLESPACE TABLE COLUMN FUNCTION PROCEDURE SEQUENCE FOREIGN SERVER LANGUAGE 操作 客体 CREATE DATABASE, SCHEMA, TABLESPACE ALTER DATABASE, SCHEMA, TABLESPACE, TABLE, FUNCTION, PRODUCE, FOREIGN SERVER, DIRECOTRY, PACKAGE DROP DATABASE, SCHEMA, TABLESPACE, TABLE, FUNCTION, PRODUCE, FOREIGN SERVER, DIRECOTRY, PACKAGE TRUNCATE TABLE VACUUM TABLE INDEX TABLE TRIGGER TABLE SELECT TABLE, COLUMN, SEQUENCE INSERT TABLE, COLUMN UPDATE TTABLE, COLUMN, SEQUENCE DELETE TABLE TEMPORARY DATABASE EXECUTE FUNCTION, PROCEDURE, PACKAGE 语法：\nGRANTE \u0026lt;operate\u0026gt; ON \u0026lt;object\u0026gt; TO \u0026lt;subject\u0026gt; WITH \u0026lt;option\u0026gt; \u0026lt;operate\u0026gt; ALL [PRIVILEGES] | ALTER | DROP | INSERT | UPDATE | SELECT | DELETE | .. \u0026lt;object\u0026gt; \u0026lt;object_type\u0026gt; \u0026lt;object_name\u0026gt; \u0026lt;object_type\u0026gt; DATABASE | SCHEMA | TABLESPACE | TABLE | FUNCTION | PROCEDURE | .. \u0026lt;subject\u0026gt; rolname | PUBLIC \u0026lt;option\u0026gt; GRANT OPTION | ADMIN OPTION GRANT rolname TO rolname; REVOKE \u0026lt;operate\u0026gt; ON \u0026lt;object\u0026gt; FROM \u0026lt;subject\u0026gt; 访问控制的分类如下：\n类型 缩写 解释 自主访问控制 DAC 客体属主定义访问控制。客体存储权限列表 角色访问控制 Role-BAC 将主体划分为不同角色，对角色权限进行定义。主体存储权限列表 规则访问控制 Rule-BAC 比如防火墙 强制访问控制 MAC 基于主体和客体的安全级别标签，机密性场景下读上写，完整性场景上读下写 在postgresql中，默认支持自主访问控制和角色访问控制，可主动开启规则访问控制（行级访问控制）。访问控制基本概念如下：\n主体：指用户和角色，但不知为何，角色和用户几乎是同一概念，可能是为了方便实现与管理 客体：指数据库对象，包括数据库、tablespace、表、列、行、函数等，每种客体都有对应的系统表，系统表中存储了所有客体的基本信息，包括ACL 操作：主体对客体的操作，主要有2类。第1类是对具体客体的操作，比如SELECT、UPDATE、INSERT等。第2类指其他如连接数据库、创建数据库、创建用户等操作，由系统表pg_authid控制 在postgresql中，先使用角色访问控制校验权限，如果校验失败，再使用自主访问控制校验权限。自主访问控制实现得较完整，因此，本文先介绍自主访问控制。\n3 自主访问控制 3.1 自主访问控制的场景 假设场景：\n1个集群中，有2个用户，分别是u1，u2 u1创建了1个表，叫t1 默认情况下，u2应该无法访问t1 但是，u1可通过自主访问控制功能，主动给u2权限，让u2可以访问t1 3.2 自主访问控制的使用 创建主体\n创建主体的语法示例如下：\nCREATE USER u1 PASSWORD \u0026#39;u1@12345\u0026#39;; CREATE USER u2 PASSWORD \u0026#39;u2@12345\u0026#39;; 查看主体信息\n主体信息存在2个系统表中，pg_authid中存储了所有主体的oid\n-- 查询系统表（PostgreSQL中，并未严格区分用户和角色的概念，因此，不用在意系统表和语法等取名差异） SELECT oid,rolname,rolpassword FROM pg_authid; oid | rolename | rolpassword ------+----------+-------------- 16384 | u1 | md5......... 16384 | u2 | md5......... -- 查询视图与查询pg_authid结果一致 SELECT * FROM pg_roles; SELECT * FROM pg_user; 创建客体\n客体有多种，此处先以最常见的表为例。创建主体的语法示例如下：\n-- 记得切换到用户 u1 \\c - u1 CREATE TABLE t1 (c1 INT); INSERT INTO t1 VALUES (3); 查看客体信息，包括权限信息\n不同客体由不同的系统表，这些系统表中均有ACL、客体属主这2个关键字段。ACL字段默认为空，在鉴权时，如果ACL为空，会认为属主有全部权限。属主即创建客体的用户。\n查看表、表权限（哪些主体可以访问指定客体）的语法如下：\n-- 表 SELECT oid,relname,relowner,relacl FROM pg_class WHERE relname = \u0026#39;t1\u0026#39;; oid | relname | relowner | relacl -------+---------+----------+-------- 16386 | t1 | 16384 | 查看其他客体的信息，包括权限信息\n-- 数据库 SELECT oid,datname,datdba,datacl FROM pg_database; oid | datname | datdba | datacl -------+-----------+--------+------------------------------- 12295 | postgres | 10 | -- 表空间 SELECT oid,spcname,spcowner,spcacl FROM pg_tablespace; oid | spcname | spcowner | spcacl ------+------------+----------+-------- 1663 | pg_default | 10 | -- 列 SELECT attrelid,attname,attacl FROM pg_attribute; attrelid | attname | attacl ----------+---------+-------- 16386 | c1 | -- 其他客体不一一介绍，通过以下语法，可查询哪些客体的系统表有ACL字段 SELECT attrelid::regclass,attname FROM pg_attribute WHERE attname LIKE \u0026#39;%acl%\u0026#39;; 验证访问控制功能\n默认情况下，用户u1创建表t1，用户u2无法访问t1\n-- 切换到用户u2 \\c - u2 SELECT * FROM t1; ERROR: permission denied for relation t1 设置访问控制功能\n-- u1给u2赋权后，u2将可以访问t1 \\c - u1 GRANT SELECT ON t1 TO u2; -- 赋权后，系统表中，relacl字段，将会发生变化，如下所示，{u1=arwdDxt/u1,u2=r/u1}表示，u2具有read权限，read权限来自u1 SELECT oid,relname,relowner,relacl FROM pg_class WHERE relname = \u0026#39;t1\u0026#39;; oid | relname | relowner | relacl -------+---------+----------+------------------------- 16386 | t1 | 16384 | {u1=arwdDxt/u1,u2=r/u1} 验证访问控制功能\n-- 现在，u2有权限了 \\c - u2 SELECT * FROM t1; 清理\nDROP TABLE t1; DROP USER u1; DROP USER u2; 3.3 自主访问控制的实现 不同语法需要不同的访问权限，postgresql会自动根据语法和客体ACL校验权限，校验主要分为2个阶段：\n语义分析阶段，根据不同的SQL语法，识别主体、客体和操作，根据操作设置所需权限。比如，在’INSERT INTO t1 ..’语法，主体是执行SQL的当前用户，客体是t1，操作是INSERT，所需权限是ACL_INSERT权限；默认情况下，所需设置ACL_SELECT权限。 初始化计划阶段，会从客体系统表中，读取ACL，判断主体所需权限是否满足ACL。比如，在’INSERT INTO t1 ..’语法中，客体是t1，客体系统表是pg_class，客体ACL是pg_class中的relacl字段。判断逻辑在下节介绍。 权限使用32位的位图表示：typedef uint32 AclMode;\n权限的类型有如下多种：\n位数 取值 0-3 ACL_INSERT ACL_SELECT ACL_UPDATE ACL_DELETE (对应 读、写、追加) 4-7 ACL_TRUNCATE ACL_REFERENCES ACL_TRIGGER ACL_EXECUTE 8-11 ACL_USAGE ACL_CREATE ACL_CREATE_TEMP ACL_CONNECT 12-15 not used (低16位表示权限) 16-31 (高16位表示组) ACL的格式\nACL本质是1个AclItem数组：[AclItem, AclItem, AclItem, ..]\nAclItem格式如下：\ntypedef struct AclItem { Oid ai_grantee; // 被授权者 Oid\tai_grantor; // 授权者 AclMode ai_privs; // 权限，即表示ACL_INSERT、ACL_SELECT等权限 } AclItem; 调用栈\nPostmasterMain ServerLoop BackendStartup BackendRun PostgresMain exec_simple_query PortalRun PortalRunMulti ProcessQuery InitPlan ExecCheckRTPerms(rtes) ExecCheckRTEPerms(rte) GetUserId pg_class_aclmask 1. 从pg_class中，获取客体acl数组，如果客体acl为空，默认为owner可读写 aclmask 2. 从pg_auth_members中，找到主体都属于哪些group 3. 判断group权限：如果主体是member of owner，则主体有权限 4. 判断role权限：遍历客体acl数组，如果主体是客体acl数组中的一员，则主体有权限 表的ACL\nACL：在pg_class中，如果a创建1个表，则表默认的acl是：\nrelname | relowner | relack ---------+----------+--------- t1 | oid_a | 默认ACL：如果ACL为空，则默认ACL是：[{ownerid, ownerid, INSERT SELECT UPDATE DELETE RUNCATE REFERENCES TRIGGER}]\n参考：\nlibpq通信协议：https://zhuanlan.zhihu.com/p/379188039 4 角色访问控制 4.1 角色访问控制的场景 假设场景：\n1个公司，有1个部门，分别是p1 1个集群中，有2个用户，分别是u1，u2，同属于部门p1 u1创建了1个表，叫t1_p1，u1想让部门p1的所有用户，都有权限访问t1_p1 4.2 角色访问控制 本文第3章已介绍过自主访问控制，此处很多步骤就不解释了\n创建主体\nCREATE USER u1 PASSWORD \u0026#39;u1@12345\u0026#39;; CREATE USER u2 PASSWORD \u0026#39;u2@12345\u0026#39;; 查看主体角色关系\nSELECT oid,rolname FROM pg_authid WHERE rolname in (\u0026#39;u1\u0026#39;, \u0026#39;u2\u0026#39;); oid | rolname -------+--------- 16398 | u1 16399 | u2 -- pg_auth_members中存储了主体之间的组关系（默认有3条记录，系统自带的，忽略） SELECT * FROM pg_auth_members; roleid | member | grantor | admin_option --------+--------+---------+-------------- 3374 | 3373 | 10 | f 3375 | 3373 | 10 | f 3377 | 3373 | 10 | f 创建客体\n\\c - u1 CREATE TABLE t1 (c1 INT); INSERT INTO t1 VALUES (3); 验证访问控制功能\n-- 默认情况下，u2无权访问t1 \\c - u2 SELECT * FROM t1; ERROR: permission denied for relation t1 设置访问控制功能\n\\c - u1 GRANT u1 TO u2; -- 查询结果中，第4条记录，表示u2属于u1这个组 SELECT * FROM pg_auth_members; roleid | member | grantor | admin_option --------+--------+---------+-------------- 3374 | 3373 | 10 | f 3375 | 3373 | 10 | f 3377 | 3373 | 10 | f 16398 | 16399 | 16398 | f 验证访问控制功能\n\\c - u2 SELECT * FROM t1; 复杂的访问控制功能\n-- 初始用户 CREATE USER u3 PASSWORD \u0026#39;u3@12345\u0026#39;; -- u2把角色传递给u3 \\c - u2 GRANT u2 TO u3; /* 此时，角色的传递模型如下： [u1] --\u0026gt; [u2] --\u0026gt; [u3] u1创建表，u3可访问 u3创建表，u1不可访问 */ -- 角色正向传递：u3也可以访问t1了 -- 检查u3是否可访问时，检查权限的链表是： u3 \u0026lt;-- u2 \u0026lt;-- u1 \\c - u3 SELECT * FROM t1; SELECT * FROM pg_auth_members; roleid | member | grantor | admin_option --------+--------+---------+-------------- 3374 | 3373 | 10 | f 3375 | 3373 | 10 | f 3377 | 3373 | 10 | f 16398 | 16399 | 16398 | f 16399 | 16403 | 16399 | f -- 16403 是 u3的oid -- 角色反向传递：u3创建表，u1不可访问 \\c - u3 CREATE TABLE t3 (c1 INT); INSERT INTO t3 VALUES (3); \\c - u1 SELECT * FROM t1; ERROR: permission denied for relation t3 5 规则访问控制（集群访问控制） 5.1 集群访问控制的场景 5.2 集群访问控制的使用 select * from pg_authid; rolname | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil ----------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+--------------+--------------- shenkun | t | t | t | t | t | t | t | -1 | | pg_monitor | f | t | f | f | f | f | f | -1 | | pg_read_all_settings | f | t | f | f | f | f | f | -1 | | pg_read_all_stats | f | t | f | f | f | f | f | -1 | | pg_stat_scan_tables | f | t | f | f | f | f | f | -1 | | pg_signal_backend | f | t | f | f | f | f | f | -1 | | u1 | f | t | f | f | t | f | f | -1 | md5.. | 6 规则访问控制（行级访问控制） 6.1 行级访问控制的场景 6.2 行级访问控制的使用 CREATE USER u1 PASSWORD \u0026#39;pg@12345\u0026#39;; CREATE USER u2 PASSWORD \u0026#39;pg@12345\u0026#39;; \\c - u1 CREATE TABLE t1 (c1 INT); -- 开启行级自主访问控制 ALTER TABLE t1 ENABLE ROW LEVEL SECURITY; INSERT INTO t1 VALUES (1), (3), (5); GRANT SELECT,INSERT ON t1 TO u2; \\c - u2 SELECT * FROM t1; -- 结果：查询到 0 条数据 \\c - u1 CREATE POLICY p1 ON t1 FOR SELECT TO u2 USING (c1 \u0026lt;= 3); \\c - u2 SELECT * FROM t1; -- 结果：查询到数据{1, 3}，未查询到数据{5} EXPLAIN SELECT * FROM t1; QUERY PLAN ----------------------------------------------------- Seq Scan on t1 (cost=xx) Filter: (c1 \u0026lt;= 3) -- 查询pg_policy系统表，可获取过滤规则 SELECT * FROM pg_policy; polname | polrelid | polcmd | polpermissive | polroles | polqual ---------+----------+--------+---------------+----------+------------------------------------------------- p1 | 16412 | r | t | {16408} | {OPEXPR :opno 523 :opfuncid 149 :opresultt ...} -- 查询pg_policy系统试图，可获取较直观的过滤规则 SELECT * FROM pg_policies; schemaname | tablename | policyname | permissive | roles | cmd | qual | with_check ------------+-----------+------------+------------+-------+--------+-----------+------------ public | t1 | p1 | PERMISSIVE | {u2} | SELECT | (c1 \u0026lt;= 3) | \\c - u1 CREATE POLICY p2 ON t1 FOR INSERT TO u2 WITH CHECK (c1 \u0026lt;= 10); INSERT INTO t1 VALUES (7); 参考 postgresql 10.0.0版本源代码 访问控制分类：https://zhuanlan.zhihu.com/p/151618654 pg ACL概念：https://www.jianshu.com/p/15262ca1740c pg 行级访问控制的使用方式：https://zhuanlan.zhihu.com/p/649711345 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/4-4-access-control/","summary":"\u003ch1 id=\"1-访问控制的背景\"\u003e1 访问控制的背景\u003c/h1\u003e\n\u003cp\u003e在使用数据库存取数据的大部分场景中，数据库具有以下特点：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e对象多：一个数据库集群中有多个database对象，1个database对象中有多个schema对象，1个schema对象中有多个table、index等对象\u003c/li\u003e\n\u003cli\u003e用户多：一个数据库中，有多个用户，每个用户可访问的数据库对象不同\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e在该场景中，通过访问控制机制，可限制某个对象访问数据库对象的范围\u003c/p\u003e\n\u003ch1 id=\"2-访问控制的原理\"\u003e2 访问控制的原理\u003c/h1\u003e\n\u003cp\u003e访问控制的模型是：主体、客体、操作。本文不解释基本概念。\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e主体\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eUSER\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e角色：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eSYSADMIN 系统管理员\u003c/li\u003e\n\u003cli\u003eCREATEROLE 安全管理员\u003c/li\u003e\n\u003cli\u003eAUDITADMIN 审计管理员\u003c/li\u003e\n\u003cli\u003eMONADMIN 监控管理员\u003c/li\u003e\n\u003cli\u003eOPRADMIN 运维管理员\u003c/li\u003e\n\u003cli\u003ePOLADMIN 安全策略管理员\u003c/li\u003e\n\u003c/ul\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e客体\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eDATABASE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eSCHEMA\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eTABLESPACE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eTABLE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCOLUMN\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eFUNCTION\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003ePROCEDURE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eSEQUENCE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eFOREIGN SERVER\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eLANGUAGE\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e操作\u003c/th\u003e\n          \u003cth\u003e客体\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eCREATE\u003c/td\u003e\n          \u003ctd\u003eDATABASE, SCHEMA, TABLESPACE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eALTER\u003c/td\u003e\n          \u003ctd\u003eDATABASE, SCHEMA, TABLESPACE, TABLE, FUNCTION, PRODUCE, FOREIGN SERVER, DIRECOTRY, PACKAGE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eDROP\u003c/td\u003e\n          \u003ctd\u003eDATABASE, SCHEMA, TABLESPACE, TABLE, FUNCTION, PRODUCE, FOREIGN SERVER, DIRECOTRY, PACKAGE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eTRUNCATE\u003c/td\u003e\n          \u003ctd\u003eTABLE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eVACUUM\u003c/td\u003e\n          \u003ctd\u003eTABLE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eINDEX\u003c/td\u003e\n          \u003ctd\u003eTABLE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eTRIGGER\u003c/td\u003e\n          \u003ctd\u003eTABLE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eSELECT\u003c/td\u003e\n          \u003ctd\u003eTABLE, COLUMN, SEQUENCE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eINSERT\u003c/td\u003e\n          \u003ctd\u003eTABLE, COLUMN\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eUPDATE\u003c/td\u003e\n          \u003ctd\u003eTTABLE, COLUMN, SEQUENCE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eDELETE\u003c/td\u003e\n          \u003ctd\u003eTABLE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eTEMPORARY\u003c/td\u003e\n          \u003ctd\u003eDATABASE\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eEXECUTE\u003c/td\u003e\n          \u003ctd\u003eFUNCTION, PROCEDURE, PACKAGE\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e语法：\u003c/p\u003e","title":"数据库安全 4 访问控制"},{"content":" 0 基础调研 一、运算符 二、数据类型 1 架构设计 工作计划 Table 1: Scan Nodes Table 2: Join Nodes Table 3: Processing Nodes Table 4: Set \u0026amp; Control Nodes 单独说明：Table Function Materialization（表函数物化计算） 2 驱动加密 - 实现 2.1 新增类型ciphera 2.2 新增系统表pg_key 2.3 新增语法DATA KEY 2.4 新增系统表pg_sec_class 2.4 新增语法ENCRYPT 2.5 新增公共语法解析libgram 2.6 libpq重写INSERT 2.7 libpq重写SELECT结果 2.8 新增支持int类型 3 机密计算 - 实现 3.1 简单计划 3.2 支持范围 一、数据类型 二、操作符与函数 3.2 新增libcalc 3.2 新增ta_calc/ca_calc 3.3 内核新增ciphera函数 3.4 内核新增ciphera运算符 3.5 内核make_op识别机密计算 3.6 index_scan算子 3.6 优化 ca/ta通信 4 测试用例 等值查询 范围查询 模糊查询 附录：专利 附录：AI 代码要求： 附录：参考文献 0 基础调研 一、运算符 运算符\n以int4为例：select proname from pg_catalog.pg_proc where proname like '%int4%' order by proname; 一、比较运算符函数\n运算符 函数 \u0026lt; int4lt \u0026lt;= int4le = int4eq != / \u0026lt;\u0026gt; int4ne \u0026gt; int4gt \u0026gt;= int4ge (btree) btint4cmp 二、算数运算符函数\n运算符 函数 + int4pl - int4mi * int4mul / int4div % int4mod @ int4abs 三、聚合函数\n运算符 函数 sum() int4_sum max() int4larger min() int4smaller avg() int4_avg_accum + int8_avg 二、数据类型 - 一、数值与字符串 | 类型 | 别名 | 说明 | | -| -| -| | smallint | int2 | - | | integer | int, int4 | - | | bigint | int8 | - | | real | float4 | - | | double precision | float8 | - | | character varying(n) | varchar(n) | - | | character(n) | char(n) | - | | text | - | - | - 二、时间、布尔、二进制 | 类型 | 别名 | 说明 | | -| -| -| | boolean | bool | - | | bytea | - | - | | timestamp | - | - | | timestamp with time zone | timestamptz | - | | time | - | - | | time with time zone | timetz | - | | interval | - | - | - 三、自增序列 | 类型 | 别名 | 说明 | | -| -| -| | smallserial | serial2 | - | | serial | serial4 | - | | bigserial | serial8 | - | - 四、其他 | 类型 | 别名 | 说明 | | -| -| -| | numeric(p,s) | decimal(p,s) | - | | bit varying(n) | varbit(n) | - | | jsonb | - | - | | uuid | - | -| 1 架构设计 Driver +Cache +Parser (libgram.so) +Encrypt (libdrvenc.so) +Rewrite (libdrvenc.so) Protocol Connect Server Parser Analyze Rewrite Plan Executor +TeeProtocol +CipherQual (libcalc.so) 代码结构：\nsrc interfaces libpq fe-drvenc.c backend utils adt ciphera.c # 新增数据类型 security 直接计算 (ExecMakeTableFunctionResult)\napp libpq libdrvenc kernel ta_cacl |---------------------------------------|---------------------------|-------------------|-------------------------------|----------------------------------- CREATE DATA KEY k1 .. insert catalog pg_key CREATE TABLE t1(c1 INT ENCRYPT .., c2 INT) insert catalog pg_attribute [c1, ciphera] insert catalog pg_sec_class [t1, c1, int] connect(drvenc=on) get encrypted columns info from catalog pg_sec_class set encrypted columns load encrypted columns get search_paths from catalog pg_namespace set search_paths INSERT INTO t1 VALUES(11,22) rewrite query if need load search_path parse query \u0026#39;INSERT INTO t1 VALUES(11,22)\u0026#39; check if column encryptd [public.t1.c1] [public.t1.c2] encrypt column value \u0026#39;11\u0026#39; rewrite query \u0026#39;INSERT INTO t1 VALUES(\u0026#39;cipher_11\u0026#39;,22)\u0026#39; send new query \u0026#39;INSERT INTO t1 VALUES(\u0026#39;cipher_11\u0026#39;,22)\u0026#39; insert t1 [\u0026#39;cipher_11\u0026#39;,22] SELECT * FROM t1 WHERE c1 = 11 (assume: seqscan) rewrite query if need parse query \u0026#39;SELECT * FROM t1 WHERE c1 = 11\u0026#39; check if column encryptd [public.t1.c1] encrypt column value \u0026#39;11\u0026#39; to \u0026#39;cipher_11\u0026#39; rewrite query \u0026#39;SELECT * FROM t1 WHERE c1 = cipher_11\u0026#39; send new query \u0026#39;SELECT * FROM t1 WHERE c1 = cipher_11\u0026#39; scan tuple [c1 = cipher_11] send result [\u0026#39;cipher_11\u0026#39;,22] recv result [\u0026#39;cipher_11\u0026#39;,22] decrypt result if need check if column encryptd [public.t1.c1] decrypt column result \u0026#39;cipher_11\u0026#39; to 11 rewrite column reslut [11,22] return result [11,22] receive [11,22] SELECT * FROM t1 WHERE c1 \u0026gt; 10 (assume: seqscan) rewrite query if need parse query \u0026#39;SELECT * FROM t1 WHERE c1 \u0026gt; 10\u0026#39; .. rewrite query \u0026#39;SELECT * FROM t1 WHERE c1 \u0026gt; cipher_10\u0026#39; send new query \u0026#39;SELECT * FROM t1 WHERE c1 \u0026gt; cipher_10\u0026#39; parse analyze qual \u0026#39;c1 \u0026gt; cipher_10\u0026#39; to \u0026#39;ciphera_gt(c1, cipher_10)\u0026#39; plan execute scan tuple [\u0026#39;cipher_11\u0026#39;,22] call \u0026#39;ciphera_gt(\u0026#39;cipher_11\u0026#39;, cipher_10)\u0026#39; package calculation [ciphera_gt, cipher_11, cipher_10] send calculation receive calculation [ciphera_gt, cipher_11, cipher_10] decrypt cipher_11 to 11 decrypt cipher_10 to 10 call int4gt(11,10) -\u0026gt; true send result [true] recv calculation [true] send scan result [\u0026#39;cipher_11\u0026#39;,22] recv result [\u0026#39;cipher_11\u0026#39;,22] decrypt result if need .. return result [11,22] SELECT c1 + c2 FROM t1 (assume: seqscan) rewrite query if need send query \u0026#39;SELECT c1 + c2 FROM t1\u0026#39; parse analyze qual \u0026#39;c1 + c2\u0026#39; to \u0026#39;ciphera_pl(c1,c2)\u0026#39; plan execute scan tuple [\u0026#39;cipher_11\u0026#39;,22] call \u0026#39;ciphera_pl(\u0026#39;cipher_11\u0026#39;, 22)\u0026#39; package calculation [ciphera_pl, cipher_11, 22] send calculation receive calculation [ciphera_pl, cipher_11, 22] decrypt cipher11 to 11 call int4pl(11,22) -\u0026gt; 33 encrypt result 33 to cipher_33 send result [cipher_33] recv calculation [cipher_33] send result [cipher_33] recv result [\u0026#39;cipher_11\u0026#39;,22] decrypt result if need .. return result [33] receive [33] 例外：\nINSERT INTO t1 VALUES(10+1, 22); --\u0026gt; INSERT INTO t1 VALUES(ciphera_sum(cipher_10, cipher_1), 22); INSERT INTO t1 SELECT c21,c22 FROM t2; INSERT INTO t1 SELECT c21::ciphera,c22 FROM t2; -- ciphera中，需包含key oid INSERT INTO t1 SELECT re_encrypt(c21, t1, c1),c22 FROM t2; 工作计划 一、基本功能\n语句加密（驱动侧 语法解析 [0.2人月] 语句重写：10+数据类型、20+语法 [0.5人月] 结果解密 [0.1人月] 加密适配器 [0.2人月] 密钥适配器 [0.2人月] 密文处理（内核侧） 密文操作符处理：15+ [0.2人月] 密文函数处理：30+ [0.3人月] 密文索引处理：btree [0.3人月] 密文聚集算子处理：sort, agg, group, unique [0.6人月] 密文连接算子处理：hashjoin, mergejoin, nestloopjoin [0.5人月] 机密计算适配器 [0.3人月] 密文计算（可信侧） 密文函数计算：40+ [0.3人月] 密文索引处理：btree [0.3人月] 二、软硬适配\n加密适配\n三未信安加密机 [0.2人月] 密钥适配\n华为云管理服务 [0.2人月] 驱动适配\nJDBC [0.5人月] 机密计算适配\n国产CPU：5 [0.8人月] 国产OS：10 [0.8人月] 分类\n表达式求值： ExecEvalExpr ExecQual ExecProject 索引访问计算： bt_compare bt_search hash_func 基础设施回调 索引 _bt_compare _bt_binsrch 排序 ApplySortComparator ST_COMPARE 哈希 ExecHashGetHashValue 合并 ExecMergeCompareKeys Table 1: Scan Nodes No. Node Exec Function Expression Evaluation Infrastructure Callback 1 Seq Scan ExecSeqScan ExecQual, ExecProject N/A 2 Index Scan ExecIndexScan ExecQual (Filter/Recheck) _bt_compare, _bt_binsrch 3 Index Only Scan ExecIndexOnlyScan ExecQual (Filter) _bt_compare, _bt_binsrch 4 Bitmap Heap Scan ExecBitmapHeapScan ExecQual, ExecProject N/A 5 Bitmap Index Scan ExecBitmapIndexScan N/A _bt_compare, _bt_binsrch 6 Tid Scan ExecTidScan ExecQual, ExecProject N/A 7 Tid Range Scan ExecTidRangeScan ExecQual, ExecProject N/A 8 Subquery Scan ExecSubqueryScan ExecQual, ExecProject N/A 9 Function Scan ExecFunctionScan ExecQual, ExecProject N/A 10 TableFunc Scan ExecTableFuncScan ExecQual, ExecProject N/A 11 Values Scan ExecValuesScan ExecQual, ExecProject N/A 12 CTE Scan ExecCteScan ExecQual, ExecProject N/A 13 Named Tuplestore Scan ExecNamedTuplestoreScan ExecQual, ExecProject N/A 14 WorkTable Scan ExecWorkTableScan ExecQual, ExecProject N/A 15 Foreign Scan ExecForeignScan ExecQual, ExecProject N/A 16 Sample Scan ExecSampleScan ExecQual, ExecProject N/A Table 2: Join Nodes No. Node Exec Function Expression Evaluation Infrastructure Callback 1 Nested Loop ExecNestLoop ExecQual (Join Filter), ExecProject N/A 2 Hash Join ExecHashJoin ExecQual, ExecProject ExecHashGetHashValue, ExecHashGetBucket 3 Merge Join ExecMergeJoin ExecQual, ExecProject ExecMergeCompareKeys Table 3: Processing Nodes No. Node Exec Function Expression Evaluation Infrastructure Callback 1 Sort ExecSort N/A ApplySortComparator (ST_COMPARE) 2 Incremental Sort ExecIncrementalSort N/A ApplySortComparator (ST_COMPARE) 3 Aggregate ExecAgg ExecEvalExpr (transfn, finalfn) N/A 4 Group ExecGroup N/A execTuplesMatchPrepare / Compare 5 Unique ExecUnique N/A execTuplesMatchPrepare / Compare 6 Hash ExecHash N/A ExecHashGetHashValue, ExecHashGetBucket 7 WindowAgg ExecWindowAgg ExecEvalExpr (window func) N/A 8 ProjectSet ExecProjectSet ExecEvalExpr (SRF in targetlist) N/A 9 ModifyTable ExecModifyTable ExecEvalExpr (SET/WHERE exprs) N/A 10 Limit ExecLimit N/A N/A 11 Material ExecMaterial N/A N/A 12 Memoize ExecMemoize N/A ExecMemoizeGetHashValue 13 Gather ExecGather N/A N/A 14 Gather Merge ExecGatherMerge N/A ApplySortComparator (ST_COMPARE) 15 LockRows ExecLockRows N/A N/A 16 SetOp ExecSetOp N/A execTuplesMatchPrepare / Compare Table 4: Set \u0026amp; Control Nodes No. Node Exec Function Expression Evaluation Infrastructure Callback 1 Append ExecAppend N/A N/A 2 Merge Append ExecMergeAppend N/A ApplySortComparator (ST_COMPARE) 3 Result ExecResult ExecQual, ExecProject N/A 4 Recursive Union ExecRecursiveUnion N/A N/A 单独说明：Table Function Materialization（表函数物化计算） 在原生 PostgreSQL 中，仅 Function Scan 算子涉及此类计算。当函数被用作 FROM 子句中的数据源（即 SRF，Set-Returning Function）时，PG 执行引擎会通过 ExecMakeTableFunctionResult 接管控制权，循环调用该函数的 SRF 接口，并将返回的多行结果物化到内存或磁盘的 Tuplestore 中。此计算路径独立于表达式求值和基础设施回调，是 PG 内核中第三种且唯一的表函数专用计算机制。注意：TableFunc Scan（如 XMLTABLE/JSON_TABLE）走的是专门的 TableFunc API，不经过 ExecMakeTableFunctionResult，因此不属于此类。\nSELECT * FROM generate_series(1, 1000000);\nSELECT * FROM pg_stat_activity;\n2 驱动加密 - 实现 2.1 新增类型ciphera pg_type.dat\nciphera.h / ciphera.c\n``` ```c pg_proc.dat\nMakefile\n验证：\npsql -d postgres -- 查看内置的数据类型 SELECT * FROM pg_type WHERE typname = \u0026#39;ciphera\u0026#39;; -- 使用新类型 CREATE TABLE t1(c1 INT, c2 CIPHERA); \\d t1 -- 检查数据正常处理 INSERT INTO t1 VALUES (1, \u0026#39;c101aaff\u0026#39;); SELECT * FROM t1; 2.2 新增系统表pg_key SELECT * FROM pg_key; \\d+ pg_key 2.3 新增语法DATA KEY CREATE DATA KEY dk1(password=\u0026#39;pass.123\u0026#39;); -- 在pg_key中，存储密钥信息 SELECT * FROM pg_key; DROP DATA KEY dk1; 2.4 新增系统表pg_sec_class SELECT * FROM pg_sec_class; -- reloid, attname, atttypid, atttypmod 2.4 新增语法ENCRYPT CREATE DATA KEY dk1(password=\u0026#39;pass.123\u0026#39;); CREATE TABLE t1(c1 INT ENCRYPT dk1); -- pg_attribute中，c1列的类型自动变更为ciphera -- pg_sec_class中，attroid列，存储c1列才pg_attribute中的oid -- pg_sec_class中，attrtype, attrmod SELECT * FROM pg_attribute WHERE attname = \u0026#39;c1\u0026#39;; SELECT * FROM pg_sec_class; 2.5 新增公共语法解析libgram 2.6 libpq重写INSERT CREATE DATA KEY dk1(password=\u0026#39;pass.123\u0026#39;); CREATE TABLE t1(c1 TEXT, c2 TEXT ENCRYPT dk1, c3 TEXT); INSERT INTO t1 VALUES (\u0026#39;aaa\u0026#39;, \u0026#39;bbb\u0026#39;, \u0026#39;ccc\u0026#39;); INSERT INTO t1(c2,c3) VALUES (\u0026#39;xxx\u0026#39;, \u0026#39;yyy\u0026#39;); INSERT INTO t1 VALUES (\u0026#39;a1\u0026#39;, \u0026#39;b1\u0026#39;, \u0026#39;c1\u0026#39;), (\u0026#39;a2\u0026#39;, \u0026#39;b2\u0026#39;, \u0026#39;c2\u0026#39;); SELECT * FROM t1; 2.7 libpq重写SELECT结果 CREATE DATA KEY dk1(password=\u0026#39;pass.123\u0026#39;); CREATE TABLE t1(c1 TEXT, c2 TEXT ENCRYPT dk1, c3 TEXT); INSERT INTO t1 VALUES (\u0026#39;aaa\u0026#39;, \u0026#39;bbb\u0026#39;, \u0026#39;ccc\u0026#39;), (\u0026#39;xxx\u0026#39;, \u0026#39;yyy\u0026#39;, \u0026#39;zzz\u0026#39;);; SELECT * FROM t1 WHERE c2 = \u0026#39;yyy\u0026#39;; -- where ciphera_eq(c2,\u0026#39;...\u0026#39;) 2.8 新增支持int类型 CREATE DATA KEY dk1(password=\u0026#39;pass.123\u0026#39;); CREATE TABLE t1(c1 INT, c2 INT ENCRYPT dk1, c3 INT); INSERT INTO t1 VALUES (10,11,12); INSERT INTO t1(c2,c3) VALUES (100,101); INSERT INTO t1 VALUES (1001,1002,1003), (1011,1012,1013); SELECT * FROM t1 WHERE c2 = 100; 3 机密计算 - 实现 3.1 简单计划 目标\n-- 构造 CREATE DATA KEY dk1(password=\u0026#39;pass.123\u0026#39;); CREATE TABLE t1(c1 INT, c2 INT ENCRYPT dk1, c3 INT); INSERT INTO t1 VALUES (11,12,13), (21,22,23), (31,32,33), (41,42,43); -- 预期：tee中，执行ciphera_gt SELECT * FROM t1 WHERE c2 \u0026gt; 30; -- 清理 DROP TABLE t1; DROP DATA KEY dk1; AI提示\n我已经在pg16中，从0实现全密态等值查询，使用方法如下：\n-- -- 1 定义密钥（新增语法）：在系统表pg_key中，存储密钥 CREATE DATA KEY dk1(password=\u0026#39;pass.123\u0026#39;); -- 2 新增内置数据类型：新增ciphera类型，存储text, int加密后的值，类似与bytea -- 3 定义加密列（新增语法 ）：在系统表 pg_attrbute中，c2存储为ciphera类型，在新系统表pg_sec_class中，存储c2的原始类型int CREATE TABLE t1(c1 INT, c2 INT ENCRYPT dk1, c3 INT); -- 4 自动加密：在libpq中，自动加密INSERT语法中c2列的值，将其转换为ciphera类型 INSERT INTO t1 VALUES (11,12,13), (21,22,23), (31,32,33), (41,42,43); -- 5 自动解密：在libpq中，自动解密SELECT返回结果中c2的值，将其转换为int类型 SELECT * FROM t1; -- 6 密态等值查询：自动加密SELECT语法中c2列的值，服务端直接比较密文 SELECT * FROM t1 WHERE c2 = 12; 其中，支持自动加解密的数据类型如下：\nint2 int4 int8 varchar(n) text bytea 执行计划\nCREATE TABLE t1(c1 INT, c2 INT ENCRYPT dk1, c3 INT); INSERT INTO t1 VALUES (11,12,13), (21,22,23), (31,32,33), (41,42,43); -- 在代码中，以下SQL的执行计划 SELECT sum(c1) FROM t1 WHERE c1 \u0026gt; 10 AND c2 \u0026lt; 40; \u0026#34;Agg -\u0026gt; Scan t1 Filter (c1 \u0026gt; 10) AND (c2 \u0026lt; \u0026#39;40\u0026#39;::ciphera) \u0026#34; SELECT c1,c2 FROM t1 WHERE c2 \u0026lt; 40 ORDER BY c2 LIMIT 10; \u0026#34;LIMIT -\u0026gt; Sort Sort Key: c2 -\u0026gt; Scan t1 Filter c2 \u0026lt; \u0026#39;40\u0026#39; \u0026#34; -- 如果数据很多，要确保以下计算速度最快，怎么创建索引优化呢？注意c1加密，c2不加密。 SELECT * FROM t1 WHERE c1 \u0026gt; 10 AND c2 \u0026lt; 40; SELECT * FROM t1 WHERE c1 \u0026gt; 10 OR c2 \u0026lt; 40; 现在，我要在服务端实现机密计算，支持int类型的各种操作，我要新增一批ciphera的运算函数，比如cipehra_lt等，cipehra_lt中，解密数据，然后转换为int4_lt。为覆盖int的各种运算，我需要新增的ciphera运算函数应该包含哪些？\n3.2 支持范围 一、数据类型 - 一、数值与字符串 | 类型 | 别名 | 说明 | | -| -| -| | smallint | int2 | - | | integer | int, int4 | - | | bigint | int8 | - | | real | float4 | - | | double precision | float8 | - | | character varying(n) | varchar(n) | - | | character(n) | char(n) | - | | text | - | - | - 二、时间、布尔、二进制 | 类型 | 别名 | 说明 | | -| -| -| | boolean | bool | - | | bytea | - | - | - 三、其他 | 类型 | 别名 | 说明 | | -| -| -| | numeric(p,s) | decimal(p,s) | - | 二、操作符与函数 - 一、比较运算符函数 | 运算符 | 函数 | | -| -| | \u0026lt; | ciphera_lt | | \u0026lt;= | ciphera_le | | = | ciphera_eq | | != / \u0026lt;\u0026gt; | ciphera_ne | | \u0026gt; | ciphera_gt | | \u0026gt;= | ciphera_ge | | (btree) | bt_ciphera_cmp | - 二、算术运算符函数 | 运算符 | 函数 | | -| -| | + | ciphera_pl | | - | ciphera_mi | | * | ciphera_mul | | / | ciphera_div | | % | ciphera_mod | | @ | ciphera_abs | - 三、位运算符函数 | 运算符 | 函数 | | -| -| | \u0026amp; | ciphera_bitand | | \\| | ciphera_bitor | | # | ciphera_bitxor | | ~ | ciphera_bitnot | | \u0026lt;\u0026lt; | ciphera_bitshiftleft | | \u0026gt;\u0026gt; | ciphera_bitshiftright | - 四、字符串与二进制操作函数 | 运算符 / 函数名 | 函数 | | -| -| | \\|\\| | ciphera_cat | | length() | ciphera_length | | substr() | ciphera_substr | | lower() | ciphera_lower | | upper() | ciphera_upper | | trim() | ciphera_trim | | replace() | ciphera_replace | | position() | ciphera_position | | like | ciphera_like | | ilike | ciphera_ilike | | ~ / ~* | ciphera_regexp_match | - 五、聚合状态转换函数 | 聚合函数 | 函数 | | -| -| | SUM() | ciphera_sum | | MAX() | ciphera_larger | | MIN() | ciphera_smaller | | AVG() | ciphera_avg_accum | | STRING_AGG() | ciphera_string_agg | 3.2 新增libcalc 3.2 新增ta_calc/ca_calc ca_calc：独立进程。自动生成pg的各种计算int2，text等计算，比如int2eq等，格式化入参，通过共享内内存的方式，把数据发送给ta_calc进程，等待计算结果。 ta_calc：独立进程。通过共享内存，接收ca_calc发送的数据，并且反格式化，并调用libcalc.so接口，完成计算，把计算结果返回给ca_calc。 3.3 内核新增ciphera函数 SELECT oid,proname,prorows,pronargs,proargtypes,prorettype,pronargdefaults,proargnames,prosrc FROM pg_proc WHERE proname like \u0026#39;%cipher%\u0026#39;; SELECT oid, proname, prorows, pronargs, (SELECT string_agg(format_type(oid, NULL), \u0026#39;, \u0026#39; ORDER BY ord) FROM unnest(proargtypes) WITH ORDINALITY AS u(oid, ord)) AS argin, format_type(prorettype, NULL) AS argout, pronargdefaults, proargnames, prosrc FROM pg_proc WHERE proname LIKE \u0026#39;%cipher%\u0026#39; ORDER BY oid; 3.4 内核新增ciphera运算符 3.5 内核make_op识别机密计算 3.6 index_scan算子 CREATE TABLE t1(c1 INT, c2 TEXT, c3 INT); CREATE INDEX i1 ON t1(c1,c2); -- 假设t1有很多数据，且analyze过 -- 哪些查询会走索引？哪些不走？给一些例子！要全一点 -- 走索引： SELECT * FROM t1 WHERE c1 = 1； SELECT * FROM t1 WHERE c1 = 1 + 1； SELECT * FROM t1 WHERE c1 IN (1,2,3); SELECT * FROM t1 WHERE c1 \u0026gt; 1; SELECT * FROM t1 WHERE c1 \u0026gt; 1 AND c1 \u0026lt; 2; SELECT * FROM t1 WHERE c1 = 1 AND c2 = \u0026#39;a\u0026#39;; -- 不能c2 \u0026gt; \u0026#39;a\u0026#39; SELECT * FROM t1 ORDER BY c1； SELECT c1,count(*) FROM t1 GROUP BY c1; SELECT max(c1) FROM t1; SELECT * FROm t1 JOIN t2 ON t1.c1 = t2.c1; DELETE FROM t1 WHERE c1 = 1; UPDATE t1 SET c2 = \u0026#39;b\u0026#39; WHERE c1 = 1; -- 不走索引 SELECT * FROM t1 WHERE c2 = \u0026#39;a\u0026#39;; SELECT * FROM t1 WHERE c2 \u0026gt; \u0026#39;a\u0026#39;; SELECT * FROM t1 WHERE c1 + 1 = 2; -- 不行 SELECT * FROM t1 WHERE c1::text = \u0026#39;1\u0026#39;; SELECT * FROM t1 WHERE c1 != 1; SELECT * FROM t1 WHERE c1 NO IN (1,2,3); SELECT * FROM t1 WHERE c1 = 1 AND c2 \u0026gt; \u0026#39;a\u0026#39;; SELECT * FROM t1 WHERE c1 = 5 OR c3 = 10; tpcc 1000 warehouse\nbmsql_customer 表： 行数：3000w 大小：13.5 G 索引：(c_w_id, c_d_id, c_id) 索引大小：700 M 索引行数：300w 索引层数：3层 root：1 page * 400 tup/page internal：400 page * 400 tup/page leaf：8.8w page * 400 tup/page tee交互次数：3 3.6 优化 ca/ta通信 ca1 ca1 ca2 ca3 +--------[fdbk]+----------[fdbk]+-------------[fdbk]+---------------+ --------- itemdesc itemdesc itemdesc itemdesc total=1000 p1 alloc off=[0-100] p2 alloc off=[100-300] p3 alloc off=[300-700] p4 alloc off=[700-1000] p3 free off=[300-700] p5 alloc len=100, 怎么处理？ p6 alloc len=200，怎么处理？ 我在使用C语言编程。有个场景：多个生产者，比如是p1,p2,p3,p4。1个消费者s1。每个p1都执行psend，然后执行precv阻塞等待s1反馈。帮我设计并实现一个demo。\n4 测试用例 等值查询 范围查询 -- 构造 CREATE DATA KEY dk1(password=\u0026#39;pass.123\u0026#39;); CREATE TABLE t1(c1 INT, c2 INT ENCRYPT dk1, c3 INT); INSERT INTO t1 VALUES (11,12,13), (21,22,23), (31,32,33), (41,42,43); -- 预期：tee中，执行ciphera_gt SELECT * FROM t1 WHERE c2 \u0026gt; 30; -- 清理 DROP TABLE t1; DROP DATA KEY dk1; 模糊查询 附录：专利 SQL改写 select * from t1 where c1 \u0026gt; 10 select * from t1 where ciphera_gt(c1, cipherf_10) 加密上下文 驱动侧：’Q’修改为’C’：携带 加密上下文版本号 内核侧：CREATE/ALTER/DROP TABLE，CREAT/ALTER/DROP KEY，更新 加密上下文版本号 表达式短路求值 内核侧：SELECT .. WHERE cipher \u0026gt; .. OR plian \u0026gt; ..优化为WHERE plian \u0026gt; .. OR cipher \u0026gt; .. OR 附录：AI 代码要求： 尽量少使用换行，遵循以下格式：\ntypedef struct CreateDataKeyStmt { NodeTag\ttype; char *keyname; } CreateDataKeyStmt; int funcname(int arg1, char *arg2) /* 要求1：返回值、函数名等放在一行 */ { int tmpa; /* 要求2：缩进统一用1个tab，1个tab是4个空格，确保是4个空格哦 */ int tmpb; /* 要求3：类型和变量名之间，用1个空格 */ if (arg1 \u0026lt; 5 \u0026amp;\u0026amp; arg \u0026lt; 10 \u0026amp;\u0026amp; arg2 != NULL) { /* 要求4：换行缩进1个tab，除了函数定义外，所有大括号不单独换行 */ /* do something */ } switch (arg1) { /* 要求5：switch和大括号放在同一行 */ case 30: /* do something */ break; case 40: /* do something */ break; default: break; } if (arg == NULL) { /* 要求6：即使if中只有1行代码，也加大括号 */ return -1; } else { /* do something */ } return 1; } 计划 新增libcalc.so 支持的类型：int2,int4,int8,varchar(n),text,bytea 支持的运算：lt, le, eq, ne, gt, ge, bt_cmp, pl, mi, mul, div, mod, abs, bitand, bitor, bitxor, bitnot, bitshiftleft, bitshiftright, cat, length, substr, lower, upper, trim, replace, position, like, ilike, regexp_match, sum, larger, smaller, avg_accum, string_agg 新增内置函数：ciphera内置函数：lt, le, eq, ne, gt, ge, bt_cmp, pl, mi, mul, div, mod, abs, bitand, bitor, bitxor, bitnot, bitshiftleft, bitshiftright, cat, length, substr, lower, upper, trim, replace, position, like, ilike, regexp_match, sum, larger, smaller, avg_accum, string_agg (ciphera, ciphera)：密文和密文 (ciphera, int2)：密文和明文 独立编译运 附录：参考文献 全密态概述：https://www.jos.org.cn/html/2024/8/7095.htm#outline_anchor_6 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/4-5-fully-encrypted-database/","summary":"\u003col\u003e\n\u003cli\u003e\u003ca href=\"#0-%E5%9F%BA%E7%A1%80%E8%B0%83%E7%A0%94\"\u003e0 基础调研\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%80%E3%80%81%E8%BF%90%E7%AE%97%E7%AC%A6\"\u003e一、运算符\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BA%8C%E3%80%81%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B\"\u003e二、数据类型\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1\"\u003e1 架构设计\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E5%B7%A5%E4%BD%9C%E8%AE%A1%E5%88%92\"\u003e工作计划\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#Table-1-Scan-Nodes\"\u003eTable 1: Scan Nodes\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#Table-2-Join-Nodes\"\u003eTable 2: Join Nodes\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#Table-3-Processing-Nodes\"\u003eTable 3: Processing Nodes\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#Table-4-Set-amp-Control-Nodes\"\u003eTable 4: Set \u0026amp; Control Nodes\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%8D%95%E7%8B%AC%E8%AF%B4%E6%98%8E%EF%BC%9ATable-Function-Materialization%EF%BC%88%E8%A1%A8%E5%87%BD%E6%95%B0%E7%89%A9%E5%8C%96%E8%AE%A1%E7%AE%97%EF%BC%89\"\u003e单独说明：Table Function Materialization（表函数物化计算）\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-%E9%A9%B1%E5%8A%A8%E5%8A%A0%E5%AF%86-%E5%AE%9E%E7%8E%B0\"\u003e2 驱动加密 - 实现\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#2-1-%E6%96%B0%E5%A2%9E%E7%B1%BB%E5%9E%8Bciphera\"\u003e2.1 新增类型ciphera\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-2-%E6%96%B0%E5%A2%9E%E7%B3%BB%E7%BB%9F%E8%A1%A8pg-key\"\u003e2.2 新增系统表pg_key\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-3-%E6%96%B0%E5%A2%9E%E8%AF%AD%E6%B3%95DATA-KEY\"\u003e2.3 新增语法DATA KEY\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-4-%E6%96%B0%E5%A2%9E%E7%B3%BB%E7%BB%9F%E8%A1%A8pg-sec-class\"\u003e2.4 新增系统表pg_sec_class\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-4-%E6%96%B0%E5%A2%9E%E8%AF%AD%E6%B3%95ENCRYPT\"\u003e2.4 新增语法ENCRYPT\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-5-%E6%96%B0%E5%A2%9E%E5%85%AC%E5%85%B1%E8%AF%AD%E6%B3%95%E8%A7%A3%E6%9E%90libgram\"\u003e2.5 新增公共语法解析libgram\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-6-libpq%E9%87%8D%E5%86%99INSERT\"\u003e2.6 libpq重写INSERT\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-7-libpq%E9%87%8D%E5%86%99SELECT%E7%BB%93%E6%9E%9C\"\u003e2.7 libpq重写SELECT结果\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-8-%E6%96%B0%E5%A2%9E%E6%94%AF%E6%8C%81int%E7%B1%BB%E5%9E%8B\"\u003e2.8 新增支持int类型\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-%E6%9C%BA%E5%AF%86%E8%AE%A1%E7%AE%97-%E5%AE%9E%E7%8E%B0\"\u003e3 机密计算 - 实现\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#3-1-%E7%AE%80%E5%8D%95%E8%AE%A1%E5%88%92\"\u003e3.1 简单计划\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-2-%E6%94%AF%E6%8C%81%E8%8C%83%E5%9B%B4\"\u003e3.2 支持范围\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%80%E3%80%81%E6%95%B0%E6%8D%AE%E7%B1%BB%E5%9E%8B\"\u003e一、数据类型\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BA%8C%E3%80%81%E6%93%8D%E4%BD%9C%E7%AC%A6%E4%B8%8E%E5%87%BD%E6%95%B0\"\u003e二、操作符与函数\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-2-%E6%96%B0%E5%A2%9Elibcalc\"\u003e3.2 新增libcalc\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-2-%E6%96%B0%E5%A2%9Eta-calc-x2F-ca-calc\"\u003e3.2 新增ta_calc/ca_calc\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-3-%E5%86%85%E6%A0%B8%E6%96%B0%E5%A2%9Eciphera%E5%87%BD%E6%95%B0\"\u003e3.3 内核新增ciphera函数\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-4-%E5%86%85%E6%A0%B8%E6%96%B0%E5%A2%9Eciphera%E8%BF%90%E7%AE%97%E7%AC%A6\"\u003e3.4 内核新增ciphera运算符\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-5-%E5%86%85%E6%A0%B8make-op%E8%AF%86%E5%88%AB%E6%9C%BA%E5%AF%86%E8%AE%A1%E7%AE%97\"\u003e3.5 内核make_op识别机密计算\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-6-index-scan%E7%AE%97%E5%AD%90\"\u003e3.6 index_scan算子\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-6-%E4%BC%98%E5%8C%96\"\u003e3.6 优化\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#ca-x2F-ta%E9%80%9A%E4%BF%A1\"\u003eca/ta通信\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-%E6%B5%8B%E8%AF%95%E7%94%A8%E4%BE%8B\"\u003e4 测试用例\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E7%AD%89%E5%80%BC%E6%9F%A5%E8%AF%A2\"\u003e等值查询\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E8%8C%83%E5%9B%B4%E6%9F%A5%E8%AF%A2\"\u003e范围查询\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E6%A8%A1%E7%B3%8A%E6%9F%A5%E8%AF%A2\"\u003e模糊查询\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E9%99%84%E5%BD%95%EF%BC%9A%E4%B8%93%E5%88%A9\"\u003e附录：专利\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E9%99%84%E5%BD%95%EF%BC%9AAI\"\u003e附录：AI\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BB%A3%E7%A0%81%E8%A6%81%E6%B1%82%EF%BC%9A\"\u003e代码要求：\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E9%99%84%E5%BD%95%EF%BC%9A%E5%8F%82%E8%80%83%E6%96%87%E7%8C%AE\"\u003e附录：参考文献\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"0-基础调研\"\u003e0 基础调研\u003c/h1\u003e\n\u003ch2 id=\"一运算符\"\u003e一、运算符\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e运算符\u003cbr\u003e\n以int4为例：\u003ccode\u003eselect proname from pg_catalog.pg_proc where proname like '%int4%' order by proname;\u003c/code\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e一、比较运算符函数\u003c/p\u003e","title":"数据库安全 5 全密态"},{"content":"1 透明加密背景 在另一篇博客中，已经讨论了几个话题：\n数据泄露风险 加密方案对比 透明加密基本原理 因此，本篇博客直接进入主题，介绍openGauss透明加密特性。\n2 透明加密使用 2.1 开启透明加密 2.2 定义加密表 CREATE TABLE t1 (c1 INT, c2 TEXT) WITH (enable_tde=on); 2.3 验证数据加密 3 透明加密设计 4 透明加密原理 1 概述 1.1 模块 heapam -\u0026gt; buffer -\u0026gt; smgr -\u0026gt; page 1 概述 1.1 功能 用户创建表时，通过SQL语句指定表是否加密\n数据库将数据页写入磁盘时，判断如果数据页属于加密表，对数据先加密在存储\n数据库从磁盘读取数据页时，判断如果数据页已被加密，读取后马上解密\n1.2 适配点 初始化page 存储page 读取page 生成xlog记录：考虑初始化pagee 重放xlog记录：考虑初始化page 1.3 kun tde 2 调用关系 2.1 初始化数据页 PageInit PageInit(Page page, Size pageSize, Size specialSize) heap_xlog_insert() heap_xlog_multi_insert() heap_xlog_update() heap_xlog_visible() raw_heap_insert() PageGetTempPageCopySpecial() fill_seq_with_data() seq_redo() brin_page_init() lazy_scan_heap() GinInitPage() GISTInitBuffer() _hash_pageinit() _bt_pageinit() SpGistInitPage() vm_readbuf() vm_extend() XLogRecordPageWithFreeSpace() fsm_readbuf() fsm_extend() image 2.2 写入数据页 smgrextend 调用栈：\nsmgrextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer) copy_relation_data() ATExecSetTableSpace() /* ALTER TABLE ... TABLESPACE */ ATRewriteTables() ATController() AlterTable() AlterTableInternal() raw_heap_insert() rewrite_heap_tuple() reform_and_rewrite_tuple() copy_heap_data() rebuild_relation() cluster_rel() cluster() /* case T_ClusterStmt */ standard_ProcessUtility() vacuum_rel() vacuum() ExecVacuum() /* case T_VacuumStmt */ standard_ProcessUtility() autovacuum_do_vac_analyze() do_autovacuum() AutoVacWorkerMain() StartAutoVacWorker() /* TODO */ SubPostmasterMain() /* --forkavworker */ end_heap_rewrite() copy_heap_data() /* repeat */ end_heap_rewrite() /* repeat */ ReadBuffer_common() ReadBufferExtended() /* 48 call */ get_raw_page_internal() pg_prewarm() statapprox_heap() pgstatindex_impl() /* TODO */ ReadBufferWithoutRelcache() XLogReadBufferExtended() XLogReadBufferForRedoExtended() XLogReadBufferForRedo() /* 58 call */ XLogInitBufferForRedo() /* 33 call */ heap_xlog_clean() heap_xlog_visible() btree_xlog_vacuum() XLogRecordPageWithFreeSpace() /* 剪枝：FSM_FORKNUM */ heap_xlog_clean() /* repeat */ heap_xlog_insert() heap_xlog_multi_insert() heap_xlog_update() btree_xlog_vacuum() btree_xlog_delete_get_latestRemovedXid() _hash_alloc_buckets() _hash_expandtable() _hash_doinsert() hashbuildCallback() hashinsert() _h_indexbuild() _bt_blwritepage() fsm_extend() vm_extend() smgrwrite 调用栈\nsmgrwrite(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer) FlushBuffer() BufferAlloc() ReadBuffer_common() /* repeat */ SyncOneBuffer() BufferSync() CheckPointBuffers() CheckPointGuts() CreateCheckPoint() StartupXLOG() StartupProcessMain() InitPostgres() ShutdownXLOG() CheckpointerMain() /* case CheckpointerProcess */ AuxiliaryProcessMain() InitPostgres() CheckpointerMain() /* repeat */ RequestCheckpoint() XLogWrite() StartupXLOG() do_pg_start_backup() XLogPageRead() createdb() dropdb() movedb() DropTableSpace() standard_ProcessUtility() /* case T_CheckPointStmt */ CreateRestartPoint() BgBufferSync() BackgroundWriterMain() AuxiliaryProcessMain() /* case BgWriterProcess */ FlushOneBuffer() XLogReadBufferForRedoExtended() XLogInitBufferForRedo() heap_xlog_insert() heap_xlog_multi_insert() heap_xlog_update() seq_redo() ... /* 33 calls, most indexs */ XLogReadBufferForRedo() xlog_redo() heap_xlog_insert() heap_xlog_multi_insert() heap_xlog_update() heap_xlog_inplace() heap_xlog_delete() heap_xlog_confirm() heap_xlog_visible() heap_xlog_freeze_page() heap_xlog_lock() heap_xlog_lock_updated() ... /* 58 calls, most index */ heap_xlog_clean() heap_xlog_visible() btree_xlog_vacuum() FlushRelationBuffers() /* repeat */ FlushDatabaseBuffers() FlushRelationBuffers() heap_sync() CopyFrom() end_heap_rewrite() /* repeat */ intorel_shutdown() transientrel_shutdown() ATRewriteTable() /* repeat */ ATExecSetTableSpace() /* repeat */ LocalBufferAlloc() ReadBuffer_common() /* repeat */ btbuildempty() _bt_blwritepage() spgbuildempty() 2.3 读取数据页 smgrread(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, char *buffer) pg_prewarm() copy_relation_data() ReadBuffer_common() /* repeat */ 2.4 记录数据 3 关键函数 heap_xlog_insert(XLogReaderState *record) if XLOG_HEAP_INIT_PAGE: XLogInitBufferForRedo() PageInit() else: XLogReadBufferForRedo(record, 0, \u0026amp;buffer) XLogReadBufferForRedoExtended(record, 0, RBM_NORMAL, false, buf) { XLogRecGetBlockTag(record, block_id, \u0026amp;rnode, \u0026amp;forknum, \u0026amp;blkno) if XLogRecHasBlockImage(record, block_id): *buf = XLogReadBufferExtended(rnode, forknum, blkno, RBM_ZERO_AND_LOCK) { smgr = smgropen(rnode, InvalidBackendId) smgrcreate(smgr, forknum, true) lastblock = smgrnblocks(smgr, forknum) if blkno \u0026lt; lastblo: buffer = ReadBufferWithoutRelcache(rnode, forknum, blkno, mode, NULL) smgropen(rnode, InvalidBackendId) ReadBuffer_common(smgr, RELPERSISTENCE_PERMANENT, forkNum, blockNum,mode, NULL, \u0026amp;hit) BufferAlloc() ... /* see buffer.md */ else: ... } page = BufferGetPage(*buf) RestoreBlockImage(record, block_id, page) MarkBufferDirty(*buf) } 2 记录 xlog记录类型：（仅针对用户表）\n1条tuple\nheap_insert() : RM_HEAP_ID, XLOG_HEAP_INSERT | XLOG_HEAP_INIT_PAGE\nheap_delete() : RM_HEAP_ID, XLOG_HEAP_DELETE\nheap_update() : RM_HEAP_ID, XLOG_HEAP_LOCK\nheap_lock_tuple() : RM_HEAP_ID, XLOG_HEAP_LOCK\nheap_lock_updated_tuple_rec() : RM_HEAP2_ID, XLOG_HEAP2_LOCK_UPDATED\nheap_finish_speculative() : RM_HEAP_ID, XLOG_HEAP_CONFIRM\nheap_abort_speculative() : …\nheap_inplace_update : RM_HEAP_ID, XLOG_HEAP_INPLACE\n多条tuple\nheap_multi_insert() : RM_HEAP2_ID, XLOG_HEAP2_MULTI_INSERT | XLOG_HEAP_INIT_PAGE\n1页page\n数据写入时机：\n单写：\nINSERT\n批量写： ALTER … TABLESPACE VACUUM FULL log_newpage场景：\nvacuum full: 创建新文件，拷贝旧文 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/4-9-tde/","summary":"\u003ch1 id=\"1-透明加密背景\"\u003e1 透明加密背景\u003c/h1\u003e\n\u003cp\u003e在另一篇博客中，已经讨论了几个话题：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e数据泄露风险\u003c/li\u003e\n\u003cli\u003e加密方案对比\u003c/li\u003e\n\u003cli\u003e透明加密基本原理\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e因此，本篇博客直接进入主题，介绍openGauss透明加密特性。\u003c/p\u003e\n\u003ch1 id=\"2-透明加密使用\"\u003e2 透明加密使用\u003c/h1\u003e\n\u003ch2 id=\"21-开启透明加密\"\u003e2.1 开启透明加密\u003c/h2\u003e\n\u003ch2 id=\"22-定义加密表\"\u003e2.2 定义加密表\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eenable_tde\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003eon\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"23-验证数据加密\"\u003e2.3 验证数据加密\u003c/h2\u003e\n\u003ch1 id=\"3-透明加密设计\"\u003e3 透明加密设计\u003c/h1\u003e\n\u003ch1 id=\"4-透明加密原理\"\u003e4 透明加密原理\u003c/h1\u003e\n\u003ch1 id=\"1-概述\"\u003e1 概述\u003c/h1\u003e\n\u003ch2 id=\"11-模块\"\u003e1.1 模块\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eheapam -\u0026gt; buffer -\u0026gt; smgr -\u0026gt; page\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"1-概述-1\"\u003e1 概述\u003c/h1\u003e\n\u003ch2 id=\"11-功能\"\u003e1.1 功能\u003c/h2\u003e\n\u003cp\u003e用户创建表时，通过SQL语句指定表是否加密\u003cbr\u003e\n数据库将数据页写入磁盘时，判断如果数据页属于加密表，对数据先加密在存储\u003cbr\u003e\n数据库从磁盘读取数据页时，判断如果数据页已被加密，读取后马上解密\u003c/p\u003e\n\u003ch2 id=\"12-适配点\"\u003e1.2 适配点\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e初始化page\u003c/li\u003e\n\u003cli\u003e存储page\u003c/li\u003e\n\u003cli\u003e读取page\u003c/li\u003e\n\u003cli\u003e生成xlog记录：考虑初始化pagee\u003c/li\u003e\n\u003cli\u003e重放xlog记录：考虑初始化page\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"13-kun-tde\"\u003e1.3 kun tde\u003c/h2\u003e\n\u003ch1 id=\"2-调用关系\"\u003e2 调用关系\u003c/h1\u003e\n\u003ch2 id=\"21-初始化数据页\"\u003e2.1 初始化数据页\u003c/h2\u003e\n\u003ch3 id=\"pageinit\"\u003ePageInit\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003ePageInit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ePage\u003c/span\u003e \u003cspan class=\"n\"\u003epage\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eSize\u003c/span\u003e \u003cspan class=\"n\"\u003epageSize\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eSize\u003c/span\u003e \u003cspan class=\"n\"\u003especialSize\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eheap_xlog_insert\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eheap_xlog_multi_insert\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eheap_xlog_update\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eheap_xlog_visible\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eraw_heap_insert\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003ePageGetTempPageCopySpecial\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003efill_seq_with_data\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eseq_redo\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003ebrin_page_init\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003elazy_scan_heap\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eGinInitPage\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eGISTInitBuffer\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003e_hash_pageinit\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003e_bt_pageinit\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eSpGistInitPage\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003evm_readbuf\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003evm_extend\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eXLogRecordPageWithFreeSpace\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003efsm_readbuf\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003efsm_extend\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"image\"\u003eimage\u003c/h3\u003e\n\u003ch2 id=\"22-写入数据页\"\u003e2.2 写入数据页\u003c/h2\u003e\n\u003ch3 id=\"smgrextend\"\u003esmgrextend\u003c/h3\u003e\n\u003cp\u003e调用栈：\u003c/p\u003e","title":"数据库安全 9 透明加密"},{"content":"1 正常场景 CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; set role u1 password \u0026#39;u1.password\u0026#39;; -- ddl DROP TABLE t1; DROP FUNCTION f1; CREATE TABLE t1(c1 INT, c2 TEXT); -- dml INSERT INTO t1 VALUES (1, \u0026#39;aaa\u0026#39;), (2, \u0026#39;bbb\u0026#39;); UPDATE t1 SET c2 = \u0026#39;aba\u0026#39; WHERE c1 = 1; SELECT * FROM t1; DELETE FROM t1 WHERE c1 = 2; -- func CREATE FUNCTION f1() RETURNS INT AS $$ SELECT count(*)::INT FROM t1 $$ LANGUAGE sql; SELECT f1(); -- trans BEGIN; SELECT * FROM t1; COMMIT; DROP TABLE t1; DROP FUNCTION f1; reset role; select * from pg_audit_log; 2 异常场景 CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; CREATE TABLE st1(c1 INT, c2 TEXT); set role u1 password \u0026#39;u1.password\u0026#39;; -- doest\u0026#39;t exist SELECT * FROM nt1; -- permission deny SELECT * FROM st1; reset role; select * from pg_audit_log; ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/5-testcase-g100-audit-refactor/","summary":"\u003ch1 id=\"1-正常场景\"\u003e1 正常场景\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003erole\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- ddl\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFUNCTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ef1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- dml\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aaa\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;bbb\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eUPDATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSET\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aba\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDELETE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- func\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFUNCTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ef1\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eRETURNS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$$\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)::\u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$$\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLANGUAGE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ef1\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- trans\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCOMMIT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFUNCTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ef1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003ereset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003erole\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eselect\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efrom\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_audit_log\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"2-异常场景\"\u003e2 异常场景\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003est1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003erole\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- doest\u0026#39;t exist\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ent1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- permission deny\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003est1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003ereset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003erole\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eselect\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efrom\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_audit_log\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"海量 5 用例 G100审计重构"},{"content":"G100审计功能重构 1 功能简述 在需求文档中，已详细介绍需求背景，此处不在重复介绍。\nG100 309之前版本，审计特性存在较多问题，因此，在本版本，将重新设计与实现审计特性，解决功能、性能、易用性、可维护性、可扩展性等问题，使审计特性达到大规模商用的标准。\n2 实现方案 一、审计架构 审计特性，核心子功能如下：\n配置审计：通过GUC参数，配置审计参数：日志目录、目录大小、日志文件淘汰策略等 设置范围：通过SQL语法，设置审计策略，控制哪些事件需审计。在策略中，可按用户、操作、对象、操作结果等过滤事件 收集事件：在代码关键节点，收集事件 过滤事件：根据审计策略，过滤无需审计的事件 生成日志：提取事件关键信息，生成日志 传输日志：工作线程，通过共享内存，传输日志给审计线程 存储日志：审计线程，组织日志，并将其存储至文件中。文件存放在单独的日志目录 查询日志：通过内置FUNCTION，在线查询日志，通过TOOL，离线查询日志 其中，设置范围、过滤事件子功能相对独立，可单独设计与实现，所以，拆分到另一个的设计文档中。\n审计特性整体架构图如下：\n二、工作流程 收集事件的主体、操作、客体等信息时，因为需收集操作结果，即操作成功或失败，所以，很多场景中，收集事件需分为2个阶段：\n执行操作前：收集事件基本信息，包括操作类型等 执行操作后：收集事件的操作结果。对于出现ERROR的场景，则在异常处理函数中收集操作结果。 在所有事件中，DML语句的事件稍复杂一点，此处主要以该类语句为例，梳理整体执行流程：\n三、详细流程 阶段1 配置审计（进程启动） 首先，用户通过GUC参数，配置审计文件管理等功能。然后，在系统启动阶段，审计模块将根据配置，初始化的各类关键资源，包括：\n日志文件：日志存储目录，初始日志文件等 审计内存：日志缓存区，内存上下文等 审计线程：信号处理函数等 事件收集节点：hook函数注册等 详细启动过程如下：\nmain # 1. 启动vastbase进程 knl_instance_init MemoryContextInit PostmasterMain # 2. 启动postmaster线程 SelectConfigFiles # 3. 加载GUC参数 checkDataDir \u0026#39;audit_dir_init\u0026#39; # 4. 创建审计日志文件目录 \u0026#39;audit_hook_init\u0026#39; # 5. 注册审计回调函数：身份认证等 load_hba reset_shared CreateSharedMemoryAndSemaphores # （日志缓冲区不是共享内存，后文阶段6详细介绍） GlobalSysDBCache::Init CreateLocalSysDBCache InitRoleIdHashTable \u0026#39;audit_comm_init\u0026#39; # 6. 初始化审计内存上下文、日志缓存区，创建审计日志文件 \u0026#39;initialize_util_thread(AUDIT_WRITER)\u0026#39; # 7. 启动audit-writer 线程，持续读取日志缓冲区，等待接收与存储日志 initialize_thread .. # ===== audit-writer 线程 ============== GaussDbThreadMain InitShmemAccess InitAuxiliaryProcess CreateSharedMemoryAndSemaphores GaussDBAuxiliaryThreadMain BaseInit \u0026#39;adt_writer_main\u0026#39; # ===== audit-writer 线程 ============== ServerLoop for (;;) comm_select ConnCreate # 9. 接收客户端连接 BackendStartup initialize_util_thread(WORKER) initialize_thread .. # ===== postgres 线程 ============== GaussDbThreadMain knl_thread_init InitializeGUCOptions CreateLocalSysDBCache \u0026#39;audit_hook_init\u0026#39; # 10. 注册事件收集回调函数：计划执行、函数执行等回调点 BackendInitialize BackendRun PostgresMain # ===== postgres 线程 ============== \u0026#39;initialize_util_thread(AUDIT_WRITER)\u0026#39; # 11. 检查audit-writer 线程状态与自动重启 阶段2 设置范围 向用户提供SQL接口，用于创建审计策略。（见另一个设计文档）\n阶段3 收集事件 数据库中，产生的事件类型较多，按触发方式，可将事件分为以下3类：\n系统事件：直接触发或异常导致的事件。启动、停止集群，登录、登出集群 SQL事件：SQL触发的事件 DML DDL/DQL/MNG/.. FUNC 内部事件：非用户直接触发的事件 一、系统事件 共4种事件，包括：启动、停止集群，登录、登出集群。各事件需注意的点如下：\n启动集群：初始化审计模块后，postmaster线程才生成启动集群事件，并传输到audit-writer线程。 停止集群：audit-writer线程收到shutdown相关信号后，生成停止集群事件并落盘。如果由postmaster线程生成停止集群事件，需在将shutdown信号传输给audit-writer前，以及清理LWLock等资源前，传输审计事件给audit-writer，适配点较多 登录集群：无法直接使用内核已有hook框架，因为代码流程中的hook点靠后，在hook点前出现的部分登录失败场景，无法走到hook点 登出集群：清理postgres线程时，产生登出集群事件，需确保在清理共享内存前产生事件，因为发送日志需依赖共享内存中的LWLock 完整流程如下：\nPostmasterMain audit_dir_init audit_worker_init # 1. 注册回调函数：身份认证 audit_comm_init # 2. 初始化审计内存上下文、日志缓存区，创建审计日志文件 \u0026#39;audit_system_startup\u0026#39; # 3. 收集事件：启动集群 initialize_util_thread(AUDIT_WRITER) initialize_thread .. # ===== audit-writer 线程 ============== adt_writer_main for (;;) if SIGTERM: \u0026#39;audit_system_shutdown\u0026#39; # 4. 收集事件：停止集群 # ===== audit-writer 线程 ============== ServerLoop for (;;) BackendStartup initialize_util_thread(WORKER) # 5. 启动 postgres线程 .. # ===== postgres 线程 ============== GaussDbThreadMain BackendInitialize BackendRun PostgresMain BaseInit on_shmem_exit(\u0026#39;audit_logout_system\u0026#39;) # 6. 注册线程退出回调函数：登出集群 PostgresInitializer::InitBackendWorker # 7. 初始化连接 if not thread_pool: PostgresInitializer::InitSession InitSysCache CheckAuthentication PerformAuthentication ClientAuthentication \u0026#39;audit_login_system\u0026#39; # 8. 收集事件：登录集群 recv_and_check_password_packet # 9. 身份认证 \u0026#39;audit_send_all_log\u0026#39; # 10. 发送日志 LoadSysCache for (;;) if thread_pool: while True: ThreadPoolWorker::AttachSessionToThread InitSession PostgresInitializer::InitSession ReadCommand proc_exit # 8. 退出线程 proc_exit_prepare shmem_exit .. \u0026#39;audit_logout_system\u0026#39; # 11. 收集事件：登出集群 # ===== postgres 线程 ============== if SIGTERM or SIGINT: pmdie signal_child PostmasterStateMachine elif SIGQUIT: killGraceThreads signal_child ExitPostmaster 二、SQL事件 SQL种类较多，根据hook点不同，可分为以下几类：\nDDL类：CREATE, DROP等。其他DCL类、MNG类等，例如GRANT、VACUUM等，也可划到DDL大类中。 DQL：SELECT FUNC：执行FUNCTION 上文提到，为收集事件中操作的结果，收集点如下：\n执行操作前：收集事件基本信息 执行操作后：未清理执行资源前，例如内存上下文等，收集事件的操作结果：操作成功，并发送日志。 执行操作中：如果发生错误，调用ereport触发的长调转，在异常处理的最早期阶段，收集事件的操作结果：操作失败，并发送日志。 内核执行SQL时，在初始化plan，执行plan，执行plan结束等多个阶段，都提供hook点，但是，部分hook点无法满足收集操作结果的需求，因此，本需求将新增几个hook点：\nDML事件 现状：在初始化plan阶段，内核访问控制框架会遍历所有的操作信息{操作，对象}，并检查权限。检查后，有个hook点 问题：如果检查过程中，发现权限问题，会直接报错，无法走到hook点 修改：在检查权限之间，新增hook点，收集事件基本信息 FUNC事件 现在：postgresql在所有执行function的地方，都有hook点 问题：openGauss与G100，将function的hook点全都删了，因为其他功能用不上 修改：新增执行function的hook点，参考postgresql加回来 当前的收集框架，存在一点小缺陷：\n问题：对于DML类事件，在语法解析、语义分析阶段，如果发生ERROR，例如操作不存在的表等，无法收集事件 原因：在初始化plan阶段，才收集DML类事件，事件中包括操作类型、客体类型、客体名称等。在语义分析大部分阶段，未完整获取操作类型、客体类型等信息。 解释：最关键的因权限导致的ERROR，可以收集事件，因为在初始化plan阶段才检查DML权限 完整流程如下：\nPostgresMain InitProcess if sigsetjmp: \u0026#39;audit_send_all_log(FAILED)\u0026#39; # 收集事件结果：操作失败 for ;; ReadCommand reload_configfile case \u0026#39;Q\u0026#39;: exec_simple_query parse_query_auto_gram pg_analyze_and_rewrite pg_plan_queries PortalStart if \u0026#39;SELECT\u0026#39;: ExecutorStart # hook standard_ExecutorStart InitPlan ExecCheckRTPerms \u0026#39;新增 prev_hook\u0026#39; # 收集事件：DQL ExecCheckRTEPerms # hook ExecInitNode PortalRun if \u0026#39;SELECT\u0026#39;: PortalRunSelect ExecutorRun elif \u0026#39;INSERT/UPDATE/DELETE\u0026#39; or \u0026#39;DDL\u0026#39;: PortalRunMulti if \u0026#39;DML\u0026#39;: ProcessQuery if \u0026#39;INSERT/UPDATE/DELETE\u0026#39;: ExecutorStart # 已有hook standard_ExecutorStart InitPlan ExecCheckRTPerms \u0026#39;新增 prev_hook\u0026#39; # 收集事件：DML ExecCheckRTEPerms # 已有hook ExecutorRun # 已有hook standard_ExecutorRun ExecutePlan ExecutorFinish # 已有hook \u0026#39;audit_send_all_log(FAILED)\u0026#39; # 收集事件结果：操作成功 standard_ExecutorFinish ExecPostrocessPlan ExecutorEnd # 已有hook standard_ExecutorEnd ExecEndPlan ExecEndNode heap_close FreeExecutorState # delete query mem cxt elif \u0026#39;DDL\u0026#39;: PortalRunUtility ProcessUtility # 已有hook # 收集事件：DDL standard_ProcessUtility \u0026#39;audit_send_all_log(FAILED)\u0026#39; # 收集事件结果：执行成功 PortalDrop PortalCleanup if \u0026#39;SELECT\u0026#39;: ExecutorFinish # hook # 收集事件结果：操作成功 standard_ExecutorFinish ExecutorEnd # hook standard_ExecutorEnd finish_xact_command CommitTransaction RecordTransactionCommit case \u0026#39;P\u0026#39;: exec_parse_message case \u0026#39;B\u0026#39;: exec_bind_message case \u0026#39;E\u0026#39;: exec_execute_message 三、内部事件 除系统事件、SQL事件外，内核还会产生一些内部事件，这些事件不是用户直接触发的。此类事件需要过滤。\n2p-cleaner线程\n平均间隔1秒左右，与数据库建立连接，并发送与执行SQL语句。此类连接，内核可识别到，客户端类型为gs_clean。审计模块将直接过滤’application_name=gs_clean’的事件。\nTwoPhaseCleanerMain for (;;) DropTempNamespace LoginDatabase PQconnectdbParams DropTempSchema \u0026#39;DROP SCHEMA pg_toast_temp_xx CASCADE\u0026#39; vsql\nvsql每次与内核建立连接时，都会自动发送与执行6条SQL，以获取兼容性等信息。审计模块将过滤’application_name=vsql’的前6条SQL。\nvsql -h xxx -p xxx -U xxx -W xxx main .. PQconnectdbParams # 1. 与server端建立连接 PQexec(\u0026#39;SELECT VB_VERSION()\u0026#39;) # 2. 检查版本 PQexec(\u0026#39;select setting from pg_catalog.pg_settings ..\u0026#39;) # 3. 检查兼容性 # 4. ... 其他信息 对于每个事件，除主体、操作、客体相关的核心信息外，还需在一些关键节点，收集以下信息：\nSQL语句 客户端信息：客户端类型、客户端IP、客户端主机名、客户端端口 客体详细属性：客体所属Database，客体所属Schema 其他信息：事务ID，XLOG ID，会话ID，线程ID等 上述信息，均可从session级的全局变量上获取。\n阶段4 过滤事件 收集事件后，需根据用户配置的审计策略，判断事件是否需被审计。（见另一个设计文档）\n阶段5 生成日志 对于所有事件，都生成统一格式的日志。每条日志中的所有内容如下：\n日志字段\n| 字段 | 内容 解释 ------------+----------------------------------- optime | 2025-09-21 12:00:01.400009+08 -- 操作时间 apolicy | ap1 -- 策略名称：生成本条日志的策略 scope | ddl -- 操作分类：例如ddl,dml,dql等 subjname | shenkun -- 操作用户 optype | create -- 操作类型 objtype | table -- 客体类型 objname | t2 -- 客体名称 cliip | 10.44.136.83 -- 客户端IP或HOST cliport | 39850 -- 客户端端口 cliapp | vsql -- 客户端类型：即连接参数applicatiion_name opresult | succeed -- 操作结果：成功或失败 objdb | vastbase -- 客体所属database objnsp | public -- 客体所属schema opxid | 0 -- 操作的xlog id optid | 0 -- 操作的事务id opthreadid | 489 -- 操作的线程id opsessid | 1986 -- 操作的会话id sql | CREATE TABLE t2 AS SELECT * FROM t1; -- 原始SQL语句 extra | -- 其他信息：例如报错信息 物理格式\n压缩存储：将大部分text类内容，使用枚举型压缩存储。例如，针对对象类型，将database存储为1，schema存储为2等\n后向兼容：日志存储在Page中，每个Page的PageHeader中，有版本号等信息\ntypedef struct { /* basic info: 4 bytes, must in the same page */ uint16 loglen; uint16 logtype; uint32 logcrc; AuditTime optime; uint16 flags; uint32 scope; uint32 cliport; /* operate info */ uint16 optype; uint16 objtype; /* to align the structure, we place it here */ uint16 opresult; uint16 sqlid; uint64 opxid; uint32 optid; uint32 oppid; /* client info */ uint16cliipoff; uint16 cliappoff; /* subject info */ uint16 subjoff; /* object info */ uint16 objoff; uint16 objdboff; uint16 objnspoff; /* the details */ uint16 sqloff; uint16 extraoff; /* all text are stored below */ char textbuf[0]; /* +------+------+------+----+------+ * | text | text | text | .. | text | * +------+------+------+----+------+ */ } 阶段6 传输日志 开启审计时，postgres等线程生成日志后，需将日志发送到日志缓存区，由audit-writer线程写至磁盘。\n关闭审计时，对于强制审计类事件，例如启动、停止集群，登录、登出用户，执行CREATE USER等DCL，产生事件的线程直接将日志写至磁盘。\n开启审计时 通过日志缓存区传输日志：\n传输场景\n通常，应用场景中，用户并发执行SQL，可能同时存在100+个worker线程执行SQL，产生并传输日志。在本版本，只有1个audit-writer线程负责存储日志 传输介质\n普通堆内存传输日志 传输设计 并发传输：多个worker线程，可并发传输日志 高效传输：合理设计锁，减少线程阻塞 传输模型 传输流程\n假设：3个工作进程，并发发送日志，日志长度分为为a,b,c 时刻 工作进程1 工作进程2 工作进程3 工作线程4 审计进程 1 发送日志 - - - - 2 - 发送日志 - - - 3 - 发送日志 - - 4 获取读锁 - - - - 5 - 获取读锁 - - - 6 - - 获取读锁 - - 7 预留空间指针 + a - - - - 8 - 预留空间指针 + b - - - 9 - - 预留空间指针 + c - - 10 - - - - 申请写锁 11 已发送指针 + a - - - - 12 - 已发送指针 + b - - - 13 - - 已发送指针 + c - - 14 释放读锁 - - - - 15 - - - 申请读锁 - 16 - 释放读锁 - - - 17 - - 释放读锁 - - 18 - - - - 获取写锁 19 - - - - 获取待落盘长度 a + b + c 20 - - - - 落盘 a + b + c 21 - - - - 已落盘指针 + a + b + c 22 - - - - 释放写锁 23 - - - 获取读锁 - 关闭审计时 postmaster线程，postgres线程，直接将日志暂存在1个大小为4k的公共的writer-buffer，当writer-buffer大小达到4k或间隔达到1秒，产生事件的线程直接将writer-buffer写至磁盘。\n阶段7 存储日志 audit-writer将日志存储至磁盘，在磁盘中，日志的存储结构如下图所示：\n其中，PageHeader格式如下：\ntypedef struct { uint16 version; /* version 1: the relative starting time of \u0026#39;pagetime\u0026#39; is \u0026#39;2020.1.1 ee:0o:eo\u0026#39; */ uint16 flags; uint16 datastart; uinti6 remainlen AuditTime pagetime; uint32 crc; uint32 noused; } AuditPageHeader; 阶段8 查询日志 审计特性，不提供在线删除日志功能。\n读写场景：对日志的访问，只有2种访问场景，postgres线程查询日志，audit-writer线程写入日志 读写冲突：对于日志文件，只有并发查询、追加写操作，二者可以完全不冲突。查询前，获取写入位置，类似快照的机制。查询时，查询到写入位置即结束，不往后继续查询。 3 接口说明 需求文档中，已详细介绍各接口，本文档不再重复介绍。\n编号 接口类型 变更 数量 细节 1 GUC 新增 6 enable_audit,audit_directory_size,audit_flush_policy等 2 SQL 变更 3 CREATE/ALTER/DROP AUDIT POLICY 3 CATALOG 新增 1 vb_adt_policy 4 FUNCTION 新增 4 vb_audit_log(sec/time),vb_audit_buffer_stat等 5 VIEW 新增 2 vb_audit_policy,vb_audit_log 6 工具 新增 1 vb_audit 7 工具 修改 2 vb_initdb, vb_dump 8 文件夹 新增 1 data_directory/vb_audit 9 文件 新增 n data_directory/vb_audit/日志文件 4 内存管理 日志缓存区\n启动集群时，在postmaster线程启动过程中，创建日志缓存区。退出集群时，才清理日志缓存区。 临时内存\n每次将事件格式化为日志时，临时申请1小块内存存放日志，并立即发送日志，发送后释放临时内存 5 安全 查询日志\n以下角色，有权查询日志： initial user superuser sysadmin (未开启三权分立的情况下) auditadmin vbadmin 6 性能 性能场景：tpcc，1000仓，300-500并发 性能要求： 基准：不开启审计 劣化场景一：开启审计，不创建审计策略，劣化低于1%（注册事件收集点） 劣化场景二：开启审计，创建审计策略，审计所有事件，日志异步落盘，劣化低于10% 劣化场景三：开启审计，创建审计策略，审计所有事件，日志同步落盘，劣化低于15%（为收集执行结果，日志发送时间较晚，待评估） 性能设计 线程通信：采用堆内存 并发控制：postgres线程并发发送日志，audit-writer线程存储日志，存在锁排队问题，后续版本继续分析优化 7 专利 通用性\n业界大部分关系数据库，都支持细粒度审计功能 Oracle：CREATE AUDIT POLICY SQL Server: CREATE DATABASE AUDIT SPECIFICATION GaussDB：CREATE AUDIT POLICY OceanBase：AUDIT 必要性 以tpcc为例，假设1分支执行60万次事务，至少生成60万次事件，约1秒至少产生1万个事件，过滤1万次。审计策略通常有几十条甚至更多。 本设计可提升过滤速度，平均提升10+倍 方案概述\n平均每个事件，可以少匹配几百个节点 8 升级管理 升级中：升级过程中，即upgrade_mode=1时，审计功能不记录任何事件。但会记录upgrade_mode取值变更的事件，据此可识别升级事件。 升级后： 编号 接口类型 变更 数量 细节 1 GUC 新增 4 enable_audit,audit_directory_size,audit_flush_policy等 2 GUC 修改 2 audit_buffer_size,audit_thread_num 3 GUC 删除 40 audit_login_logout,audit_dml_state,audit_user,audit_operation_result等 4 SQL 变更 3 CREATE/ALTER/DROP AUDIT POLICY 5 CATALOG 新增 1 vb_adt_policy 6 CATALOG 删除 5 gs_auditing_policy,gs_auditing_policy_access等 7 FUNCTION 新增 4 vb_audit_log(sec/time),vb_audit_buffer_stat等 8 FUNCTION 删除 7 pg_query_audit,pg_delete_audit,pg_query_audit_dump,pg_query_audit_info 9 VIEW 新增 2 vb_audit_policy,vb_audit_log 10 VIEW 删除 3 gs_audting,gs_auditing_access等 11 工具 新增 1 vb_audit 12 工具 修改 2 vb_initdb, vb_dump 13 文件夹 删除 1 data_directory/pg_audit 14 文件夹 新增 1 data_directory/vb_audit 15 文件 新增 n data_directory/vb_audit/日志文件 9 其他说明 postgresql函数hook -- aggregate CREATE FUNCTION f_add_a_int(state bigint[], val int) RETURNS bigint[] LANGUAGE sql AS $$ SELECT ARRAY[state[1] + val, state[2] + 1] $$; CREATE FUNCTION f_avg_final(state bigint[]) RETURNS numeric LANGUAGE sql AS $$ SELECT state[1]::numeric / state[2] $$; CREATE AGGREGATE a_int_avg(int) ( SFUNC = f_add_a_int, STYPE = bigint[], FINALFUNC = f_avg_final, INITCOND = \u0026#39;{0,0}\u0026#39; ); SELECT a_int_avg(v) FROM generate_series(1,6) v; -- bug: should audit a_int_avg DROP AGGREGATE a_int_avg(int); DROP FUNCTION f_add_a_int; DROP FUNCTION f_avg_final; -- function CREATE TABLE t1(c1 INT); CREATE FUNCTION f1() RETURNS INT AS $$ SELECT count(*)::INT FROM t1 $$ LANGUAGE sql; SELECT f1(); INSERT INTO t1 VALUES(f1()); DROP TABLE t1; DROP FUNCTION f1; # 场景一： InvokeFunctionExecuteHook fmgr_info | fmgr_info_cxt fmgr_info_cxt_security fn_addr = InitFunctionCallInfoData # 场景二：aggrage的入口函数 PostgresMain InitProcess for ;; ReadCommand case \u0026#39;Q\u0026#39;: exec_simple_query parse_query_auto_gram pg_analyze_and_rewrite pg_plan_queries PortalStart if \u0026#39;SELECT\u0026#39;: ExecutorStart # hook standard_ExecutorStart InitPlan ExecCheckRTPerms \u0026#39;新增 prev_hook\u0026#39; # 收集事件：DQL ExecCheckRTEPerms # hook ExecInitNode PortalRun if \u0026#39;SELECT\u0026#39;: PortalRunSelect ExecutorRun elif \u0026#39;INSERT/UPDATE/DELETE\u0026#39; or \u0026#39;DDL\u0026#39;: PortalRunMulti if \u0026#39;DML\u0026#39;: ProcessQuery if \u0026#39;INSERT/UPDATE/DELETE\u0026#39;: ExecutorStart # 已有hook standard_ExecutorStart InitPlan ExecCheckRTPerms \u0026#39;新增 prev_hook\u0026#39; # 收集事件：DML ExecCheckRTEPerms # 已有hook ExecutorRun # 已有hook standard_ExecutorRun ExecutePlan ExecutorFinish # 已有hook \u0026#39;audit_send_all_log(FAILED)\u0026#39; # 收集事件结果：操作成功 standard_ExecutorFinish ExecPostrocessPlan ExecutorEnd # 已有hook standard_ExecutorEnd ExecEndPlan ExecEndNode heap_close FreeExecutorState # delete query mem cxt elif \u0026#39;DDL\u0026#39;: PortalRunUtility ProcessUtility # 已有hook # 收集事件：DDL standard_ProcessUtility \u0026#39;audit_send_all_log(FAILED)\u0026#39; # 收集事件结果：执行成功 PortalDrop PortalCleanup if \u0026#39;SELECT\u0026#39;: ExecutorFinish # hook # 收集事件结果：操作成功 standard_ExecutorFinish ExecutorEnd # hook standard_ExecutorEnd finish_xact_command ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/5-design-g100-audit-refactor/","summary":"\u003ch1 id=\"g100审计功能重构\"\u003eG100审计功能重构\u003c/h1\u003e\n\u003ch1 id=\"1-功能简述\"\u003e1 功能简述\u003c/h1\u003e\n\u003cp\u003e在需求文档中，已详细介绍需求背景，此处不在重复介绍。\u003cbr\u003e\nG100 309之前版本，审计特性存在较多问题，因此，在本版本，将重新设计与实现审计特性，解决功能、性能、易用性、可维护性、可扩展性等问题，使审计特性达到大规模商用的标准。\u003c/p\u003e\n\u003ch1 id=\"2-实现方案\"\u003e2 实现方案\u003c/h1\u003e\n\u003ch2 id=\"一审计架构\"\u003e一、审计架构\u003c/h2\u003e\n\u003cp\u003e审计特性，核心子功能如下：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e配置审计：通过GUC参数，配置审计参数：日志目录、目录大小、日志文件淘汰策略等\u003c/li\u003e\n\u003cli\u003e设置范围：通过SQL语法，设置审计策略，控制哪些事件需审计。在策略中，可按用户、操作、对象、操作结果等过滤事件\u003c/li\u003e\n\u003cli\u003e收集事件：在代码关键节点，收集事件\u003c/li\u003e\n\u003cli\u003e过滤事件：根据审计策略，过滤无需审计的事件\u003c/li\u003e\n\u003cli\u003e生成日志：提取事件关键信息，生成日志\u003c/li\u003e\n\u003cli\u003e传输日志：工作线程，通过共享内存，传输日志给审计线程\u003c/li\u003e\n\u003cli\u003e存储日志：审计线程，组织日志，并将其存储至文件中。文件存放在单独的日志目录\u003c/li\u003e\n\u003cli\u003e查询日志：通过内置FUNCTION，在线查询日志，通过TOOL，离线查询日志\u003c/li\u003e\n\u003c/ol\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003e其中，设置范围、过滤事件子功能相对独立，可单独设计与实现，所以，拆分到另一个的设计文档中。\u003c/strong\u003e\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003e审计特性整体架构图如下：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"1-st\" loading=\"lazy\" src=\"/images/ProjectDocs/5-design-g100-audit-refactor/1-st.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"二工作流程\"\u003e二、工作流程\u003c/h2\u003e\n\u003cp\u003e收集事件的主体、操作、客体等信息时，因为需收集操作结果，即操作成功或失败，所以，很多场景中，收集事件需分为2个阶段：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e执行操作前：收集事件基本信息，包括操作类型等\u003c/li\u003e\n\u003cli\u003e执行操作后：收集事件的操作结果。对于出现ERROR的场景，则在异常处理函数中收集操作结果。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e在所有事件中，DML语句的事件稍复杂一点，此处主要以该类语句为例，梳理整体执行流程：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"2-fl\" loading=\"lazy\" src=\"/images/ProjectDocs/5-design-g100-audit-refactor/2-fl.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"三详细流程\"\u003e三、详细流程\u003c/h2\u003e\n\u003ch3 id=\"阶段1-配置审计进程启动\"\u003e阶段1 配置审计（进程启动）\u003c/h3\u003e\n\u003cp\u003e首先，用户通过GUC参数，配置审计文件管理等功能。然后，在系统启动阶段，审计模块将根据配置，初始化的各类关键资源，包括：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e日志文件：日志存储目录，初始日志文件等\u003c/li\u003e\n\u003cli\u003e审计内存：日志缓存区，内存上下文等\u003c/li\u003e\n\u003cli\u003e审计线程：信号处理函数等\u003c/li\u003e\n\u003cli\u003e事件收集节点：hook函数注册等\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e详细启动过程如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e    \u003cspan class=\"c1\"\u003e# 1. 启动vastbase进程\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eknl_instance_init\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eMemoryContextInit\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ePostmasterMain\u003c/span\u003e      \u003cspan class=\"c1\"\u003e# 2. 启动postmaster线程\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eSelectConfigFiles\u003c/span\u003e       \u003cspan class=\"c1\"\u003e# 3. 加载GUC参数\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003echeckDataDir\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"s1\"\u003e\u0026#39;audit_dir_init\u0026#39;\u003c/span\u003e        \u003cspan class=\"c1\"\u003e# 4. 创建审计日志文件目录\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"s1\"\u003e\u0026#39;audit_hook_init\u0026#39;\u003c/span\u003e       \u003cspan class=\"c1\"\u003e# 5. 注册审计回调函数：身份认证等\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eload_hba\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ereset_shared\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eCreateSharedMemoryAndSemaphores\u003c/span\u003e \u003cspan class=\"c1\"\u003e# （日志缓冲区不是共享内存，后文阶段6详细介绍）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eGlobalSysDBCache\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eInit\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eCreateLocalSysDBCache\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eInitRoleIdHashTable\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"s1\"\u003e\u0026#39;audit_comm_init\u0026#39;\u003c/span\u003e       \u003cspan class=\"c1\"\u003e# 6. 初始化审计内存上下文、日志缓存区，创建审计日志文件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"s1\"\u003e\u0026#39;initialize_util_thread(AUDIT_WRITER)\u0026#39;\u003c/span\u003e  \u003cspan class=\"c1\"\u003e# 7. 启动audit-writer 线程，持续读取日志缓冲区，等待接收与存储日志\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003einitialize_thread\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"o\"\u003e..\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"c1\"\u003e# ===== audit-writer 线程 ==============\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eGaussDbThreadMain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eInitShmemAccess\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eInitAuxiliaryProcess\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eCreateSharedMemoryAndSemaphores\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eGaussDBAuxiliaryThreadMain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003eBaseInit\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"s1\"\u003e\u0026#39;adt_writer_main\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"c1\"\u003e# ===== audit-writer 线程 ==============\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eServerLoop\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(;;)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003ecomm_select\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eConnCreate\u003c/span\u003e  \u003cspan class=\"c1\"\u003e# 9. 接收客户端连接\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eBackendStartup\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003einitialize_util_thread\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eWORKER\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003einitialize_thread\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"o\"\u003e..\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"c1\"\u003e# ===== postgres 线程 ==============\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003eGaussDbThreadMain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eknl_thread_init\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eInitializeGUCOptions\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eCreateLocalSysDBCache\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"s1\"\u003e\u0026#39;audit_hook_init\u0026#39;\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 10. 注册事件收集回调函数：计划执行、函数执行等回调点\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eBackendInitialize\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eBackendRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                        \u003cspan class=\"n\"\u003ePostgresMain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"c1\"\u003e# ===== postgres 线程 ==============\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"s1\"\u003e\u0026#39;initialize_util_thread(AUDIT_WRITER)\u0026#39;\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 11. 检查audit-writer 线程状态与自动重启\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"阶段2-设置范围\"\u003e阶段2 设置范围\u003c/h3\u003e\n\u003cp\u003e向用户提供SQL接口，用于创建审计策略。（见另一个设计文档）\u003c/p\u003e","title":"海量 5 设计 G100审计"},{"content":"1 简介 1.1 目的 审计特性：\n功能：收集数据库内的关键事件，例如启动集群、创建对象、查询数据等，根据事件生成与存储审计日志，向用户提供审计日志查询接口。 必要：从客户角度，使用审计特性，主要目的包括：合法合规、安全监控、事故调查等。从内核角度，为满足信创要求，数据库需达到CC标准，在CC标准中，对审计功能提出多项要求。 问题：G100审计特性存在多处设计缺陷，导致功能问题多、性能低、易用性差、可维护性差、可扩展性差等。到目前为止，其中累计识别50+缺陷，仍具有30+未识别缺陷。 历史：openGauss早期版本，华为以色列团队开发审计特性，交付标准为基本功能可用，与商用标准差距大。G100早期版本，由openGauss引入审计特性。在之后版本，G100进行多轮迭代。 本需求的目标是重构审计特性，解决功能、性能、易用性、可维护性、可扩展性等问题，使审计特性达到大规模商用的标准。\n1.2 适用范围 G100 3.0.8 psu5以及之后版本\n1.3 术语定义、首字母缩写词和缩略语 暂无 1.3 参考资料 原始需求：https://www.tapd.cn/tapd_fe/60475194/story/detail/1160475194001083526 国标查询下载网站： https://openstd.samr.gov.cn/bzgk/gb/index CC标准 《GB/T 20009-2019 信息安全技术 数据库管理系统安全评估准则》 《GB/T 20273-2019 信息安全技术 数据库管理系统安全技术要求》 信创标准 《SJ/T 11939-2024 安全可靠 集中式事务型数据库技术要求》 《T/AIA 016—2023信创产品测评 通用要求》 等保标准 《GB/T 25070-2019》信息安全技术 网络安全等级保护安全设计技术要求》 数据库政府采购标准：https://jx.mof.gov.cn/xxgk/zhengcefagui/202401/t20240105_3925117.htm 标准原文：微盘：https://drive.weixin.qq.com/s?k=AHUAfwdSAA87Z01xB G100审计特性：https://docs.vastdata.com.cn/zh_CN/VastbaseG100/V3.0.8/1/2f4fb0e4adcc49f8b19dd4710f2a6549 G100审计历史客户需求：https://www.tapd.cn/tapd_fe/60475194/story/list?sort_name=created\u0026amp;order=\u0026amp;useScene=storyList\u0026amp;groupType=\u0026amp;conf_id=1160475194001046742\u0026amp;queryToken=fe85cdfc29d23bba423905c15d72d127\u0026amp;page=1 Oracle审计特性：https://docs.oracle.com/en/database/oracle/oracle-database/23/dbseg/part_6.html 开源组件pgaudit：https://www.modb.pro/db/105894 需求分析与整理文档：语雀：https://www.yuque.com/u57264336/oav5h4/tkhcgdilcbpuqm09 2 G100审计功能重构 2.1 功能简述 一、需求背景：审计特性 审计目的：记录数据库内的各种事件，事件包括： 启动、恢复、切换、停止集群 登录、注销账号 创建、修改、删除数据库对象，包括：DATABASE、SCHEMA、TABLE等 插入、更新、删除、查询关系表 … 描述事件：每个事件中，有3个关键要素：\u0026lt;主体\u0026gt;\u0026lt;操作\u0026gt;\u0026lt;客体\u0026gt; 主体：一般是数据库用户 客体：集群、账号、DATABASE、SCHEMA、TABLE、FUNCTION等 操作：不同的客体，涉及的操作不一样。比如，对于TABLE，操作有：CREATE, INSERT, SELECT等。 审计日志：针对每个事件，收集与主体、操作、客体有关的信息，封装为1条审计日志。通常，1条审计日志中，包括的信息如下： 主体相关：用户名、客户端IP、会话ID等 操作相关：操作的类型、操作的时间、触发操作的SQL语句等 客体相关：客体类型、客体名称、客体属于哪个database、客体属于哪个schema 审计特性：为实现审计功能，在数据库内核中，需实现以下功能： 配置范围：对用户提供接口，配置需审计的事件范围 收集事件：在内核关键代码节点，发现事件，例如：登录用户、创建对象、查询数据等，收集主体、操作、客体相关信息 生成日志：按统一格式组织事件信息，生成审计日志 存储日志：将审计日志存储至磁盘 查询日志：对用户提供接口，查询日志 二、需求背景：G100审计特性（旧版本） G100早期版本，引入openGauss审计特性，但是，该特性存在较多问题，包括：\n功能问题多：已识别50+缺陷，未识别30+缺陷，其中，文件管理，并发管理问题较多 性能低：开启审计功能，启动单个审计线程，tpcc劣化90%以上 易用性差：审计功能分为传统审计、统一审计子功能，二者大部分功能重复，但大部分设计与代码独立。例如，传统审计通过30+GUC参数设置审计范围。统一审计通过SQL语法设置审计范围。 可维护性差：缺少模块化设计。代码多，代码分散，代码易读性差，部分功能设计较复杂 可扩展性差：新增审计事件，适配麻烦 此处，详细介绍传统审计、统一审计的差异：\n传统审计 配置审计功能：可配置：日志存储目录、日志文件轮转策略等\n设置审计范围：审计范围控制粒度粗。通过GUC参数控制是否审计某类事件\n# 示例，是否审计所有SELECT语法。 vb_guc set -D $VBDATA -c \u0026#34;audit_dml_state_select=on\u0026#34; 配置参数如下：\n按操作类型、客体类型（14个）\n参数 功能 audit_copy_exec 是否审计 COPY audit_dml_state 是否审计 INSERT、UPDATE、DELETE audit_dml_state_select 是否审计 SELECT audit_set_parameter 是否审计 SET audit_system_object 审计OBJECT的范围：DATABASE、SCHEMA、TABLE、…等CREATE、DROP、ALTER操作 audit_database_process 是否审计CLUSTER：启动、停止、切换和恢复 audit_function_exec 是否审计FUNCTION：执行 audit_systerm_function_exec 是否审计FUNCTION：执行（内核写了一个白名单，共61个，例如pg_stat_activity，pg_switch_xlog等） audit_crypt_func 是否审计FUNCION （密码运算函数） audit_security_policy 是否审计POLICY audit_transcation 是否审计TANSCATITON：提交、回滚 audit_login_logout 审计CLUSTER：{登录、注销} x {成功、失败} audit_user_locked 是否审计USER：锁定、解锁 audit_grant_revoke 是否审计USER：赋权、收权 按主体信息（3个）\n参数 功能 audit_user 对白名单内的用户进行审计 full_audit_users 对白名单内的用户的所有操作进行审计 no_audit_client 对黑名单内的IP的用户不审计 按操作结果（1个）\n参数 功能 audit_operation_result 只记录操作：成功、失败、成功和失败 的日志 其他（6个）\n参数 功能 audit_user_violation 是否越权操作 audit_network_error 是否审计网络连接错误 audit_query_cancel 是否审计用户取消SELECT操作 audit_insufficient_space 是否记录SPACE：达到限额 audit_tool_error 是否审计 vb_dump、vb_dumpall、vb_restore 的异常 audit_sequence_enabled 是否审计语句序列 传输审计日志：工作线程生成日志，通过管道，传输日志给审计线程，审计线程存储日志\n存储审计日志：将日志组织写入审计文件，审计文件存放在独立的审计目录\n统一审计： 配置审计功能：无法配置：日志存储目录、日志文件轮转策略等\n设置审计范围：通过SQL语法，控制是否审计指定的操作、对象、用户等，审计范围控制粒度细。例如，是否审计用户对表t1的SELECT操作，并过滤用户u1。\nCREATE RESOURCE LABEL rl1 ADD TABLE(t1); CREATE AUDIT POLICY ap1 ACCESS select ON LABEL(rl1) FILTER ON roles(u1); 传输审计日志：工作线程生成日志，直接存储，无审计线程\n存储审计日志：工作线程将日志写到syslog\n（照着Oracle抄，但根本没抄明白）\n三、需求背景：Oracle审计特性 Oracle审计特性迭代如下：\n8i以及更早版本：支持传统审计 12版本（2013年），新增支持统一审计，建议放弃传统审计，使用统一审计 23ai版本（2024年），不再支持传统审计，使用统一审计替代 使用统一审计替代传统审计的思路：\n传统审计：\n# 示例，是否审计所有SELECT语法。 vb_guc set -D $VBDATA -c \u0026#34;audit_dml_state_select=on\u0026#34; 统一审计：\nCREATE AUDIT POLICY ap1 ACCESS select; -- 后面不加其他 [用户、表名] 等过滤条件： Oracle统一审计语法如下：\nCREATE AUDIT POLICY ap1 PRIVILEGES privilege [ , privilege ..] -- privilege 子句，内置权限有200多种，示例：CREATE TABLE(可能是其他SQL，但使用到该权限), ALTER USER ACTIONS action [ , action ..] -- aciton 子句，示例：CREATE TABLE, SELECT,ALTER,DROP 。操作+对象组合，共有1900+ ON object [ , object ..] -- object 子句 ROLES role [ , role ..] -- role 子句 .. [其他不关键的子句] 四、需求范围：G100审计特性（新版本） 重构目标：新版本审计特性，解决功能、性能、易用性、可维护性、可扩展性等问题，使审计特性达到大规模商用的标准。 重构工作：与旧版本相比，90%代码完全重写，采用全新的接口、系统表、架构、文件格式等。同时，将删除部分无用的功能。 重构参考：保留的功能，主要参考以下标准。其中，对于一些标准中提及，优先级不高，但实现复杂的功能，本版本只完成设计，由以后版本实现。 CC标准 信创标准 等保标准 政府采购标准 Oracle审计特性 G100审计历史客户需求 重构设计：重构后，审计特性的几个关键设计如下： 配置审计：通过GUC参数，配置审计参数：日志目录、目录大小、日志文件淘汰策略等 设置范围：通过SQL语法，设置审计策略，控制哪些事件需审计。可创建1条或多条审计策略，在策略中，可按用户、操作、对象、操作结果、客户端IP等过滤事件。 收集事件：在代码关键节点，收集事件 生成日志：提取事件关键信息，生成日志 传输日志：工作线程，通过共享内存，传输日志给审计线程 存储日志：审计线程，以Page为粒度，组织日志，并存储至文件中。文件存放在单独的日志目录。 查询日志：通过内置FUNCTION，在线查询日志，通过TOOL，离线查询日志。 上述设计中，除实现基本功能外，为满足标准和部分客户的要求，需支持的相关功能如下：\n编号 流程 来源 描述 支持 1 1.配置审计 - - - 2 2.设置范围 CC 选择性审计 按需审计：用户、主机、操作类型、权限级别（系统、数据库、对象、细粒度权限等）、操作结果 支持：权限即对象类型 3 3.收集事件 CC 审计数据生成 事件类型：开启、关闭审计，启动、停止实例，修改GUC，修改对象结构，检查权限失败等 支持 6 3.收集事件 客户需求：红线要求 强制审计：未开启审计，记录启动、停止实例、修改GUC、创建、删除用户 支持 7 3.收集事件 客户需求 敏感事件：修改密码失败、拒绝会话 支持 8 3.收集事件 客户需求 序列审计：1个会话多个操作组成1个日志 暂不支持 4 4.生成日志 CC 审计数据生成 日志内容：事件类型、时间、用户、对象、客户端、操作结果 支持 5 4.生成日志 CC 用户身份关联 日志内容：数据库会话 支持 9 5.传输日志 客户需求：性能要求 审计性能：性能不能太低 支持 10 6.存储日志 CC 审计事件存储 功能失效：存储空间耗尽、失败、受攻击等，功能不失效，措施：忽略新日志、覆盖旧日志 支持 11 6.存储日志 CC 审计事件存储 日志防丢：支持审计数据批量传输到另一个系统 暂不支持：需对接es 12 6.存储日志 客户需求 日志保护：加密、校验 暂不支持 13 6.存储日志 客户需求 日志转存：转存（即归档）日志 暂不支持：疑似想要日志防丢 14 6.存储日志 客户需求：网专测试 日志保留：日志强制保留180天 支持 15 6.存储日志 客户需求 日志同步：日志同时存储至/var/log/message或/var/log/syslog 暂不支持 16 6.存储日志 内部识别 日志脱敏：不记录password等敏感信息 支持 17 6.存储日志 内部识别 同步落盘：提交事务时，等待事务产生的日志落盘（默认异步落盘） 支持 18 7.查询日志 CC 审计查阅 查询权限：授权用户 支持 19 7.查询日志 CC 审计查阅 查询权限：三权分立，防止系统管理员干扰审计日志 暂不支持：三权分立设计乱 20 7.查询日志 CC 审计查阅 查询方式：按条件过滤，如时间、用户等，可排序、搜索、筛选 支持 21 7.查询日志 内部识别 日志展示：支持图形化界面vem 支持 22 7.查询日志 内部识别 存储视图：查看日志存储空间占比 支持 部分客户需求如下：\n日志转存需求：https://www.tapd.cn/tapd_fe/60475194/story/detail/1160475194001025838 2.2 功能说明 2.2.1 使用流程 最简场景 从用户角度，执行以下步骤，可快速了解什么是审计。\n配置审计\nvb_guc set -D $VBDATA -c \u0026#34;enable_audit=on\u0026#34; # 开启审计功能，需重启集群使配置生效 设置范围\nCREATE AUDIT POLICY ap1 OPERATE CREATE,DROP; -- 审计所有操作为：CREATE、DROP的事件 收集事件、生成日志、传输日志、存储日志\nCREATE TABLE t1(c1 INT); -- 内核自动识别事件，生成与存储日志 查询日志\nSELECT * FROM vb_audit_log; optime | .. | subjname | optype | objtype | objname | .. -------------------------------+----+----------+--------+---------+---------+----- 2025-09-21 12:00:01.400009+08 | .. | shenkun | create | table | t1 | .. 其他操作\n用户基于审计日志，实现合法合规、安全监控、事故调查等。\n场景一、配置审计 功能：通过GUC参数，配置审计参数：日志目录、目录大小、日志文件淘汰策略等。\n本需求新增以下6个GUC参数：\n编号 参数名 默认值 取值范围 级别 功能 1 enable_audit off on,off postmaster 是否开启审计功能 2 audit_directory pg_audit 绝对路径、相对路径 postmaster 审计日志存储目录。如果取值为空，则默认存储于’数据目录/pg_audit’下 3 audit_directory_size 128M [64M,-] postmaster 审计日志目录最大空间 4 audit_directory_full_policy overwrite overwrite,stopwrite postmaster 目录达到最大空间，采取策略：覆盖最旧文件、忽略新日志 5 audit_buffer_size 16M [1M，1024M] postmaster 内存中，审计线程接收工作线程日志时，审计日志缓冲区大小 6 audit_flush_policy asnyc sync,asnyc postmaster 事务提交时，是否等待事务产生的日志落盘 7 audit_thread_num (待评估) 1 [1, 5] postmaster 审计写线程的数量，每个审计写线程，单独写审计文件。取值大于1时，需启动1个异步归并线程 开启审计功能\nvb_guc set -D $VBDATA -c \u0026#34;enable_audit=on\u0026#34; # 重启生效 配置审计目录\n默认存储于数据目录下pg_audit目录，可配置为其他目录\n# 1. 创建目录，假设新目录为 $new_dir # 2. 设置目录（以\u0026#39;/\u0026#39;开头，为绝对路径。不以\u0026#39;/\u0026#39;开头，为相对路径，相对于data_directory） vb_guc set -D $VBDATA -c \u0026#34;audit_directory=\u0026#39;$new_dir\u0026#39;\u0026#34; # 3. 重启生效 # 4. 查看目录 ll $new_dir # 预期结果：有日志文件产生 重启数据库\n让GUC生效\n配置其他GUC参数\naudit_directory_size、audit_directory_full_policy、audit_buffer_size、audit_flush_policy、audit_thread_num等，在后续场景详细介绍。\n场景二、设置范围 功能：通过SQL语法，设置审计策略，控制哪些事件需审计\n了解审计策略语法\nCREATE AUDIT POLICY policy_name -- [ROLE {all | role_lsit}] -- 1.按角色过滤（暂不支持） [USER { all | user_list }] -- 2.按用户过滤 [OPERATE { all | operate_list }] -- 3.按操作过滤 [ON { all | object_list }] -- 4.按对象过滤 [IN { all | in_object_list }] -- 4.按对象过滤：例如：IN DATABASE db1，表示db1中所有对象 [CLIENT { all | client_ip_or_host_list }] -- 5.按客户端过滤 [RESULT { all | { succeed | failed }}] -- 6.按操作结果过滤 创建审计策略：按用户过滤\n-- 针对单个用户 CREATE AUDIT POLICY ap1 USERS u1; -- 针对多个用户 CREATE AUDIT POLICY ap2 USERS u1,u2,u3; -- 针对所有用户（使用保留关键字ALL） CREATE AUDIT POLICY ap3 USERS all; -- 表示对所有操作都审计 -- 未主动指定的过滤条件，默认为all，即 OPERATE 默认为 all 创建审计策略：按操作过滤\n-- 针对操作 CREATE AUDIT POLICY ap1 OPERATE CREATE,DROP; -- 针对操作大类 CREATE AUDIT POLICY ap1 OPERATE ddl,dcl,dml,INSERT,SELECT; -- 查看可选操作（此处列出44种，来自E100，G100的待补充） SELECT * FROM pg_audit_operate; opscope | operates --------+-------------------------------------------------------------------------- dml | insert select update delete func | execute ddl | create alter drop import refresh lock declare close prepare deallocate listen unlisten notify comment load mng | truncate copy cluster reindex vacuum analzye explain checkpoint discard tcl | begin commit rollback release misc | fetch move 创建审计策略：按对象过滤\n-- 按 DATABASE 过滤 CREATE AUDIT POLICY ap2 ON DATABASE db1,db2; -- 按 SCHEMA 过滤，替换 ON 子句为： ON SCHEMA s1,s2 -- 按 TABLE 过滤，替换 ON 子句为： ON db1.public.t1 -- 或者： ON t1 -- t1为当前database下，当前schema下的t1 -- 按 DATABASE 过滤 IN DATABASE db1,db2; -- 按 SCHEMA 过滤 IN SCHEMA s1,s2 SELECT * FROM vb_audit_object; objid | objtype | objfilter ------+------------+---------- 1 | database | on,in 2 | schema | on,in 3 | tablespace | on,in 4 | user | on 5 | role | -- 该列为空，表示不支持过滤 6 | group | 7 | table | on 11 | view | on 8 | index | on 9 | function | on 10 | sequence | 10 | matview | 12 | trigger | ... | .. | 56 | extension | -- 完整的客体类型（此处列出56种，来自E100，G100的待补充） database schema tablespace user role group -- relation table index sequence view matview -- function function procedure trigger routine event_trigger constraint aggregate -- transcation transcation savepoint -- security policy security_lable -- others query plan fdw foreign_server foreign_table foreign_schema user_mapping publication subscription access_method operator operator_class operator_family domain type language largeobject collation conversion cast rule transform channel stats plang cursor portal ts_dic ts_coonfig ts_parser ts_template extension 创建审计策略：客户端过滤\nCREATE AUDIT POLICY ap4 CLIENT \u0026#39;192.168.0.10\u0026#39;,\u0026#39;192.168.0.11\u0026#39;,\u0026#39;host_1\u0026#39;; 创建审计策略：按操作结果过滤\nCREATE AUDIT POLICY ap5 RESULT succeed,failed; 创建审计策略：组合过滤\n上述过滤条件，可2种或多种随意组合\nCREATE AUDIT POLICY ap5 USERS u1,u2 OPERATE INSERT,UPDATE ON t1,t2 CLIENT \u0026#39;192.168.0.10\u0026#39; RESULT succeed,failed; 查看审计策略\n-- 查看系统表 SELECT * FROM vb_adt_policy; -- 示例输出 polname | polsubjname | poloptype | polopres | polobjtype | polobjname | polcliip | status --------+-------------+-----------+----------+------------+------------+----------+--------- ap1 | | 1,2 | 0 | 0 | | | enable /* 解释 polname: 策略名 polsubjname: 用户名 poloptype：操作类型 polopres: 操作结果 polobjtype: 客体类型 polobjname：客体名称 polcliip：客户端类型 status: 策略是否启用 */ -- 查看视图 SELECT * FROM pg_audit_policy; policy | users | actions | objtype | objects | result | status -------+--------+-------------+---------+----------+---------+-------- ap1 | | create,drop | table | t1,t2 | | enable 修改审计策略\nCREATE AUDIT POLICY ap_old USERS u1,u2 OPERATE INSERT,UPDATE ON t1,t2; ALTER AUDIT POLICY ap_old USERS all -- 已有过滤类型：可设置为all OPERATE INSERT -- 已有过滤类型：可修改范围 CLIENT \u0026#39;192.168.0.10\u0026#39;; -- 新增过滤额类型 -- 已有过滤类型：如果未主动指定，则保持原样，例如 ON t1,t2 保持原样 停止审计策略\nALTER AUDIT POLICY ap1 DISABLE; 启用审计策略\nALTER AUDIT POLICY ap1 ENABLE; 删除审计策略\n一次DROP一个或多个，可设置IF EXISTS参数。\nDROP AUDIT POLICY IF EXISTS ap1,ap2,ap3; 场景三、收集事件 功能：在代码关键节点，收集事件。此处，需了解什么场景会产生事件。\n熟悉事件类型\n系统事件\n系统事件，属于强制审计事件，即使不开启审计时，也会生成审计日志。\n编号 主体 操作 客体 事件线程 收集阶段 触发示例 1 用户 启动 集群 postmaster 线程启动 vb_ctl start .. 2 用户 停止 集群 postmaster 线程退出 vb_ctl stop .. 3 用户 登录 集群 postgres 身份认证 vsql -d database .. 4 用户 登出 集群 postgres 线程退出 \\q 或 超时等 5 用户 修改 配置 postgres SQL执行 alter system set .. 安全事件\n安全事件，也属于强制审计事件。大部分由用户执行SQL产生：\nCREATE USER ALTER USER DROP USER GRANT REVOKE CREATE ROLE ALTER ROLE DROP ROLE ... SQL事件\n由用户执行SQL产生的事件（不包括用户、权限相关的事件，此类事件单独归到安全事件中）。一个事件可描述为：主体、操作、客体。\n主体：通常为用户名\n操作：操作类型如下：\n-- 参考以下SQL执行结果 SELECT * FROM vb_audit_operate; 客体：客体类型如下：\n-- 参考以下SQL执行结果 SELECT * FROM vb_audit_object; 熟悉SQL与事件的对应关系（对象级审计）\n大部分情况下，执行1条SQL，产生1个事件。也有一些情况，执行1条SQL，多个1个事件。\nCREATE TABLE t1(c1 INT); -- 操作：create，客体类型：table，客体：t1 INSERT INTO t1 VALUES(3); -- 操作：insert，客体类型：table，客体：t1 CREATE TABLE t2 AS SELECT * FROM t1; -- 操作：create，客体类型：table，客体：t2 -- 操作：select，客体类型：table，客体：t1 SELECT * FROM t1 JOIN t2 ON t1.c1 = t2.c1; -- 操作：select，客体类型：table，客体：t1 -- 操作：select，客体类型：table，客体：t2 场景四、生成日志 功能：提取事件关键信息，生成日志。\n查看日志字段\nCREATE TABLE t2 AS SELECT * FROM t1; SELECT * FROM vb_audit_log; -- 示例输出（共2行） ------------+-------------[record 1] optime | 2025-09-21 12:00:01.400009+08 -- 操作时间 apolicy | ap1 -- 策略名称：生成本条日志的策略 scope | ddl -- 操作分类：例如ddl,dml,dql等 subjname | shenkun -- 操作用户 optype | create -- 操作类型 objtype | table -- 客体类型 objname | t2 -- 客体名称 cliip | 10.44.136.83 -- 客户端IP或HOST cliport | 39850 -- 客户端端口 cliapp | vsql -- 客户端类型：即连接参数applicatiion_name opresult | succeed -- 操作结果：成功或失败 objdb | vastbase -- 客体所属database objnsp | public -- 客体所属schema opxid | 0 -- 操作的xlog id optid | 0 -- 操作的事务id opthreadid | 489 -- 操作的线程id opsessid | 1986 -- 操作的会话id sql | CREATE TABLE t2 AS SELECT * FROM t1; -- 原始SQL语句 extra | -- 其他信息：例如报错信息 ------------+-------------[record 2] optime | 2025-09-21 12:00:01.639529+08 apolicy | ap2 scope | dml subjname | shenkun optype | select objtype | table objname | t1 cliip | 10.44.136.83 cliport | 39850 cliapp | vsql opresult | succeed objdb | vastbase objnsp | public opxid | 0 optid | 0 opthreadid | 489 opsessid | 1986 sql | (repeat) extra | 场景五、传输日志 功能：工作线程，通过共享内存，传输日志给审计线程。可通过GUC参数，控制与传输相关的参数。\n设置日志缓冲区大小\n参考机器配置，参考wal_buffer大小设置\nvb_guc set -D $VBDATA -c \u0026#34;audit_buffer_size=16\u0026#34; # 单位为M # 预期结果：即使400+工作线程产生日志，audit_buffer_size仅16M，也能正常工作 设置审计线程数\nvb_guc set -D $VBDATA -c \u0026#34;audit_thread_num=2\u0026#34;; 重启数据库，并生成一些日志\n查看审计缓冲区统计信息\n为提高可维护性，本需求参考xlog，新增1个视图，用于查询审计日志缓存区的信息。\nSELECT * FROM pg_audit_buffer_stat(); -- 示例输出 bufid | buffiled | value --------+-------------+------------------------------------------------- 0 | writer_tid | 6891 -- 负责将buffer数据写到磁盘的审计写线程的id 0 | total_size | 128M -- buffer总大小 0 | dirty_size | 3.1M -- buffer中待写入的大小 0 | alloc_pos | 19888998 -- 从启动开始算，buffer已接收的日志总长度 0 | write_pos | 19887004 -- 从启动开始算，buffer已落盘的日志总长度 0 | write_file | adt_2025_0922_120001_124581_writing_0.blog -- 存储buffer数据的文件 1 | writer_tid | 6892 1 | total_size | 128M 1 | dirty_size | 9.8M 1 | alloc_pos | 20016510 1 | write_pos | 20064020 1 | write_file | adt_2025_0922_120001_124581_writing_1.blog 场景六：存储日志 查看审计目录\nshow audit_directory; 查看审计文件\nll $audit_directory -- 示例输出（4类文件）： adt_2025_0922_120401_424581_writing_1.blog # 状态1：正在写 adt_2025_0922_120401_424581_writing_2.blog adt_2025_0922_120201_139900_unmerged_1.blog # 状态2：已写完，待归并 adt_2025_0922_120201_139900_unmerged_2.blog adt_2025_0922_120201_139900_merging.blog # 临时文件：归并中产生的 adt_2025_0922_120001_980431.blog # 状态3：已归并 场景七：查询日志 在线查询审计日志\n-- 查看日志：从最早日志开始，查看最多10000条日志 SELECT * FROM vb_audit_log; -- 查看日志：指定时间区间 vb_audit_log(timestamptz begitime, timestamptz endtime); SELECT * FROM vb_audit_log(\u0026#39;2020-01-01 12:00:00\u0026#39;, NOW()); -- 查看日志：指定最近几秒内的日志 vb_audit_log(int seconds); SELECT * FROM vb_audit_log(3); 离线查询日志\nvb_audit decode -d $audit_directory -o ./decode_dir # 预期输出：decode_dir下，日志文件与$audit_directory数量一致，文件以.log结尾，内容都是解码后的日志，与select pg_audit_log() 查询格式几乎一致 扩展场景一：收集事件：强制审计 要求：未开启审计，记录启动、停止实例、修改GUC、创建、删除用户\n关闭审计\nvb_guc set -D $VBDATA -c \u0026#34;enable_audit=off\u0026#34; 重启数据库\n创建与删除用户\nCREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; DROP USER u1; 修改GUC参数\n只能识别通过ALTER SYSTEM SET修改GUC，无法识别通过vb_guc set修改GUC。\n（gaussdb做法：每个工具本身也产生日志，比如vb_guc.log）\nALTER SYSTEM SET password_effect_time=10; 查询审计日志\nSELECT optype,objtype,objname FROM vb_audit_log; -- 预期输出 optype | objtype | objname ---------+---------+----------------------- startup | system | create | user | u1 drop | user | u1 alter | system | password_effect_time 扩展场景二：收集事件：敏感事件 敏感事件：修改密码失败、拒绝会话\n修改密码失败\nCREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; CREATE USER u2 PASSWORD \u0026#39;u2.password\u0026#39;; -- 场景1：密码不合法 ALTER USER u1 PASSWORD \u0026#39;password\u0026#39;; -- 场景2：无权限修改 SET ROLE u1 PASSWORD \u0026#39;u1.password\u0026#39;; ALTER USER u2 PASSWORD \u0026#39;u2.ne2pass\u0026#39;; 查看日志\nSELECT optype,objtype,objname,opres FROM vb_audit_log WHERE optype = \u0026#39;alter\u0026#39;; -- 预期输出 optype | objtype | objname | opres --------+---------+---------+------- alter | user | u1 | failed alter | user | u1 | failed 登录失败\nvsql -d vastbase -U u1 -W \u0026#39;u1.wrongpass\u0026#39; # 使用错误密码 查看日志\nSELECT optype,objtype,objname,opres FROM vb_audit_log; -- 预期输出 optype | objtype | objname | opres --------+---------+---------+------- login | user | u1 | failed 扩展场景三：传输日志：审计性能 要求：性能不能太低\n确定测试方法\n此处，以标准tpcc为例： 1000仓 300-500并发 性能要求 场景一：不开启审计\n场景二：开启ddl审计\nCREATE AUDIT POLICY ap1 OPERATE create,alter,drop,import,refresh; -- 可继续添加其他ddl 预期：与场景一相比，劣化不高于5% 场景三：开启全审计\nCREATE AUDIT POLICY ap1 OPERATE all; 预期：与场景一相比，劣化不高于20% 场景四：开启全审计，创建大量策略\nCREATE AUDIT POLICY ap1 OPERATE all; -- 创建大量无效策略 CREATE AUDIT POLICY ap2 USERS u1 OPERATE create; CREATE AUDIT POLICY ap3 USERS u2 OPERATE create; CREATE AUDIT POLICY ap4 USERS u3 OPERATE create,insert,select; -- 省略 .... (自行构造) 预期：与场景一相比，劣化不高于20% 扩展场景四：存储日志：日志保留 要求：存储空间耗尽、失败、受攻击等，功能不失效，措施：忽略新日志、覆盖旧日志\n要求：日志强制保留180天（从数据库角度，无法强制保留，只能以后版本支持将日志传输到另一系统，让客户自行保留）\n设置审计目录最大值\nvb_guc set -D $VBDATA -c \u0026#34;audit_directory_size=10240\u0026#34; # 单位M # 预期结果：日志文件总大小，始终不会超过设定值 设置日志目录写满策略\nvb_guc set -D $VBDATA -c \u0026#34;audit_directory_full_policy=\u0026#39;overwrite\u0026#39;\u0026#34; # 覆盖最旧日志 重启数据库，产生大量日志\n预期结果：最旧的日志文件被删除，继续生成新日志\n设置日志目录写满策略\nvb_guc set -D $VBDATA -c \u0026#34;audit_directory_full_policy=\u0026#39;stopwrite\u0026#39;\u0026#34; # 停止写最新日志 重启数据库，产生大量日志\n预期结果：最旧的日志文件还在，停止生成新日志\n扩展场景六：存储日志：日志脱敏 要求：不记录password等敏感信息\n执行敏感操作\nCREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; ALTER USER u1 PASSWORD \u0026#39;u1.newpass\u0026#39;; SELECT gs_encrypt_aes128(\u0026#39;plaindata\u0026#39;,\u0026#39;i_am_password\u0026#39;); -- 复用G100已有脱敏机制，支持对多种敏感数据脱敏 查看审计日志\nSELECT optype,objname,sql FROM vb_audit_log; -- 示例输出： optype | objname | sql ---------+---------------------+------------------------------------------------------------ create | u1 | CREATE USER u1 PASSWORD \u0026#39;*********\u0026#39; alter | u1 | ALTER USER u1 PASSWORD \u0026#39;*********\u0026#39; execute | gs_encrypt_aes128 | SELECT gs_encrypt_aes128(\u0026#39;plaindata\u0026#39;,\u0026#39;***********\u0026#39;) 扩展场景七：存储日志：日志落盘 要求：提交事务时，等待事务产生的日志落盘（默认异步落盘）\n设置日志同步落盘\nvb_guc set -D $VBDATA -c \u0026#34;audit_flush_policy=\u0026#39;sync\u0026#39;\u0026#34; 重启数据库\n连续生成日志，并构造异常\nvsql -d vastbase -c \u0026#34;CREATE TABLE t1(c1 INT)\u0026#34; # 连续生成日志（建议用c语言并发执行） for i in $(seq 1 10000); do echo \u0026#34;INSERT INTO t1 VALUES($i);\u0026#34;; done | vsql -d vastbase # 执行到一半 # 构造数据库异常 kill -9 `pidof vastbase` 查询审计日志\nSELECT * FROM t1; SELECT * FROM vb_audit_log(100); -- 预期输出：所有t1中能查到的数据，vb_audit_log中均记录了日志 设置日志异步落盘\nvb_guc set -D $VBDATA -c \u0026#34;audit_flush_policy=\u0026#39;async\u0026#39;\u0026#34; 重启数据库\n连续生成日志，并构造异常\n重复步骤3\n查询审计日志\nSELECT * FROM t1; SELECT * FROM vb_audit_log(100); -- 预期输出：t1中能查到的数据，vb_audit_log中可能存在未记录审计日志的情况 扩展场景八：查询日志：查询权限 要求：授权用户才可查询日志\n以下角色，有权查询日志：\ninitial user\nsuperuser\nsysadmin (未开启三权分立的情况下)\nauditadmin\nCREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39; AUDITADMIN; vbadmin\nGRANT vbadmin TO u2; set role u2 password \u0026#39;u2.password\u0026#39;; GRANT u2 TO u3; -- 继承角色也可以 扩展场景八：查询日志：日志展示 要求：支持图形化界面vem\nvem需对接，g100旧版本中，vem已对接审计。新版本中，vem需修改查询日志的函数名。\n扩展场景九：查询日志：存储视图 要求：存储视图：查看日志存储空间占比\n查看审计目录使用情况\nSELECT * FROM pg_audit_directory_stat(); -- 示例输出 dirfiled | value -------------+------------ total_zie | 100G used_size | 52.8G file_num | 1050 full_policy | overwrite oldest | adt_2025_0301_120201_139900.blog latest | adt_2025_0925_113133_589181_writing_0.blog 交互场景一：vsql \\h vsql查看 CREATE AUDIT POLICY用法\n\\h CREATE AUDIT POLICY vsql查看 ALTER AUDIT POLICY用法\n\\h ALTER AUDIT POLICY vsql查看 DROP AUDIT POLICY用法\n\\h DROP AUDIT POLICY 交互场景二：vb_dumpall 创建审计策略\nCREATE AUDIT POLICY ap1 USERS u1,u2 OPERATE create,drop; 导出审计策略\nvb_dumpall -p 5432 --audit-only -f adt.sql 恢复审计策略\nvsql -d vastbase -p 5432 -c \u0026#34;DROP AUDIT POLICY ap1\u0026#34; vsql -d vastbase -p 5432 -f adt.sql # 预期结果：恢复ap1成功 交互场景三：其他 物理备份恢复：支持备份、恢复AUDIT POLICY，默认支持，无需单独适配。 逻辑复制：不支持同步审计策略 异常场景一：语法异常 设置不存在的过滤对象\nCREATE AUDIT POLICY ap1 USERS u1,u2 -- 假设 u1 不存在，报错 OPERATE INSERT,UPDATE -- 假设是奇怪的操作类型，比如dump，报错 ON t1,t2 -- 假设 t1 不存在，报错 CLIENT \u0026#39;192.168.0.10\u0026#39; RESULT succeed,failed; 异常场景二：配置异常 假设以下异常，会导致数据库无法启动\n编号 参数名 默认值 取值范围 级别 功能 1 enable_audit off on,off postmaster 是否开启审计功能 2 audit_directory pg_audit 绝对路径、相对路径 postmaster 审计日志存储目录。如果取值为空，则默认存储于’数据目录/pg_audit’下 3 audit_directory_size 128M [64M,-] postmaster 审计日志目录最大空间 4 audit_directory_full_policy overwrite overwrite,stopwrite postmaster 目录达到最大空间，采取策略：覆盖最旧文件、忽略新日志 5 audit_buffer_size 16M [1M，1024M] postmaster 内存中，审计线程接收工作线程日志时，审计日志缓冲区大小 6 audit_flush_policy asnyc sync,asnyc postmaster 事务提交时，是否等待事务产生的日志落盘 7 audit_thread_num (待评估) 1 [1, 5] postmaster 审计写线程的数量，每个审计写线程，单独写审计文件。取值大于1时，需启动1个异步归并线程 异常场景三：运行异常 异常场景 描述 预期结果 进程异常 kill 审计线程 自动重启线程，不影响业务，日志不丢失 文件异常 audit_direcotry运行时异常 审计功能异常，无法记录审计日志，不影响业务 文件异常 audit log已写完文件丢失 查询日志时，缺少部分日志，影响不大 文件异常 audit log正在写文件丢失 自动重新创建文件，不影响业务 2.2.2 配置参数和文件 此次变更接口较多，统一在”2.3接口信息”中介绍。\n2.2.3 数据相关性 无\n2.3 接口信息 本需求变更接口较多，以下为变更项统计信息：\n编号 接口类型 变更 数量 细节 1 GUC 新增 4 enable_audit,audit_directory_size,audit_flush_policy等 2 GUC 修改 2 audit_buffer_size,audit_thread_num 3 GUC 删除 40 audit_login_logout,audit_dml_state,audit_user,audit_operation_result等 4 SQL 变更 3 CREATE/ALTER/DROP AUDIT POLICY 5 CATALOG 新增 1 vb_adt_policy 6 CATALOG 删除 5 gs_auditing_policy,gs_auditing_policy_access等 7 FUNCTION 新增 4 vb_audit_log(sec/time),vb_audit_buffer_stat等 8 FUNCTION 删除 7 pg_query_audit,pg_delete_audit,pg_query_audit_dump,pg_query_audit_info 9 VIEW 新增 2 vb_audit_policy,vb_audit_log 10 VIEW 删除 3 gs_audting,gs_auditing_access等 11 工具 新增 1 vb_audit 12 工具 修改 2 vb_initdb, vb_dump 13 文件夹 删除 1 data_directory/pg_audit 14 文件夹 新增 1 data_directory/vb_audit 15 文件 新增 n data_directory/vb_audit/日志文件 一、GUC 新增4个GUC\n编号 参数名 默认值 取值范围 级别 功能 1 enable_audit off on,off postmaster 是否开启审计功能 2 audit_directory_size 128M [64M,-] postmaster 审计日志目录最大空间 3 audit_directory_full_policy overwrite overwrite,stopwrite postmaster 目录达到最大空间，采取策略：覆盖最旧文件、忽略新日志 4 audit_flush_policy asnyc sync,asnyc postmaster 事务提交时，是否等待事务产生的日志落盘 修改3个GUC含义\n编号 参数名 默认值 取值范围 级别 功能 1 audit_directory pg_audit 绝对路径、相对路径 postmaster 审计日志存储目录。如果取值为空，则默认存储于’数据目录/pg_audit’下 2 audit_buffer_size 16M [1M，1024M] postmaster 内存中，审计线程接收工作线程日志时，审计日志缓冲区大小 3 audit_thread_num (待评估) 1 [1, 5] postmaster 审计写线程的数量，每个审计写线程，单独写审计文件。取值大于1时，需启动1个异步归并线程 删除30个GUC\n配置审计\n编号 参数名 参数含义 变更 1 audit_enabled 是否开启审计功能 删除 - audit_directory 文件目录 保留 2 audit_backup_directory 文件备份目录 删除 3 audit_dump_directory 文件归档目录 删除 4 audit_resource_policy 什么场景删除旧日志：达到时间限制还是总大小限制 删除 5 audit_space_limit 文件夹总大小 删除：由audit_directory_size替代 6 audit_file_remain_time 日志保留时间 删除 7 audit_file_remain_threshold 初始化索引文件时，文件数量最大值 删除 8 audit_rotation_interval 生成新文件时，时间间隔 删除 9 audit_rotation_size 生成新文件时，文件大小阈值 删除：改为固定值 10 audit_stop_policy 文件大小或时间达到阈值时，删除旧日志，还是停止写新日志 删除 11 vb_audit_space_alarm_threshold 是否对文件大小达到阈值时告警 删除 12 get_auditindex_file_lock 读取索引文件时，不加锁（只是为了测性能时不加锁） 删除 13 audit_data_format 日志格式，仅支持二进制 删除 14 audit_hash_enabled 日志中是否记录哈希值 删除 15 audit_xid_info 日志中是否记录xid 删除 配置审计线程\n编号 参数 功能 变更 - audit_thread_num 写日志的线程数 保留 - audit_buffer_size 日志缓存大小 保留 16 audit_buffer_fflush_interval 日志缓存刷盘间隔 删除：自动控制 配置审计范围\n主体\n编号 参数 功能 变更 17 audit_user 对白名单内的用户进行审计 删除 18 full_audit_users 对白名单内的用户的所有操作进行审计 删除 19 no_audit_client 对黑名单内的IP的用户不审计 删除 操作\n编号 参数 功能 变更 20 audit_copy_exec 是否审计 COPY 删除 21 audit_dml_state 是否审计 INSERT、UPDATE、DELETE 删除 22 audit_dml_state_select 是否审计 SELECT 删除 23 audit_set_parameter 是否审计 SET 删除 24 audit_user_violation 是否越权操作 删除 25 audit_operation_result 只记录操作：成功、失败、成功和失败 的日志 删除 26 audit_network_error 是否审计网络连接错误 删除 27 audit_query_cancel 是否审计用户取消SELECT操作 删除 28 audit_insufficient_space 是否记录SPACE：达到限额 删除 29 audit_tool_error 是否审计 vb_dump、vb_dumpall、vb_restore 的异常 删除 客体\n编号 参数 功能 变更 30 audit_system_object 审计OBJECT的范围：DATABASE、SCHEMA、TABLE、…等CREATE、DROP、ALTER操作 删除 31 audit_database_process 是否审计CLUSTER：启动、停止、切换和恢复 删除 32 audit_function_exec 是否审计FUNCTION：执行 删除 33 audit_systerm_function_exec 是否审计FUNCTION：执行（内核写了一个白名单，共61个，例如pg_stat_activity，pg_switch_xlog等） 删除 34 audit_sequence_enabled 是否审计语句序列 删除 35 audit_crypt_func 是否审计FUNCION （密码运算函数） 删除 36 audit_security_policy 是否审计POLICY 删除 37 audit_transcation 是否审计TANSCATITON：提交、回滚 删除 38 audit_login_logout 审计CLUSTER：{登录、注销} x {成功、失败} 删除 39 audit_user_locked 是否审计USER：锁定、解锁 删除 40 audit_grant_revoke 是否审计USER：赋权、收权 删除 2 SQL 变更 CREATE AUDIT POLICY 新版本\nCREATE AUDIT POLICY policy_name [USER { all | user_list }] -- 按用户过滤 -- [ROLE {all | role_lsit}] -- 暂不支持：按角色过滤 [OPERATE { all | operate_list }] -- 按操作过滤 [ON { all | object_list }] -- 按对象过滤 [IN { all | in_object_list }] -- 按对象过滤：例如：IN DATABASE db1，表示db1中所有对象 [CLIENT { all | client_ip_or_host_list }] -- 按客户端过滤 [RESULT { all | { succeed | failed }}] -- 按操作结果过滤 user_list: user_name [, user_name, ..] operate_list: opereate_or_scope [, opereate_or_scope, ..] opereate_or_scope: | create | drop | insert | execute | ... -- 查看可选的operate：SELECT * FROM vb_audit_operate() | { ddl | dcl | dml | dql | func | tcl } object_list: | table_name [, table_name, ..] | TABLE table_name [, table_name, ..] | DATABASE database_name [, database_name, ..] | SCHEMA schema_name [, schema_name, ..] | FUNCTION function_name [, function_name, ..] | DATABASE all | SCHEMA all | FUNCTION all in_object_list: | DATABASE database_name [, database_name, ..] | SCHEMA schema_name [, schema_name, ..] client_ip_or_host_list: ip_or_host [, ip_or_host, ..] 旧版本\nCREATE AUDIT POLICY [ IF NOT EXISTS ] policy_name { | { { privilege_audit_clause | access_audit_clause } [ filter_group_clause ] [ ENABLE | DISABLE ] [normally | warning | block] } | [ sequence_audit_clause ] [normally | warning | block ] }; privilege_audit_clause: PRIVILEGES { DDL | ALL } [ ON LABEL ( resource_label_name [, ... ] ) ] access_audit_clause: ACCESS { DML | ALL } [ ON LABEL ( resource_label_name [, ... ] ) ] -- LABLE 由 CREATE RESOURCE LABLE .. resource_type(item,item,..)语法创建 -- resource_type取值： TABLE | COLUMN | SCHEMA | VIEW | FUNCTION filter_group_clause: FILTER ON { ( FILTER_TYPE ( filter_value [, ... ] ) ) [, ... ] } sequence_audit_clause: SEQUENCE BY [\u0026#39;SQL\u0026#39;] DDL: { ( ALTER | ANALYZE | COMMENT | CREATE | DROP | GRANT | REVOKE | SET | SHOW ) } DML: { ( COPY | DEALLOCATE | DELETE_P | EXECUTE | REINDEX | INSERT | PREPARE | SELECT | TRUNCATE | UPDATE ) } FILTER_TYPE: { APP | ROLES | IP | TIME_PERIOD } 3 CATALOG 新增1个系统表\nSELECT * FROM vb_adt_policy; -- 详细输出：场景二：设置范围 删除5个系统表\n编号 名称 功能 变更 1 gs_auditing_policy 存储审计策略 删除 2 gs_auditing_policy_access 存储审计策略中的操作 删除 3 gs_auditing_policy_privileges 存储审计策略中的权限 删除 4 gs_auditing_policy_filters 存储审计策略中的用户、客户端等 5 gs_auditing_policy_sequence 存储序列审计 删除 4 FUNCTION 新增4个内置函数\nvb_audit_log(timestamptz begintime, timestamptz endtime); -- 详细输出：场景四：生成日志 vb_audit_log(int seconds); pg_audit_buffer_stat(); -- 详细输出：场景五：传输日志 pg_audit_directory_stat(); -- 详细输出：扩展场景九：存储视图 删除7个内置函数\n编号 名称 功能 变更 1 pg_query_audit 查询审计日志 删除 2 pg_query_audit_dump 查询dump目录（归档目录下）的审计日志 删除 3 pg_query_audit_info - 删除 4 login_audit_messages - 删除 5 login_audit_messages_pid - 删除 6 pg_audit_logsize_warning - 删除 7 audit_analyze_offsite_landing - 删除 5 VIEW 新增2个视图\nCREATE VIEW pg_audit_policy AS SELECT .. FROM vb_adt_policy; -- 详细输出：场景二：设置范围 CREATE VIEW pg_audit_log AS SELECT * FROM pg_audit_log(\u0026#39;2020-01-01\u0026#39;, NOW()); 删除3个视图\n编号 名称 功能 变更 1 gs_auditing 审计策略 删除 2 gs_auditing_access 存储审计策略中的操作 删除 3 gs_audit_privilege 存储审计策略中的权限 删除 6 TOOL 新增1个工具\nvb_audit -h # 输出如下： vb_audit is a utility to process audit log. usage: vb_audit decode [options] vb_audit print [options] [options] could be: -h,-?, --help show this help, then exit -v, --version show the version of this tool, then exit -d, --direcotry=LOG_DIR directory of audit logs -f, --file=LOG_FILE audit log file -o, --output=DIR_OR_FILE used with the --direcotry or --file parameter -b, --begin-time=BEGIN_TIME the earliest audit log, format example: \u0026#39;2020/01/01 12:00:00\u0026#39; -e, --end-time=END_TIME the latest audit log 修改2个工具\n# vb_initdb中，设置审计加密算法、加密密钥的参数，不再生效 vb_initdb -D ./data --audit_encrypt_algorithm=SM4 --audit_master_key=\u0026#34;MTIzNDVhYmNLZEBBQkNERQ==\u0026#34; --audit_encrypt_key=\u0026#34;MTIzNDVhYmNLZEBBQkNERQ==\u0026#34; # vb_dumpall 新增参数--audit-only，支持导出审计策略 vb_dumpall -p 5432 --audit-only -f adt.sql 7 FILE 新增1个文件夹\n数据目录/vb_audit # 存储审计日志，可通过GUC参数设置为其他目录 废弃1个文件夹\n数据目录/vb_audit # 旧版本审计存储审计日志的默认路径 2.4 正反向行为 2.4.1 生效说明 2.4.2 提示信息 报错\n2.4.3 约束和依赖 无\n2.5 安全性 2.5.1 权限控制 以下角色，有权查询日志：\ninitial user superuser sysadmin (未开启三权分立的情况下) auditadmin vbadmin 2.5.2 审计 无\n2.6 影响范围 2.6.1 对已有UDT,UDF, ECPG的影响 无\n2.6.2 对系统函数的影响 详情见：2.3接口信息章节\n2.6.3 对系统CATALOG的影响 详情见：2.3接口信息章节\n2.6.4 对xlog日志格式、数据格式的影响 无\n2.6.5 与其他功能交互时的行为表现 无\n2.6.6 版本兼容性 接口变更较多，无法前向兼容\n2.6.7 用户行为变更 此次变更接口较多，统一在”2.3接口信息”中介绍。\n2.7 指标相关 2.7.1 关键资源指标 CPU：最差情况，1条SQL语句，生成1条日志 线程：不开启审计功能，未新增线程。开启审计功能，默认启动1个审计写线程。 内存：全局内存：审计日志缓存区大小为16M-1G。临时内存：每次生成日志时，需临时申请一段内存，大小一般为100多字节。 网络：无 磁盘：审计日志文件夹下，会存储大量审计日志。tpcc 1000仓场景，如果审计所有SQL，大小约为600多G 2.7.2 系统性指标 无\n2.7.3 性能指标 详情见：扩展场景：审计性能\n2.8 测试建议 参考E100审计测试方案。\n2.9 其他说明 审计策略语法 新版本 方式一：与oracle一致\nCREATE AUDIT POLICY ap1 PRIVILEGES privilege [ , privilege ..] -- privilege 子句，内置权限有200多种，示例：CREATE TABLE(可能是其他SQL，但使用到该权限), ALTER USER ACTIONS action [ , action ..] -- aciton 子句，示例：CREATE TABLE, SELECT,ALTER,DROP 。操作+对象组合，共有1900+ ON object [ , object ..] -- object 子句 ROLES role [ , role ..] -- role 子句 方式二：与opengauss一致\nCREATE AUDIT POLICY policy_name PRIVILEGES { DDL | ALL } -- DDL操作类型 ON LABEL resource_label_name [, ... ] -- 对象 ACCESS { DML | ALL } -- DML操作类型 ON LABEL resource_label_name [, ... ] -- 对象 FILTER ON FILTER_TYPE filter_value [, ... ] -- 过滤类型：用户、IP等 -- DDL: ALTER | ANALYZE | COMMENT | CREATE | DROP | GRANT | REVOKE | SET | SHOW -- DML: COPY | DEALLOCATE | DELETE_P | EXECUTE | REINDEX | INSERT | PREPARE | SELECT | TRUNCATE | UPDATE -- FILTER_TYPE: APP | ROLES | IP | TIME_PERIOD 方式三：便于理解版\nCREATE AUDIT POLICY $ap_name WHERE subjname = \u0026#39;u1\u0026#39; AND scope = \u0026#39;ddl\u0026#39; AND optype in (\u0026#39;create\u0026#39;, \u0026#39;drop\u0026#39;) AND objtype = \u0026#39;table\u0026#39; AND objname != (\u0026#39;t1\u0026#39;, \u0026#39;t2\u0026#39;, \u0026#39;t3\u0026#39;); -- 优化：创建group CREATE GROUP g1 TYPE user MEMBER u1,u2,u3; CREATE GROUP g2 TYPE operate MEMBER create,drop; CREATE AUDIT POLICY $ap_name WHERE subjname = g1 AND scope = \u0026#39;ddl\u0026#39; AND optype = g2 AND objtype = \u0026#39;table\u0026#39; AND objname != (\u0026#39;t1\u0026#39;, \u0026#39;t2\u0026#39;, \u0026#39;t3\u0026#39;); -- 传统审计： CREATE AUDIT POLICY $ap_nam WHERE optype in (\u0026#39;create\u0026#39;, \u0026#39;drop\u0026#39;); ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/5-requirement-g100-audit-refactor/","summary":"\u003ch1 id=\"1-简介\"\u003e1 简介\u003c/h1\u003e\n\u003ch2 id=\"11-目的\"\u003e1.1 目的\u003c/h2\u003e\n\u003cp\u003e审计特性：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e功能：收集数据库内的关键事件，例如启动集群、创建对象、查询数据等，根据事件生成与存储审计日志，向用户提供审计日志查询接口。\u003c/li\u003e\n\u003cli\u003e必要：从客户角度，使用审计特性，主要目的包括：合法合规、安全监控、事故调查等。从内核角度，为满足信创要求，数据库需达到CC标准，在CC标准中，对审计功能提出多项要求。\u003c/li\u003e\n\u003cli\u003e问题：G100审计特性存在多处设计缺陷，导致功能问题多、性能低、易用性差、可维护性差、可扩展性差等。到目前为止，其中累计识别50+缺陷，仍具有30+未识别缺陷。\u003c/li\u003e\n\u003cli\u003e历史：openGauss早期版本，华为以色列团队开发审计特性，交付标准为基本功能可用，与商用标准差距大。G100早期版本，由openGauss引入审计特性。在之后版本，G100进行多轮迭代。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e本需求的目标是重构审计特性，解决功能、性能、易用性、可维护性、可扩展性等问题，使审计特性达到大规模商用的标准。\u003c/p\u003e\n\u003ch2 id=\"12-适用范围\"\u003e1.2 适用范围\u003c/h2\u003e\n\u003cp\u003eG100 3.0.8 psu5以及之后版本\u003c/p\u003e\n\u003ch2 id=\"13-术语定义首字母缩写词和缩略语\"\u003e1.3 术语定义、首字母缩写词和缩略语\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e暂无\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"13-参考资料\"\u003e1.3 参考资料\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e原始需求：\u003ca href=\"https://www.tapd.cn/tapd_fe/60475194/story/detail/1160475194001083526\"\u003ehttps://www.tapd.cn/tapd_fe/60475194/story/detail/1160475194001083526\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e国标查询下载网站： \u003ca href=\"https://openstd.samr.gov.cn/bzgk/gb/index\"\u003ehttps://openstd.samr.gov.cn/bzgk/gb/index\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eCC标准\n\u003cul\u003e\n\u003cli\u003e《GB/T 20009-2019 信息安全技术 数据库管理系统安全评估准则》\u003c/li\u003e\n\u003cli\u003e《GB/T 20273-2019 信息安全技术 数据库管理系统安全技术要求》\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e信创标准\n\u003cul\u003e\n\u003cli\u003e《SJ/T 11939-2024 安全可靠 集中式事务型数据库技术要求》\u003c/li\u003e\n\u003cli\u003e《T/AIA 016—2023信创产品测评 通用要求》\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e等保标准\n\u003cul\u003e\n\u003cli\u003e《GB/T 25070-2019》信息安全技术 网络安全等级保护安全设计技术要求》\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e数据库政府采购标准：\u003ca href=\"https://jx.mof.gov.cn/xxgk/zhengcefagui/202401/t20240105_3925117.htm\"\u003ehttps://jx.mof.gov.cn/xxgk/zhengcefagui/202401/t20240105_3925117.htm\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e标准原文：微盘：\u003ca href=\"https://drive.weixin.qq.com/s?k=AHUAfwdSAA87Z01xB\"\u003ehttps://drive.weixin.qq.com/s?k=AHUAfwdSAA87Z01xB\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eG100审计特性：\u003ca href=\"https://docs.vastdata.com.cn/zh_CN/VastbaseG100/V3.0.8/1/2f4fb0e4adcc49f8b19dd4710f2a6549\"\u003ehttps://docs.vastdata.com.cn/zh_CN/VastbaseG100/V3.0.8/1/2f4fb0e4adcc49f8b19dd4710f2a6549\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eG100审计历史客户需求：\u003ca href=\"https://www.tapd.cn/tapd_fe/60475194/story/list?sort_name=created\u0026amp;order=\u0026amp;useScene=storyList\u0026amp;groupType=\u0026amp;conf_id=1160475194001046742\u0026amp;queryToken=fe85cdfc29d23bba423905c15d72d127\u0026amp;page=1\"\u003ehttps://www.tapd.cn/tapd_fe/60475194/story/list?sort_name=created\u0026amp;order=\u0026amp;useScene=storyList\u0026amp;groupType=\u0026amp;conf_id=1160475194001046742\u0026amp;queryToken=fe85cdfc29d23bba423905c15d72d127\u0026amp;page=1\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eOracle审计特性：\u003ca href=\"https://docs.oracle.com/en/database/oracle/oracle-database/23/dbseg/part_6.html\"\u003ehttps://docs.oracle.com/en/database/oracle/oracle-database/23/dbseg/part_6.html\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e开源组件pgaudit：\u003ca href=\"https://www.modb.pro/db/105894\"\u003ehttps://www.modb.pro/db/105894\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e需求分析与整理文档：语雀：\u003ca href=\"https://www.yuque.com/u57264336/oav5h4/tkhcgdilcbpuqm09\"\u003ehttps://www.yuque.com/u57264336/oav5h4/tkhcgdilcbpuqm09\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-g100审计功能重构\"\u003e2 G100审计功能重构\u003c/h1\u003e\n\u003ch2 id=\"21-功能简述\"\u003e2.1 功能简述\u003c/h2\u003e\n\u003ch3 id=\"一需求背景审计特性\"\u003e一、需求背景：审计特性\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e审计目的：记录数据库内的各种事件，事件包括：\n\u003cul\u003e\n\u003cli\u003e启动、恢复、切换、停止集群\u003c/li\u003e\n\u003cli\u003e登录、注销账号\u003c/li\u003e\n\u003cli\u003e创建、修改、删除数据库对象，包括：DATABASE、SCHEMA、TABLE等\u003c/li\u003e\n\u003cli\u003e插入、更新、删除、查询关系表\u003c/li\u003e\n\u003cli\u003e…\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e描述事件：每个事件中，有3个关键要素：\u0026lt;主体\u0026gt;\u0026lt;操作\u0026gt;\u0026lt;客体\u0026gt;\n\u003cul\u003e\n\u003cli\u003e主体：一般是数据库用户\u003c/li\u003e\n\u003cli\u003e客体：集群、账号、DATABASE、SCHEMA、TABLE、FUNCTION等\u003c/li\u003e\n\u003cli\u003e操作：不同的客体，涉及的操作不一样。比如，对于TABLE，操作有：CREATE, INSERT, SELECT等。\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e审计日志：针对每个事件，收集与主体、操作、客体有关的信息，封装为1条审计日志。通常，1条审计日志中，包括的信息如下：\n\u003cul\u003e\n\u003cli\u003e主体相关：用户名、客户端IP、会话ID等\u003c/li\u003e\n\u003cli\u003e操作相关：操作的类型、操作的时间、触发操作的SQL语句等\u003c/li\u003e\n\u003cli\u003e客体相关：客体类型、客体名称、客体属于哪个database、客体属于哪个schema\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e审计特性：为实现审计功能，在数据库内核中，需实现以下功能：\n\u003cul\u003e\n\u003cli\u003e配置范围：对用户提供接口，配置需审计的事件范围\u003c/li\u003e\n\u003cli\u003e收集事件：在内核关键代码节点，发现事件，例如：登录用户、创建对象、查询数据等，收集主体、操作、客体相关信息\u003c/li\u003e\n\u003cli\u003e生成日志：按统一格式组织事件信息，生成审计日志\u003c/li\u003e\n\u003cli\u003e存储日志：将审计日志存储至磁盘\u003c/li\u003e\n\u003cli\u003e查询日志：对用户提供接口，查询日志\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"二需求背景g100审计特性旧版本\"\u003e二、需求背景：G100审计特性（旧版本）\u003c/h3\u003e\n\u003cp\u003eG100早期版本，引入openGauss审计特性，但是，该特性存在较多问题，包括：\u003c/p\u003e","title":"海量 5 需求 G100审计"},{"content":" 1 审计特性介绍 1.1 核心功能 1.2 整体架构（308.3） 1.3 工作流程（308.3） 1.4 文件组织 2 使用审计特性 2.1 配置审计特性 2.2 启动数据库 2.3 生成审计日志 2.4 查询审计日志 2.5 异常管理 3 审计特性变更点 3.1 问题分析 2.2 重构目标 2.3 问题分析（当前版本） 一、存储日志慢 二、检索日志慢 三、文件问题多 2.4 重构方案 一、存储日志重构 二、检索日志 2.5 重构开销 2.6 重构影响 2.7 性能测试 3 审计特性详细设计 3.1 架构设计 一、整体架构 二、工作流程 三、文件组织 3.2 详细设计 一、配置审计特性 二、审计文件管理 三、 启动数据库 四、生成审计日志 五、存储审计日志 六、审计日志一致性 七、归并审计日志 八、查询审计日志 4 审计后续重构计划 摘要\n介绍审计特性，分析性能问题，提出优化方案，评审优化方案，规划其他计划\n1 审计特性介绍 1.1 核心功能 审计特性：记录数据库内的各种事件，事件包括：\n启动、恢复、切换、停止集群 登录、注销账号 创建、修改、删除数据库对象，包括：DATABASE、SCHEMA、TABLE等 插入、更新、删除、查询关系表 … 描述事件：数据库内发生的事件，都可描述为\u0026lt;主体\u0026gt;\u0026lt;操作\u0026gt;\u0026lt;客体\u0026gt;\n主体：一般是数据库用户 客体：集群、账号、数据对象等 操作：不同客体操作类型不一样。比如，对于TABLE，操作类型有：CREATE, INSERT, SELECT等。 审计日志：针对每个事件，审计模块都会生成一条或多条审计日志，审计日志中记录事件关键信息，包括：\n主体信息：用户名、客户端IP、登入的数据库名、线程id等 操作信息：操作的类型、操作的时间、操作的SQL语句等 客体信息：客体类型、客体名称、客体属于哪个database、客体属于哪个schema 1.2 整体架构（308.3） 审计架构如下图所示，按模块划分，可将审计划分为5个模块：\n管理模块：管理审计配置，相关配置由GUC控制，可分为3类：审计范围、日志传输、审计文件。管理审计内存、锁等资源，启停审计线程 事件模块：发生关键事件时，如启停集群、执行SQL语句等，收集事件关键信息，即主体、操作、客体关键信息，将各类事件封装为统一格式的审计日志，并将其发送至审计线程 存储模块： 审计写线程：接收审计日志，按文件格式组织日志，将日志存储至文件中。如果有多个写线程，每个写线程都有独立的日志缓冲区、日志文件。同一时间段内生成的多条日志，可能存储于多个文件中 审计归并线程：读取同一时间段内多个审计文件，排序日志，合并为同1个审计文件 文件模块：管理多种状态的审计文件，包括：正在写、待归并、已归并等 查询模块： 在线查询：通过内置函数，查询一段时间内的日志 离线查询：通过离线工具，解析二进制格式的日志文件 1.3 工作流程（308.3） 审计特性的工作流程如下图所示：\n用户：通过GUC参数，配置审计特性，包括审计范围、日志传输、审计文件等。 主线程：启动审计线程 工作线程：在关键流程中，收集审计事件。以执行DML为例，审计处理流程包括： 在清理计划阶段，收集审计事件，事件包括主体、操作、客体等信息。然后，将事件封装为日志后，发送给审计写线程。由审计线程负责将日志落盘 在事务提交阶段，如果开启日志同步落盘机制，则等待审计线程将日志落盘 审计writer线程：不断将接收到的日志写至磁盘 审计merger线程：存在多个审计写线程的情况下，将同一时间段内的多个已写完的文件，合并为1个文件 1.4 文件组织 在存在多个writer线程的场景，日志文件有3种状态：\n正在写：writer线程正在写的文件 已写完：writer线程已写完的文件，merger未归并或者归并中 已归并：merger归并多个已写完的文件，生成的最终文件 1个审计文件，由多个page组成。1个page由header和多条log组成，log可跨page存储\n2 使用审计特性 2.1 配置审计特性 开启审计特性\nvb_guc set .. \u0026#34;audit_enable=on\u0026#34; 设置文件管理参数\n# 1 日志目录 vb_guc set .. \u0026#34;audit_directory=\u0026#39;/pato/to/audit_log\u0026#39;\u0026#34; # 2 归档目录 vb_guc set .. \u0026#34;audit_dump_directory=on\u0026#34; # 3 日志目录空间限制 vb_guc set .. \u0026#34;audit_space_limit=10G\u0026#34; 设置日志同步参数\n2.2 启动数据库 2.3 生成审计日志 2.4 查询审计日志 2.5 异常管理 3 审计特性变更点 3.1 问题分析 关键问题：目前，客户使用审计特性时，最严重的2个问题如下：\n性能问题：开启审计特性，设置审计范围包括DML，TPCC测试，单个审计线程性能劣化90%以上（不开审计40w+，开DML审计2-3w） 功能问题：审计缺陷数量多，已识别缺陷20+，未识别的缺陷至少20+，很多缺陷会导致集群coredump、无法启动等 审计来源：opengauss审计特性来源：\n2019年，华为高斯以色列团队向国内交付审计demo 2020年，高斯2名新员工将demo交付到gaussdb，并开源到opengauss 2021年-2024年，高斯陆续有3人全职解决审计的问题单，至少50+，包括5+现网问题 2.2 重构目标 提高审计性能：以tpcc场景为例，1主1备，1000仓，500并发： 基线：默认不开启审计特性 场景一：开启审计特性，设置关键设计范围，审计DDL等，不审计DML，性能劣化很小，在5%以内 场景二：开启审计特性，设置最大审计范围，审计DDL等，xxDML、SELECT等，性能劣化可控，在20% 降低审计缺陷 重构前：曾解决10+审计文件类问题，未识别问题10+。因设计太复杂，无法控制风险 重构后：审计文件管理类问题，新增问题不超过5。简化设计，风险可控 2.3 问题分析（当前版本） 在审计架构中，主要线程分为业务线程、审计线程。\n一般情况下，业务线程生成日志，通过管道将日志发送给审计线程，审计线程存储日志至审计文件。\n在分析问题时，为方便描述，本章以常规tpcc为例，假设：并发数为400，审计线程数为20，1个事务执行3次UPDATE。\n一、存储日志慢 线程、管道、文件的数量关系如下：\n线程数：400个业务线程，默认1个审计线程，最高可配置48个。二者使用管道通信 管道数：管道数与审计线程数相等 文件数：每个审计线程，都独立写文件，即正在写的文件数与审计线程数相等 当前方案，存在多个设计问题。以常规tpcc为例，假设：：\n编号 设计 方案 问题 1 线程通信 管道 平均20个业务线程，使用1个管道，管道很容易满。线程阻塞、上下切换等开销高 2 IO模型 同步IO 1个事务执行3次UPATE，生成3条日志，阻塞等待3次管道空闲、管道传输、日志落盘 3 IO粒度 Record级 同1时刻，20个并发，20个事务，生成60条日志，需串行等待60次IO 4 加密粒度 Record级 同1时刻，20个并发，20个事务，生成60条日志，需串行加密60次，哈希60次 二、检索日志慢 目前，用户只能通过SQL语句检索日志，查询出的日志，默认情况不是按时间顺序排列的：\nSELECT query_audit(\u0026#39;开始时间\u0026#39;， \u0026#39;结束时间\u0026#39;)； 存储日志时，存在多个问题。\n日志分布（多文件）：20个审计线程，分别写20个审计文件。同一时刻，400个业务线程，生成的日志被随机写入20个文件中。 日志顺序（乱序）：假设，在时刻1，线程1生成日志1，但是发生线程切换。在时刻2，线程2生成日志2，并存储至文件中。在时刻3，日志1落盘。此时，日志1先生成，但是后落盘 文件信息（索引文件）：1个数据库节点，维护1个审计索引文件，索引文件记录所有日志关键的生成时间 如下图所示，不同线程写不同日志文件，每个日志文件写完，生成新的日志文件：\n检索日志时，流程如下：\n用户查询：指定’开始时间’、’结束时间’查询日志 查找文件：遍历索引文件，判断所有日志文件的’创建时间’，找到符合条件的日志文件。（20审计线程，最少需查找20个文件） 查找日志：分别遍历每个日志文件，判断所有日志的’生成时间’，找到符合条件的日志（假设1个文件64M = 8192 * 8k） 检索结果中，日志并不是按时间顺序排列的。\n三、文件问题多 在存储日志时，生成新日志文件，需更新索引文件。检索日志时，需遍历索引文件。索引文件丢失、损坏等，集群无法正常运行。但是，索引文件存在以下问题：\n无备份 无一致性保证：无双写机制 只初始1次：第1次使用审计，生成1次索引文件，与初始化约10万个索引节点，不可扩张。即最多可生成10万个日志文件。 2.4 重构方案 一、存储日志重构 新方案中，线程、管道、文件的数量关系如下：\n线程数：400个业务线程，只需1个审计线程即可。参考wal-writer设计 管道数：删除管道通信机制。参考wal-buffer设计 文件数：同1时刻，只有1个正在写的日志文件 针对各关键设计，重构思路如图所示：\n重构方案如下：\n编号 设计点 旧方案 新方案 优化分析 1 线程通信 管道 堆内存 参考wal-buffer，新增alog-buffer，业务线程直接将日志写入alog-buffer。同1时刻，20个线程无需阻塞等待管道串行传输，直接将日志写入alog-buffer 2 IO模型 同步IO 异步IO 参考wal-writer，同1时刻，20个并发，20个事务执行共60次UPDATE，无需串行阻塞等待60次管道传输、日志落盘，只需60次将日志写入alog-buffer，并在提交事务时，检查20次日志是否已落盘，理论上阻塞次数小于5次 3 IO粒度 record级 page级 参考wal-writer，1次落盘1个或多个page。 同1时刻，20个并发，20个事务，生成60条日志，无需串行等待60次IO，只需按page执行1次或多次IO即可 4 加密粒度 record级 page级 同1时刻，20个并发，20个事务，生成60条日志，需串行加密60次，哈希60次，只需按page执行1次加密、哈希即可 二、检索日志 存储日志时，重构思路如下：\n日志分布（单文件）：同一时刻，400个业务线程，生成的日志，被写入同1日志文件，或者下1个日志文件中 日志顺序（顺序）：每个日志文件中，日志严格按照从前往后的顺序排列。参考xlog按照lsn顺序排列。 文件信息（系统表）：新增系统表，vb_audit_files，记录每个审计日志的创建时间。另外，还可记录是否归档、是否备份等信息。 另外，还有以下优化：\n日志页：引入日志页的概念。1个日志文件，由多个日志页组成，1个日志页记录多条日志。页头记录：日志版本、日志时间、加密参数、LSN、上一个日志页未存完的日志长度等信息。 文件命名：旧方案中命名方式是1_adt, 2_adt, 3_adt, ..，新方案以时间为文件命名。例如adt_2025-0501-1200-00.log 新系统表内容如下，其中，aftime列记录日志文件创建时间，该列上建立btree索引：\nSELECT * FROM vb_audit_files; afnum | aftime | afname | isarchive | isbackup | isencrypt ------+---------------------+-------------------------+-----------+----------+----------- 1 | 2025-04-20 12:00:00 | adt_2025_0420_1200_0000 | false | fasle | false 2 | 2025-04-20 12:01:23 | adt_2025_0420_1201_2300 | false | fasle | false -- 1T日志文件，系统表总大小1M -- 计算：1个日志文件64M，64T有1024 * 1024个文件，系统表有1024 * 1024条记录，假设1条记录64字节。 重构思路如下图所示：\n检索日志时，流程如下：\n用户查询：指定’开始时间’、’结束时间’查询日志 查找文件：使用btree索引，从系统表vb_audit_files中查找符合条件的日志文件 查找日志：在日志文件中，使用二分查找，先获取文件第1个、最后1个日志页，判断日志页时间，最多需要13次IO（假设1个文件64M = 8192 * 8k） 2.5 重构开销 预估重构开销：\n工作量：2人月 代码量：3k 质量提升：提前规避30+问题，包括现网问题。降低问题发现、定位、修复时间 2.6 重构影响 删除审计索引文件\n重构审计日志文件：文件名变化，文件内容变化（使用page和record机制）。旧版本日志文件，仅在检索审计日志时被读取\nGUC配置参数：删除部分\n审计线程\n参数 功能 变化 audit_thread_num 写日志的线程数 删除 audit_buffer_size 日志缓存大小 删除，参考wal-buffer设置 audit_buffer_fflush_interval 日志缓存刷盘间隔 删除，参考wal-writer设置 日志格式\n参数 功能 变化 audit_data_format 日志格式，仅支持二进制 删除 audit_hash_enabled 日志中是否记录哈希值 - get_acl_for_audit 是否从系统表中，获取当前操作对象的ACL信息 - audit_xid_info 日志中是否记录xid - 日志文件\n参数 功能 变化 audit_space_limit 文件总空间 - audit_directory 文件目录 - audit_dump_directory 文件复制目录 - audit_backup_directory 文件备份目录 - audit_file_remain_threshold 文件数量最大值（问题大） 删除 audit_file_remain_time 日志保留时间 - audit_rotation_interval 生成新文件的时间间隔 删除 audit_stop_policy 文件大小或时间达到阈值时，删除旧日志，还是停止写新日志 删除 audit_resource_policy 文件阈值类型，大小还是时间 删除 audit_rotation_size 生成新文件的文件大小阈值 删除，使用默认值 64M vb_audit_space_alarm_threshold 是否对文件大小达到阈值时告警 删除 get_auditindex_file_lock 读取索引文件时，不加锁（只是为了测性能时不加锁） 删除 系统表：新增vb_audit_files\n2.7 性能测试 测试场景：tpcc, 1000仓，1主1备，400并发\n场景一：不开启审计特性 场景二：开启审计特性，默认审计范围，不审计DML 场景三：开启审计特性，最大审计范围，审计DML 测试流程：\nssh shenkun@172.16.103.90 # gauss@123 不开审计：43.3857，cpu利用率80% 39.4989 开审计：3.19，cpu利用率80% 3 审计特性详细设计 3.1 架构设计 一、整体架构 二、工作流程 三、文件组织 3.2 详细设计 一、配置审计特性 当前版本中，与审计相关的GUC参数有近60个，本次重构中，主要修改文件管理、线程管理相关参数，修改点如下：\n文件目录管理\n编号 变更 参数名 功能 参数类型 数据类型 取值范围 默认值 变更点 1 - audit_directory 审计文件路径 postmaster 字符串 绝对路径或相对路径 pg_audit - 2 - vb_audit_dump_directory 审计文件归档路径，audit_directory目录下的旧文件，定期move到归档路径 postmaster 字符串 绝对路径 空 - 3 删除 vb_audit_backup_directory 审计文件备份路径，audit_directory目录下新增文件，同时再copy到vb_audit_backup_directory目录 postmaster 字符串 绝对路径 空 删除 4 删除 audit_resource_policy 审计目录下，所有日志文件总阈值，是按时间，还是按文件大小 sighup bool on,off on 删除 5 删除 audit_file_remain_time 审计目录下，保留一段时间内的日志文件 sighup int [0,730] day 90 删除 6 修改 audit_space_limit 审计目录下，保留日志文件总大小 sighup int [1024,1073741824] kb 1048576(1GB) 修改：取值范围为[1MB, 1TB]，默认1GB 7 删除 audit_file_remain_threshold 审计目录下，保留日志文件数量 sighup int [100, 1048576] 1048576 删除 8 删除 vb_audit_space_alarm_threshold 审计空间达到阈值前，提前在pg_log告警 sighup double [0,1] 0 删除 文件管理\n编号 变更 参数名 功能 参数类型 数据类型 取值范围 默认值 变更点 9 删除 audit_data_format 审计文件格式，只支持2进制 postmaster 字符串 binary binary 删除 10 删除 audit_rotation_interval 创建新审计文件的时间间隔 sighup int [1, 35791394] min 1440 (1day) 删除 11 删除 vb_audit_stop_policy 日志文件总大小达到阈值，是停止写入新日志，还是保留旧日志 sighup bool on,off off 删除 12 删除 audit_rotation_size 单个日志文件最大值 sighup int [1024, 1048576] KB 10240 (10 MB) 删除 线程管理\n编号 变更 参数名 功能 参数类型 数据类型 取值范围 默认值 变更点 13 修改 audit_thread_num 审计线程数 postmaster int [1,48] 1 修改：取值范围[1, 10] IO管理\n编号 变更 参数名 功能 参数类型 数据类型 取值范围 默认值 变更点 14 删除 vb_audit_buffer_size_kb 将日志写到buffer中，不直接write postmaster int [0, 51200] kb 0 15 删除 vb_audit_buffer_fflush_interval_sec 定期对buffer中的日志进行write sighup [1,1800] s 120 删除 16 删除 vb_enable_get_auditindexfile_lock 每次write时，对索引文件加锁，为了检查有人修改系统时间 sighup bool on,off on 删除 17 新增 audit_buffer_size 日志缓冲区大小 postmaster int [1M, 1G] 64M 新增 18 新增 audit_sync_log 事务提交时，是否确保审计日志同步落盘 postmaster bool true, false false 新增 审计范围管理\n通过GUC参数，设置哪类事件需被审计。相关控制参数较多，设计混乱，由于时间限制，不在本次重构范围内：\nvb_audit_crypt_func vb_audit_sequence_enabled vb_enable_get_acl_for_audit audit_login_logout audit_database_process audit_user_locked audit_user_violation audit_grant_revoke audit_user full_audit_users no_audit_client audit_user audit_system_object audit_dml_state audit_dml_state_select audit_function_exec audit_system_function_exec audit_copy_exec audit_set_parameter audit_xid_info vb_audit_insufficient_space vb_audit_network_error vb_audit_query_cancel vb_audit_tool_error vb_enable_separation_of_duty enable_nonsysadmin_execute_direct enable_access_server_directory vb_audit_transaction_enabled 其他审计参数\nvb_audit_hash_enabled 其他 二、审计文件管理 审计文件夹 由GUC参数audit_direcotry控制，默认存储在data_directory/pgaudit目录 审计文件 背景：\n有2种类型的文件\n|-- audit_direcotry |-- adt_2025_0420_1200_0000.blog # 已归并的日志 |-- adt_2025_0420_1201_1234.blog |-- adt_unmerge_2025_0420_1203_2222.blog # 正在写的日志，多个写线程， |-- adt_unmerge_2025_0420_1203_2222.blog |-- adt_unmerge_2025_0420_1203_2222.blog 三、 启动数据库 四、生成审计日志 PostgresMain exec_simple_query(sql) # 1. 执行SQL parse_query_auto_gram() # 2. 解析语法、分析语义、重写查询、生成计划 pg_analyze_and_rewrite() pg_plan_queries() PortalRun(plan) # 3. 执行计划 ... ExecutorRun(plan) ExecutorEnd(plan) # 4. 清理计划 # ------------------------------------------------------------------------------- pos = audit_dml(plan) # 5. DML审计 event = parse_plan(plan.rte) # 5.1 生成事件：从执行计划、会话控制等中获取信息 log = assemble_event(event) # 5.2 封装日志 pos = send_log(log) # 5.3 发送日志 buf = get_buffer() # 随机获取1个adtbuffer并缓存，1个事务复用1个adtbuffer buf = (buf == NULL ? get_random_buffer() : buf) pos = copy_log(buf, log) read_lock_buffer(buf) # 获取读锁 spin_lock_buffer(buf) # 申请空间，返回偏移 pos = buf.sendpos buf.sendpos += pos # 偏移一直在递增 time = current_time() # 偏移越大，时间越大 spin_unlock_buffer(buf) memcpy(buf, log， pos % buf.size) read_unlock_buffer(buf) # 释放读锁 finish_xact_command() # 5. 提交事务 CommitTranscationCommand() XLogFlush(XactLastRecEnd) # 等待本事务最后1条xlog落盘 # ---------------------------------------------------- audit_flush(pos) # 如果设置了同步落盘日志：等待本事务最后1条adtlog落盘 五、存储审计日志 audit_main(buf) for (;;) write_lock_buffer(buf) len = buf.sendpos - buf.writepos write_unlock_buffer(buf) write(buf.writepos, len) buf.writepos += len sleep(count_sleep(len)) 六、审计日志一致性 七、归并审计日志 八、查询审计日志 4 审计后续重构计划 目前，审计特性还存在较多问题，但出于时间、成本、收益等考虑，暂不重构：\n设计问题（功能冗余）：\n传统审计：通过40+个guc参数，控制审计哪类对象、审计哪类操作、管理审计文件等，日志存储于指定文件夹 统一审计：通过CREATE AUDIT POLICY语法，控制哪个对象、哪类操作需审计。日志存储于syslog 设计问题（设置审计范围）\n传统审计 主体\n参数 功能 audit_user 对白名单内的用户进行审计 full_audit_users 对白名单内的用户的所有操作进行审计 no_audit_client 对黑名单内的IP的用户不审计 操作\n参数 功能 audit_copy_exec 是否审计 COPY audit_dml_state 是否审计 INSERT、UPDATE、DELETE audit_dml_state_select 是否审计 SELECT audit_set_parameter 是否审计 SET 操作结果 参数 功能 audit_user_violation 是否越权操作 audit_operation_result 只记录操作：成功、失败、成功和失败 的日志 audit_network_error 是否审计网络连接错误 audit_query_cancel 是否审计用户取消SELECT操作 audit_insufficient_space 是否记录SPACE：达到限额 audit_tool_error 是否审计 vb_dump、vb_dumpall、vb_restore 的异常 客体\n参数 功能 audit_system_object 审计OBJECT的范围：DATABASE、SCHEMA、TABLE、…等CREATE、DROP、ALTER操作 audit_database_process 是否审计CLUSTER：启动、停止、切换和恢复 audit_function_exec 是否审计FUNCTION：执行 audit_systerm_function_exec 是否审计FUNCTION：执行（内核写了一个白名单，共61个，例如pg_stat_activity，pg_switch_xlog等） audit_sequence_enabled 是否审计语句序列 audit_crypt_func 是否审计FUNCION （密码运算函数） audit_security_policy 是否审计POLICY audit_transcation 是否审计TANSCATITON：提交、回滚 audit_login_logout 审计CLUSTER：{登录、注销} x {成功、失败} audit_user_locked 是否审计USER：锁定、解锁 audit_grant_revoke 是否审计USER：赋权、收权 代码质量问题\n可扩展性：新增SQL语法、事件，适配审计特性难度\n其他优化：\n易用性（审计日志文件）：新增工具，离线解析日志文件功能，将日志解析为可见字符串，比如日志生成时间等 insert alrec = adt_assemble_record() atomic_lock(abuff) alrecpos = adt_alloc_buffer(size) alrectime = adt_get_time() atomic_unlock(abuff) commit adt_flush_buffer(myask) +---------------------------------------+-----------+----------+-------- | | al1 | al2 | | | +---------------------------------------+-----------+----------+-------- disk iobuffer albuffer writing alloced | writer | postgres | ^ ^ ask maxask t1 p1 --\u0026gt; write p1 t2 p2 --\u0026gt; write p4 t3 p3 --\u0026gt; ok - t4 p4 --\u0026gt; ok - t5 p5 --\u0026gt; write p6 t6 p6 --\u0026gt; ok - ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/5-solution-g100-audit-refactor/","summary":"\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-%E5%AE%A1%E8%AE%A1%E7%89%B9%E6%80%A7%E4%BB%8B%E7%BB%8D\"\u003e1 审计特性介绍\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-1-%E6%A0%B8%E5%BF%83%E5%8A%9F%E8%83%BD\"\u003e1.1 核心功能\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-%E6%95%B4%E4%BD%93%E6%9E%B6%E6%9E%84%EF%BC%88308-3%EF%BC%89\"\u003e1.2 整体架构（308.3）\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-3-%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B%EF%BC%88308-3%EF%BC%89\"\u003e1.3 工作流程（308.3）\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-4-%E6%96%87%E4%BB%B6%E7%BB%84%E7%BB%87\"\u003e1.4 文件组织\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-%E4%BD%BF%E7%94%A8%E5%AE%A1%E8%AE%A1%E7%89%B9%E6%80%A7\"\u003e2 使用审计特性\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#2-1-%E9%85%8D%E7%BD%AE%E5%AE%A1%E8%AE%A1%E7%89%B9%E6%80%A7\"\u003e2.1 配置审计特性\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-2-%E5%90%AF%E5%8A%A8%E6%95%B0%E6%8D%AE%E5%BA%93\"\u003e2.2 启动数据库\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-3-%E7%94%9F%E6%88%90%E5%AE%A1%E8%AE%A1%E6%97%A5%E5%BF%97\"\u003e2.3 生成审计日志\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-4-%E6%9F%A5%E8%AF%A2%E5%AE%A1%E8%AE%A1%E6%97%A5%E5%BF%97\"\u003e2.4 查询审计日志\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-5-%E5%BC%82%E5%B8%B8%E7%AE%A1%E7%90%86\"\u003e2.5 异常管理\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-%E5%AE%A1%E8%AE%A1%E7%89%B9%E6%80%A7%E5%8F%98%E6%9B%B4%E7%82%B9\"\u003e3 审计特性变更点\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#3-1-%E9%97%AE%E9%A2%98%E5%88%86%E6%9E%90\"\u003e3.1 问题分析\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-2-%E9%87%8D%E6%9E%84%E7%9B%AE%E6%A0%87\"\u003e2.2 重构目标\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-3-%E9%97%AE%E9%A2%98%E5%88%86%E6%9E%90%EF%BC%88%E5%BD%93%E5%89%8D%E7%89%88%E6%9C%AC%EF%BC%89\"\u003e2.3 问题分析（当前版本）\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%80%E3%80%81%E5%AD%98%E5%82%A8%E6%97%A5%E5%BF%97%E6%85%A2\"\u003e一、存储日志慢\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BA%8C%E3%80%81%E6%A3%80%E7%B4%A2%E6%97%A5%E5%BF%97%E6%85%A2\"\u003e二、检索日志慢\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%89%E3%80%81%E6%96%87%E4%BB%B6%E9%97%AE%E9%A2%98%E5%A4%9A\"\u003e三、文件问题多\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-4-%E9%87%8D%E6%9E%84%E6%96%B9%E6%A1%88\"\u003e2.4 重构方案\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%80%E3%80%81%E5%AD%98%E5%82%A8%E6%97%A5%E5%BF%97%E9%87%8D%E6%9E%84\"\u003e一、存储日志重构\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BA%8C%E3%80%81%E6%A3%80%E7%B4%A2%E6%97%A5%E5%BF%97\"\u003e二、检索日志\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-5-%E9%87%8D%E6%9E%84%E5%BC%80%E9%94%80\"\u003e2.5 重构开销\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-6-%E9%87%8D%E6%9E%84%E5%BD%B1%E5%93%8D\"\u003e2.6 重构影响\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-7-%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95\"\u003e2.7 性能测试\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-%E5%AE%A1%E8%AE%A1%E7%89%B9%E6%80%A7%E8%AF%A6%E7%BB%86%E8%AE%BE%E8%AE%A1\"\u003e3 审计特性详细设计\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#3-1-%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1\"\u003e3.1 架构设计\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%80%E3%80%81%E6%95%B4%E4%BD%93%E6%9E%B6%E6%9E%84\"\u003e一、整体架构\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BA%8C%E3%80%81%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B\"\u003e二、工作流程\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%89%E3%80%81%E6%96%87%E4%BB%B6%E7%BB%84%E7%BB%87\"\u003e三、文件组织\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-2-%E8%AF%A6%E7%BB%86%E8%AE%BE%E8%AE%A1\"\u003e3.2 详细设计\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%80%E3%80%81%E9%85%8D%E7%BD%AE%E5%AE%A1%E8%AE%A1%E7%89%B9%E6%80%A7\"\u003e一、配置审计特性\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BA%8C%E3%80%81%E5%AE%A1%E8%AE%A1%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86\"\u003e二、审计文件管理\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%89%E3%80%81-%E5%90%AF%E5%8A%A8%E6%95%B0%E6%8D%AE%E5%BA%93\"\u003e三、 启动数据库\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%9B%9B%E3%80%81%E7%94%9F%E6%88%90%E5%AE%A1%E8%AE%A1%E6%97%A5%E5%BF%97\"\u003e四、生成审计日志\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BA%94%E3%80%81%E5%AD%98%E5%82%A8%E5%AE%A1%E8%AE%A1%E6%97%A5%E5%BF%97\"\u003e五、存储审计日志\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%85%AD%E3%80%81%E5%AE%A1%E8%AE%A1%E6%97%A5%E5%BF%97%E4%B8%80%E8%87%B4%E6%80%A7\"\u003e六、审计日志一致性\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%83%E3%80%81%E5%BD%92%E5%B9%B6%E5%AE%A1%E8%AE%A1%E6%97%A5%E5%BF%97\"\u003e七、归并审计日志\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%85%AB%E3%80%81%E6%9F%A5%E8%AF%A2%E5%AE%A1%E8%AE%A1%E6%97%A5%E5%BF%97\"\u003e八、查询审计日志\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-%E5%AE%A1%E8%AE%A1%E5%90%8E%E7%BB%AD%E9%87%8D%E6%9E%84%E8%AE%A1%E5%88%92\"\u003e4 审计后续重构计划\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e\u003cstrong\u003e摘要\u003c/strong\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e介绍审计特性，分析性能问题，提出优化方案，评审优化方案，规划其他计划\u003c/p\u003e\u003c/blockquote\u003e\n\u003ch1 id=\"1-审计特性介绍\"\u003e1 审计特性介绍\u003c/h1\u003e\n\u003ch2 id=\"11-核心功能\"\u003e1.1 核心功能\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e审计特性：记录数据库内的各种事件，事件包括：\u003c/p\u003e","title":"海量 5 方案 G100审计重构"},{"content":"2 使用方法 2.1 设置安全策略 表级\nCREATE TABLE t1 (c1 INT, c2 TEXT); -- 1 身份认证 -- 2 安全传输 -- 3 安全审计 CREATE SECURITY POLICY ad1 ON t1 USE (type=\u0026#39;security audit\u0026#39;, scope=\u0026#39;create, insert, update\u0026#39;); -- 4 访问控制 CREATE SECURITY POLICY ac1 ON t1 USE (type=\u0026#39;access control\u0026#39;, group=\u0026#39;user1, user2, user3\u0026#39;); -- 5 数据发现 -- 6 数据防篡改 CREATE SECURITY POLICY lga ON t1 USE (type=\u0026#39;ledger\u0026#39;); -- 7 加密函数 -- 8 透明加密 CREATE SECURITY POLICY se1 ON t1 USE (type=\u0026#39;storage encrypt\u0026#39;, key=\u0026#39;key1\u0026#39;); -- 9 数据脱敏 CREATE SECURITY POLICY ms1 ON t1 USE (type=\u0026#39;mask\u0026#39;, type=\u0026#39;money\u0026#39;); -- 10 全密态加密 CREATE SECURITY POLICY ce1 ON t1 USE (type=\u0026#39;client encrypt\u0026#39;, key=\u0026#39;key1\u0026#39;); -- 11 机密计算 列级\n-- 10 全密态加密 CREATE SECURITY POLICY ce1 ON t1(c1) USE (type=\u0026#39;client encrypt\u0026#39;, key=\u0026#39;key1\u0026#39;); 2.2 管理安全策略 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/5-unified-management/","summary":"\u003ch1 id=\"2-使用方法\"\u003e2 使用方法\u003c/h1\u003e\n\u003ch2 id=\"21-设置安全策略\"\u003e2.1 设置安全策略\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e表级\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 1 身份认证\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2 安全传输\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 安全审计\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSECURITY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePOLICY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ead1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eUSE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003etype\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;security audit\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003escope\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;create, insert, update\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 4 访问控制\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSECURITY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePOLICY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eac1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eUSE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003etype\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;access control\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003egroup\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;user1, user2, user3\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 5 数据发现\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 6 数据防篡改\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSECURITY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePOLICY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003elga\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eUSE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003etype\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;ledger\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 7 加密函数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 8 透明加密\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSECURITY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePOLICY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ese1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eUSE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003etype\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;storage encrypt\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;key1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 9 数据脱敏\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSECURITY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePOLICY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ems1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eUSE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003etype\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;mask\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etype\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;money\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 10 全密态加密\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSECURITY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePOLICY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ece1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eUSE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003etype\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;client encrypt\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ekey\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;key1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 11 机密计算\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e列级\u003c/p\u003e","title":"数据库安全 统一管理"},{"content":"简介 postgresql 简单架构\napplication driver(jdbc/libpq/..) server +-----------------------------------------------+-----------------------------------------+--------- | PQconnect(host, port, user, name) | do something .. | PQexec(\u0026#34;create table t1(c1 int, c2 text)\u0026#34;) | | PQexecStart() | PQsendQuery() | pqPutMsgStart(\u0026#39;Q\u0026#39;) | pqPutnchar(\u0026#34;$sql\u0026#34;) | pqPutMsgEnd() | pqFlush() | | SocketBackend() | pq_parse_input() | \u0026#39;Q\u0026#39;: exec_simple_query() | PQexec(\u0026#34;insert into t1 values(1,\u0026#39;a\u0026#39;),(2,\u0026#39;b\u0026#39;)\u0026#34;)| | PQexec(\u0026#34;select * from t1\u0026#34;) | .. | .. | exec_simple_query() | libpq的功能\n连接管理 协议编码 数据收发 连接管理 application driver(jdbc/libpq/..) server +-------------------------------------------+-----------------------------------------+--------- | connect(host, port, user, name) 协议编码 消息通用格式\n+------+--------+-------------+ | type | length | palyload | +------+--------+-------------+ char int32 type有以下类型：\n执行SQL场景\n场景 type length payload 触发条件 payload示例 c-\u0026gt;s ‘Q’ int32 char *query PQexec / PQsendQuery SELECT * FROM t1\\0 c-\u0026gt;s ‘P’ int32 char *stmt_name / char *query / .. PQprepare / Parse阶段 - c-\u0026gt;s ‘B’ int32 char *portal_name / char *stmt_name / .. - $1=1, $2=’a’ c-\u0026gt;s ‘E’ int32 char *portal_name / 执行portal portal0 + 0 c-\u0026gt;s ‘T’ int32 int16 nfileds / Field fields[] SELECT 返回结果 c1:int4, c2:text c-\u0026gt;s ‘D’ int32 int16 nrows / Column colsp[] SELECT 返回结果 1,’a’ c-\u0026gt;s ‘C’ int32 char tag SQL 执行结束 2 c-\u0026gt;s ‘Z’ int32 char status Server空闲 1 c-\u0026gt;s ‘n’ int32 (nodata) DDL等返回结果 .. 身份认证场景\n数据收发 create table t1(c1 int, c2 text) insert into t1 values(1,\u0026#39;a\u0026#39;),(2,\u0026#39;b\u0026#39;) select * from t1 Client (Libpq) Server (Backend) │ │ │ send msg [\u0026#39;Q\u0026#39;][len][\u0026#34;SELECT * from t1\\0\u0026#34;] --\u0026gt; | │ │ │ \u0026lt;-- send msg [\u0026#39;T\u0026#39;][len][nfields:2 c1/23/4 c2/25/-1 │ │ \u0026lt;-- send msg [\u0026#39;D\u0026#39;][len][nfields:2 4/1/1/\u0026#39;a\u0026#39; │ │ \u0026lt;-- send msg [\u0026#39;D\u0026#39;][len][nfields:2 4/2/1/\u0026#39;b\u0026#39; │ │ \u0026lt;-- send msg [\u0026#39;C\u0026#39;][len][\u0026#34;SELECT 2\u0026#34;] │ │ \u0026lt;-- send msg [\u0026#39;Z\u0026#39;][len][\u0026#39;I\u0026#39;] │ 其中：\n/* --------- msg \u0026#39;T\u0026#39; -------------- */ /* server */ void printtup_startup(TupleDesc typeinfo) { pq_beginmessage(\u0026#39;T\u0026#39;) pq_sendint16(typeinfo-\u0026gt;natts) for (i = 0; i \u0026lt; typeinfo-\u0026gt;natts; i++) { Form_pg_attribute attr = TupleDescAttr(typeinfo, i); pq_sendstring(NameStr(attr-\u0026gt;attname)) pq_sendint32(attr-\u0026gt;attrelid) pq_sendint16(attr-\u0026gt;attnum) pq_sendint32(attr-\u0026gt;atttypid) pq_sendint16(attr-\u0026gt;attlen) pq_sendint32(attr-\u0026gt;atttypmod) pq_sendint16(format); /* text还是二进制格式，bytea是二进制，其他大部分是text */ } pq_endmessage() } /* client */ typedef struct pgresAttDesc { char\t*name;\t/* column name */ Oid\ttableid;\t/* source table, if known */ int\tcolumnid;\t/* source column, if known */ int\tformat;\t/* format code for value (text/binary) */ Oid\ttypid;\t/* type id */ int\ttyplen;\t/* type size */ int\tatttypmod;\t/* type-specific modifier info */ } PGresAttDesc; /* --------- msg \u0026#39;D\u0026#39; -------------- */ /* server */ bool printtup(TupleTableSlot *slot) { TupleDesc typeinfo = slot-\u0026gt;tts_tupleDescriptor; pq_beginmessage(\u0026#39;D\u0026#39;) pq_sendint16(typeinfo-\u0026gt;natts); /* 列数 */ for (int i = 0; i \u0026lt; typeinfo-\u0026gt;natts; i++) { Datum attr = slot-\u0026gt;tts_values[i]; bool isnull = slot-\u0026gt;tts_isnull[i]; if（isnull) { pq_sendint32(-1); } else { char *outputstr = OidOutputFunctionCall(typoutput, attr) /* 注意：如果是int类型，且是默认的text发送，此处会调用int4out函数，输出字符串，加入int=101，输出char*=\u0026#39;101\u0026#39; */ int len = strlen(outputstr) pq_sendint32(len); pq_sendbytes(outputstr); } } pq_endmessage() } /* client */ typedef struct pgresAttValue { int\tlen;\t/* length in bytes of the value */ char\t*value;\t/* actual value, plus terminating zero byte */ } PGresAttValue; ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/5-1-libpq/","summary":"\u003ch1 id=\"简介\"\u003e简介\u003c/h1\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003epostgresql 简单架构\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eapplication                             driver\u003cspan class=\"o\"\u003e(\u003c/span\u003ejdbc/libpq/..\u003cspan class=\"o\"\u003e)\u003c/span\u003e                       server\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e+-----------------------------------------------+-----------------------------------------+---------\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e PQconnect\u003cspan class=\"o\"\u003e(\u003c/span\u003ehost, port, user, name\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"k\"\u003edo\u003c/span\u003e something ..\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e PQexec\u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;create table t1(c1 int, c2 text)\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e)\u003c/span\u003e    \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"p\"\u003e|\u003c/span\u003e PQexecStart\u003cspan class=\"o\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"p\"\u003e|\u003c/span\u003e PQsendQuery\u003cspan class=\"o\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"p\"\u003e|\u003c/span\u003e   pqPutMsgStart\u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;Q\u0026#39;\u003c/span\u003e\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"p\"\u003e|\u003c/span\u003e   pqPutnchar\u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$sql\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"p\"\u003e|\u003c/span\u003e   pqPutMsgEnd\u003cspan class=\"o\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"p\"\u003e|\u003c/span\u003e pqFlush\u003cspan class=\"o\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"p\"\u003e|\u003c/span\u003e                                       \u003cspan class=\"p\"\u003e|\u003c/span\u003e SocketBackend\u003cspan class=\"o\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                                                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e pq_parse_input\u003cspan class=\"o\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                                                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e   \u003cspan class=\"s1\"\u003e\u0026#39;Q\u0026#39;\u003c/span\u003e: exec_simple_query\u003cspan class=\"o\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e PQexec\u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;insert into t1 values(1,\u0026#39;a\u0026#39;),(2,\u0026#39;b\u0026#39;)\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e PQexec\u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;select * from t1\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"p\"\u003e|\u003c/span\u003e ..\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                                                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e ..\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                                                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e exec_simple_query\u003cspan class=\"o\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                                                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003elibpq的功能\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e连接管理\u003c/li\u003e\n\u003cli\u003e协议编码\u003c/li\u003e\n\u003cli\u003e数据收发\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"连接管理\"\u003e连接管理\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-fallback\" data-lang=\"fallback\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eapplication                             driver(jdbc/libpq/..)                       server\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e+-------------------------------------------+-----------------------------------------+---------\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e| connect(host, port, user, name)\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"协议编码\"\u003e协议编码\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e消息通用格式\u003c/p\u003e","title":"PostgreSQL 5-1 libpq"},{"content":"1 需求分析 透明加密 主密钥 动态脱敏 和统一审计共用resource lable模块 全密态 密态等值 密态非等值 范围查询：OPE保序加密 模糊查询 内置函数 排序 .. 防篡改 分布式：有点麻烦，区块链记录在每个节点上 哈希函数：md5 1.1 透明加密 模块分析 密钥管理 设置主密钥 定义加密属性 表：普通表、临时表、分区表、toast表 索引 xlog 加密数据 加密算法：aes-256-ctr, sm4-ctr 备机加密 -- 创建主密钥 -- 设置表加密 CREATE TABLE t1 (c1 INT, c2 TEXT) WITH (enable_tde=on); -- 验证数据加密存储 INSERT INTO t1 VALUES (1, \u0026#39;bbbcccddd\u0026#39;); 1.2 动态脱敏 -- 开启脱敏功能 gs_guc reload -D $GAUSSHOME/data -c \u0026#34;enable_security_policy=on\u0026#34; -- 创建表 CREATE TABLE t1 (c1 TEXT, c2 TEXT); INSERT INTO t1 VALUES (\u0026#39;bbccdd\u0026#39;, \u0026#39;bbccdd\u0026#39;); -- 创建用户 CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; CREATE USER u2 PASSWORD \u0026#39;u2.password\u0026#39;; GRANT SELECT ON t1 TO u1; GRANT SELECT ON t1 TO u2; -- 创建资源标签（只对u1脱敏） CREATE RESOURCE LABEL l1 ADD COLUMN(t1.c1); CREATE MASKING POLICY m1 randommasking ON LABEL(l1) FILTER ON ROLES(u1); -- 验证脱敏：只有u1脱敏 SET ROLE u1 PASSWORD \u0026#39;u1.password\u0026#39;; SELECT * FROM t1; RESET ROLE; SET ROLE u2 PASSWORD \u0026#39;u2.password\u0026#39;; SELECT * FROM t1; RESET ROLE; -- 清理环境 DROP MASKING POLICY m1; DROP RESOURCE LABEL l1; DROP TABLE t1; DROP USER u1,u2; 1.3 全密态 模块分析 客户端 语法解析 语义分析 加密 服务端 .. 1.4 防篡改 hash算法：md5 2 greenplum yum install zstd libzstd-devel krb5-devel krb5-libs cyrus-sasl-gssapi libevent-devel libyaml-devel libxml2 libxml2-devel curl libcurl-devel yum install apr apr-devel apr-util apr-util-devel yum install expat-devel openldap-devel bzip2 bzip2-devel xerces-c xerces-c-devel python36-devel ln -s /usr/include/python2.7/Python.h /usr/include/Python.h # 报错就降级 yum downgrade expat-2.1.0-12.el7 mkdir install cd install # echo \u0026#39;\u0026#39;使用单引号可防止变量$PATH等展开 echo \u0026#39; export GPHOME=`pwd`/install export BINARYLIBS=`pwd`/../third export GCC_PATH=$BINARYLIBS/buildtools/gcc10.3 export CC=$GCC_PATH/gcc/bin/gcc export CXX=$GCC_PATH/gcc/bin/g++ export LD_LIBRARY_PATH=$GCC_PATH/gcc/lib64:$GCC_PATH/isl/lib:$GCC_PATH/mpc/lib/:$GCC_PATH/mpfr/lib/:$GCC_PATH/gmp/lib/:$LD_LIBRARY_PATH export PATH=$GCC_PATH/gcc/bin:$PATH \u0026#39; \u0026gt; genv # 建议把环境变量再在~/.bashrc中写一份，因为初始化集群时，需要ssh登录，以初始化segment节点 ./configure --with-python --with-libxml --with-gssapi --without-zlib --with-gpcc --prefix=$GPHOME make -sj 16 make install -sj 16 echo \u0026#34; ARRAY_NAME=\u0026#34;Greenplum Cluster\u0026#34; SEG_PREFIX=gpseg #segment数据库前缀名 PORT_BASE=40000 #segment数据库起始端口号 declare -a DATA_DIRECTORY=(//home/shenkun/gp/install/segdata) #segments数据目录，有几个DATA_DIRECTORY, 每个节点上便会启动几个segment，本例为2个segment MASTER_HOSTNAME=master #master主机名 MASTER_DIRECTORY=/home/shenkun/gp/install/master #master数据目录 MASTER_PORT=5000 #master端口号，也是对外业务端口号 TRUSTED_SHELL=ssh CHECK_POINT_SEGMENTS=8 ENCODING=UNICODE DATABASE_NAME=gpdb MACHINE_LIST_FILE=/home/shenkun/gp/install/hostfile #集群配置文件，hostfile对应7中创建的文件名 \u0026#34; \u0026gt; gpcfg echo \u0026#34;master\u0026#34; \u0026gt; hostfile gpinitsystem -c gpcfg -a psql -p 5000 -d gpdb PGOPTIONS=\u0026#39;-c gp_session_role=utility\u0026#39; psql -p 40000 -d gpdb # @ master exec_simple_query pg_parse_query pg_analyze_and_rewrite pg_plan_queries pg_plan_querie planner standard_planner subquery_planner cdbllize_adjust_top_path create_plan cdbpathtoplan_create_flow makeFlow cdbllize_decorate_subplans_with_motions PortalStart ExecutorStart standard_ExecutorStart CdbDispatchPlan # @ segment exec_mpp_query deserializeNode PortalStart PortalRun PortalDrop PortalRun PortalRunMulti ProcessQuery ExecutorStart ExecutorRun standard_ExecutorRun ExecutePlan ExecutorFinish ExecutorEnd PortalDrop ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/6-design-greenplum/","summary":"\u003ch1 id=\"1-需求分析\"\u003e1 需求分析\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e透明加密\n\u003cul\u003e\n\u003cli\u003e主密钥\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e动态脱敏\n\u003cul\u003e\n\u003cli\u003e和统一审计共用resource lable模块\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e全密态\n\u003cul\u003e\n\u003cli\u003e密态等值\u003c/li\u003e\n\u003cli\u003e密态非等值\n\u003cul\u003e\n\u003cli\u003e范围查询：OPE保序加密\u003c/li\u003e\n\u003cli\u003e模糊查询\u003c/li\u003e\n\u003cli\u003e内置函数\u003c/li\u003e\n\u003cli\u003e排序\u003c/li\u003e\n\u003cli\u003e..\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e防篡改\n\u003cul\u003e\n\u003cli\u003e分布式：有点麻烦，区块链记录在每个节点上\u003c/li\u003e\n\u003cli\u003e哈希函数：md5\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"11-透明加密\"\u003e1.1 透明加密\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e模块分析\n\u003cul\u003e\n\u003cli\u003e密钥管理\n\u003cul\u003e\n\u003cli\u003e设置主密钥\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e定义加密属性\n\u003cul\u003e\n\u003cli\u003e表：普通表、临时表、分区表、toast表\u003c/li\u003e\n\u003cli\u003e索引\u003c/li\u003e\n\u003cli\u003exlog\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e加密数据\n\u003cul\u003e\n\u003cli\u003e加密算法：aes-256-ctr, sm4-ctr\u003c/li\u003e\n\u003cli\u003e备机加密\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 创建主密钥\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 设置表加密\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eenable_tde\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003eon\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 验证数据加密存储\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;bbbcccddd\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"12-动态脱敏\"\u003e1.2 动态脱敏\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 开启脱敏功能\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003egs_guc\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ereload\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;enable_security_policy=on\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 创建表\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;bbccdd\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;bbccdd\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 创建用户\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eGRANT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eGRANT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 创建资源标签（只对u1脱敏）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eRESOURCE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eLABEL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003el1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eADD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCOLUMN\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eMASKING\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePOLICY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003em1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erandommasking\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eLABEL\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003el1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eFILTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eROLES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 验证脱敏：只有u1脱敏\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSET\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eROLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eRESET\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eROLE\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSET\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eROLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eRESET\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eROLE\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 清理环境\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eMASKING\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePOLICY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003em1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eRESOURCE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eLABEL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003el1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"13-全密态\"\u003e1.3 全密态\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e模块分析\n\u003cul\u003e\n\u003cli\u003e客户端\n\u003cul\u003e\n\u003cli\u003e语法解析\u003c/li\u003e\n\u003cli\u003e语义分析\u003c/li\u003e\n\u003cli\u003e加密\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e服务端\n\u003cul\u003e\n\u003cli\u003e..\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"14-防篡改\"\u003e1.4 防篡改\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003ehash算法：md5\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-greenplum\"\u003e2 greenplum\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eyum install zstd libzstd-devel krb5-devel krb5-libs cyrus-sasl-gssapi libevent-devel libyaml-devel libxml2 libxml2-devel curl libcurl-devel\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eyum install apr apr-devel apr-util apr-util-devel\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eyum install expat-devel openldap-devel bzip2 bzip2-devel xerces-c xerces-c-devel python36-devel\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eln -s /usr/include/python2.7/Python.h /usr/include/Python.h\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 报错就降级\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eyum downgrade expat-2.1.0-12.el7\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir install\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e install\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# echo \u0026#39;\u0026#39;使用单引号可防止变量$PATH等展开\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport GPHOME=`pwd`/install\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport BINARYLIBS=`pwd`/../third\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport GCC_PATH=$BINARYLIBS/buildtools/gcc10.3\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport CC=$GCC_PATH/gcc/bin/gcc\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport CXX=$GCC_PATH/gcc/bin/g++\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport LD_LIBRARY_PATH=$GCC_PATH/gcc/lib64:$GCC_PATH/isl/lib:$GCC_PATH/mpc/lib/:$GCC_PATH/mpfr/lib/:$GCC_PATH/gmp/lib/:$LD_LIBRARY_PATH\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PATH=$GCC_PATH/gcc/bin:$PATH\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u003c/span\u003e \u0026gt; genv\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 建议把环境变量再在~/.bashrc中写一份，因为初始化集群时，需要ssh登录，以初始化segment节点\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e./configure --with-python --with-libxml --with-gssapi  --without-zlib --with-gpcc --prefix\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$GPHOME\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emake -sj \u003cspan class=\"m\"\u003e16\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emake install -sj \u003cspan class=\"m\"\u003e16\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003eARRAY_NAME=\u0026#34;\u003c/span\u003eGreenplum Cluster\u003cspan class=\"s2\"\u003e\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003eSEG_PREFIX=gpseg #segment数据库前缀名\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003ePORT_BASE=40000 #segment数据库起始端口号\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003edeclare -a DATA_DIRECTORY=(//home/shenkun/gp/install/segdata)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003e#segments数据目录，有几个DATA_DIRECTORY, 每个节点上便会启动几个segment，本例为2个segment\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003eMASTER_HOSTNAME=master #master主机名\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003eMASTER_DIRECTORY=/home/shenkun/gp/install/master #master数据目录\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003eMASTER_PORT=5000 #master端口号，也是对外业务端口号\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003eTRUSTED_SHELL=ssh\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003eCHECK_POINT_SEGMENTS=8\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003eENCODING=UNICODE\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003eDATABASE_NAME=gpdb\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003eMACHINE_LIST_FILE=/home/shenkun/gp/install/hostfile #集群配置文件，hostfile对应7中创建的文件名\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e \u0026gt; gpcfg\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;master\u0026#34;\u003c/span\u003e \u0026gt; hostfile\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egpinitsystem -c gpcfg -a\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epsql -p \u003cspan class=\"m\"\u003e5000\u003c/span\u003e -d gpdb\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003ePGOPTIONS\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;-c gp_session_role=utility\u0026#39;\u003c/span\u003e psql -p \u003cspan class=\"m\"\u003e40000\u003c/span\u003e -d gpdb\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# @ master\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eexec_simple_query\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    pg_parse_query\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    pg_analyze_and_rewrite\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    pg_plan_queries\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        pg_plan_querie\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            planner\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                standard_planner\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    subquery_planner\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    cdbllize_adjust_top_path\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    create_plan\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    cdbpathtoplan_create_flow\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        makeFlow\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    cdbllize_decorate_subplans_with_motions\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    PortalStart\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        ExecutorStart\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            standard_ExecutorStart\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                CdbDispatchPlan\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                                    \u003cspan class=\"c1\"\u003e# @ segment\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                                    exec_mpp_query\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                                        deserializeNode\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                                            PortalStart\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                                            PortalRun\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                                            PortalDrop\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    PortalRun\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        PortalRunMulti\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            ProcessQuery\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                ExecutorStart\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                ExecutorRun\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    standard_ExecutorRun\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        ExecutePlan\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                ExecutorFinish\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                ExecutorEnd\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    PortalDrop\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"海量 6 设计 greenplum"},{"content":"本需求包含6个小需求：\n身份认证：创建用户：CREATE/SET USER .. PASSWORD ..，密码可以只设置2类字符 身份认证：创建用户：CREATE/SET [角色] USER ..，角色支持指定SUPERUSER和NOSUPERUSER 身份认证：查看用户：SELECT .. FROM pg_user，普通用户可查询pg_user视图（仅pg兼容性） 身份认证：登录用户：SET ROLE new_user [PASSWORD ..]，new_user是会话用户时，可以不指定PASSWORD 访问控制：Database权限：普通用户可访问template1数据库（仅pg兼容性） 访问控制：Schema权限：普通用户可在public下执行CREATE操作（仅pg兼容性） 描述 身份认证：创建用户\n变更：用户密码可以只包含2类字符\n-- password_polcy取值不同，密码需包含的字符种类数不同，为1时需3类，需2时需4类，为3时需2类 ALTER SYSTEM SET password_policy OT 3; -- 修改取值范围[0,2]为[0,3] CREATE USER u1 PASSWORD \u0026#39;password1\u0026#39;; -- 此时，密码可以只含2类字符 ALTER USER old_user PASSWORd \u0026#39;password1\u0026#39;; 身份认证：创建用户\n变更：可以指定SUPERUSER角色\nCREATE USER u1 SUPERUSER PASSWORD ..; -- 支持设置 SUPERUSER 角色 ALTER USER u1 NOSUPERUSER ..; -- 支持取消 SUPERUSER 角色 ALTER USER old_user SUPERUSER ..; 身份认证：查看用户\n变更：普通用户可查询pg_user视图（仅pg兼容性）\nvsql -d $database -U $ordinary_user .. SELECT * FROM pg_user; -- 普通用户可查询pg_user视图 身份认证：登录用户\n变更：3种场景下，SET ROLE无需再输密码（仅pg兼容性）\n约束（已有约束，本次未修改）：无论怎样，都不支持set role到superuser。set role到sysadmin可以。\nvsql -d $databse -U $session_user -W .. -- 切换用户 SET ROLE $new_user [PASSWORD $password] 非pg兼容性，必须输入password，无改动。pg兼容性，与postgresql保持一致，以下3种情况，切换到新用户时，无需输入密码：\n场景1: new_user = session_user\nvsql -d $databse -U u1 -W .. SET ROLE u2 PASSWORD \u0026#39;u2.password\u0026#39;; SET ROLE u1; 场景2: new_user 给 session_user 赋权\nGRANT u2 TO u1; vsql -d $databse -U u1 -W .. SET ROLE u2; 场景3: session_user是特权用户（未开启三权分立时，superuser和sysadmin；开启三权分立时，superuser）\nCREATE USER u1 SYSADMIN PASSWORD .. vsql -d $databse -U u1 -W .. SET ROLE u2; 访问控制：Database权限\n变更：普通用户可访问 template1 数据库(仅pg兼容性)\nvsql -d template1 -U $ordinary_user .. -- 普通用户能连接成功 访问控制：Schema权限\n变更：普通用户可在public模式下CREATE多种对象(仅pg兼容性)\nvsql -d template1 -U $ordinary_user .. SET search_path TO public; CREATE ... -- 普通用户可在public模式下CREATE多种对象，包括table, view, sequence, function, trigger等 一、set role current_user 把role当做1个user_set级guc -- 1. 创建多个用户 vsql -d postgres CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; CREATE USER u2 PASSWORD \u0026#39;u2.password\u0026#39;; -- 2. 登录u1用户 vsql -d postgres -U u1 -W \u0026#39;u1.password\u0026#39; -- 3. set role为其他用户，需要密码 SET ROLE u2 PASSWORD \u0026#39;u2.password\u0026#39;; SELECT CURRENT_USER; -- 4. set role为连接用户，无需密码 SET ROLE u1; SELECT CURRENT_USER; -- 5. 清理 DROP USER u1,u2; 超级用户 -- 普通用户（父） -- 普通用户 -- 普通用户（子） vsql -d postgres -U {session_user} SET ROLE new_role return is_member_of_role(session_user, new_role) -- session_user 是 super_user -- session_user == new_role -- session_user is member of () GRANT u1 TO u2; -- 给u2赋予权限 GRANT u1 TO u3; -- u1: SET ROLE u2，无权限 -- u2: SET ROLE u1, 成功 -- u2: SET ROLE u3, 无权限 SELECT pg_get_userbyid(roleid),pg_get_userbyid(member) FROM pg_auth_members; SELECT pg_get_userbyid(member) FROM pg_auth_members WHERE roleid = (SELECT oid FROM pg_authid WHERE rolname = \u0026#39;u1\u0026#39;); -- 获取同组用户 SELECT pg_get_userbyid(m.member) FROM pg_auth_members m JOIN pg_authid a ON m.roleid = a.oid WHERE a.rolname = \u0026#39;u1\u0026#39;; -- 获取可set role的用户（哪些用户给本用户赋权了） SELECT pg_get_userbyid(roleid) can_setto FROM pg_auth_members WHERE member = (SELECT oid FROM pg_authid WHERE rolname = SESSION_USER); ExecSetVariableStmt case VAR_SET_ROLEPWD check_setrole_permisson verify_setrole_passwd 二、普通用户可查询pg_user视图 -- 1. 创建普通用户 vsql -d postgres -r CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; -- 2. 登录普通用户 vsql -d postgres -r -U u1 -W \u0026#39;u1.password\u0026#39; -- 3. 查询pg_user视图 SELECT * FROM pg_user -- 4. 清理 DROP USER u1; 三、创建密码时只需2种字符 password_policy取值\n0: 不开启密码复杂度校验 1：开启密码复杂度校验：字符类型至少3类，密码不能与用户名相同，根据其他guc参数校验每类字符数、密码长度等 2：开启密码复杂度校验：字符类型至少4类，密码不能与用户名相同或接近，根据其他guc参数校验每类字符数、密码长度等 3：开启密码复杂度校验：字符类型至少2类，密码不能与用户名相同，根据其他guc参数校验每类字符数、密码长度等 SHOW password_policy; ALTER SYSTEM SET password_policy TO 2; -- 1. 创建普通用户 vsql -d postgres -r CREATE USER u1 PASSWORD \u0026#39;u1password\u0026#39;; -- 2. 登录普通用户 vsql -d postgres -r -U u1 -W \u0026#39;u1.password\u0026#39; -- 3. 清理 DROP USER u1; 四、支持superuser/nosuperuser与sysadmin/nosysadmin角色名 -- 1. 创建用户 CREATE USER u1 SUPERUSER PASSWORD \u0026#39;u1.password\u0026#39;; CREATE USER u2 NOSUPERUSER PASSWORD \u0026#39;u2.password\u0026#39;; -- pg不支持sysadmin CREATE USER u3 SYSADMIN PASSWORD \u0026#39;u3.password\u0026#39;; CREATE USER u4 NOSYSADMIN PASSWORD \u0026#39;u4.password\u0026#39;; -- pg支持admin CREATE USER u5 ADMIN u1 PASSWORD \u0026#39;u5.password\u0026#39;; -- 2. 登录用户 -- 3. 清理用户 DROP USER IF EXISTS u1,u2,u3,u4,u5,u6; 五、普通用户有public create权限 function, procedure, table, sequence, index\nvb有权限\n-- 1 高权限用户：创建普通用户 CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; -- 2 登录普通用户 vsql -d postgres -U u1 -W \u0026#39;u1.password\u0026#39; -r -- 3 创建对象 CREATE DATABASE db1; -- 无权限 CREATE SCHEMA sch1; -- 无权限 CREATE TABLE t1(c1 INT); CREATE VIEW v1 AS SELECT * FROM t1; CREATE INDEX i1 ON t1(c1); CREATE SEQUENCE seq1; CREATE FUNCTION f1() RETURNS INT AS $$ SELECT count(*)::INT FROM t1 $$ LANGUAGE sql; -- CREATE PROCEDURE p1() LANGUAGE plpgsql AS $$ BEGIN INSERT INTO t1 VALUES (3); END; $$; CREATE PROCEDURE p1() IS BEGIN INSERT INTO t1 VALUES (3); END; / CREATE FUNCTION ft1() RETURNS TRIGGER AS $$ BEGIN SELECT count(*) FROM t1; RETURN NEW; END; $$ LANGUAGE plpgsql; -- vb不支持语法 EXECUTE PROCEDURE CREATE TRIGGER tri1 AFTER INSERT ON t1 FOR EACH ROW EXECUTE PROCEDURE ft1(); CREATE TYPE typ1 AS ENUM(\u0026#39;v1\u0026#39;, \u0026#39;v2\u0026#39;); -- 4 清理对象 DROP TABLE t1 CASCADE; DROP SEQUENCE seq1; DROP FUNCTION f1; DROP PROCEDURE p1; DROP FUNCTION ft1; DROP TYPE typ1; -- 5 清理用户 RESET ROLE; DROP USER IF EXISTS u1; 六、普通用户登录template1数据库 -- 1 创建用户 CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; -- 2 登录用户 vsql -d template1 -U u1 -W \u0026#39;u1.password\u0026#39; -- 3 清理 DROP USER u1; -- --------------------------------------------------- -- 1. auth: login user: support set role without password -- --------------------------------------------------- -- secen 1: set role to session_user, password is unnecessary CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; CREATE USER u2 PASSWORD \u0026#39;u2.password\u0026#39;; GRANT u2 TO u1; SET SESSION AUTHORIZATION u1 PASSWORD \u0026#39;u1.password\u0026#39;; SELECT session_user; SELECT current_user; SET ROLE u2 PASSWORD \u0026#39;u2.password\u0026#39;; SET ROLE u1; -- no need password anymore SET ROLE u2 PASSWORD \u0026#39;u2.password\u0026#39;; SET ROLE u1 PASSWORD \u0026#39;u1.password\u0026#39;; -- set password also ok SET ROLE u2 PASSWORD \u0026#39;u2.password\u0026#39;; SET ROLE u1 PASSWORD \u0026#39;u1.wrong\u0026#39;; -- if set password, we will still check it -- secen 2: if grant user permission, password is unnecessary SET ROLE u1; SET ROLE u2; -- no need password too RESET SESSION AUTHORIZATION; RESET ROLE; DROP USER u1,u2; -- secen 3: super user and sysadmin, set role to other user, password is unnecessary CREATE USER u1 SUPERUSER PASSWORD \u0026#39;u1.password\u0026#39;; CREATE USER u2 SYSADMIN PASSWORD \u0026#39;u2.password\u0026#39;; CREATE USER u3 PASSWORD \u0026#39;u3.password\u0026#39;; \\! sleep 1 SET SESSION AUTHORIZATION u1 PASSWORD \u0026#39;u1.password\u0026#39;; SET ROLE u3; SET ROLE u2; \\! sleep 1 SET SESSION AUTHORIZATION u2 PASSWORD \u0026#39;u2.password\u0026#39;; SET ROLE u3; SET ROLE u2; \\! sleep 1 RESET SESSION AUTHORIZATION; RESET ROLE; GRANT u1 TO u3; GRANT u2 TO u3; SET SESSION AUTHORIZATION u3 PASSWORD \u0026#39;u3.password\u0026#39;; SET ROLE u1; -- error: can\u0026#39;t set role to superuser SET ROLE u2; -- error: need pass RESET SESSION AUTHORIZATION; RESET ROLE; DROP USER u1,u2,u3; -- --------------------------------------------------- -- 2. auth: auth meta: check the permission of pg_user -- --------------------------------------------------- CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; SET ROLE u1 PASSWORD \u0026#39;u1.password\u0026#39;; SELECT usename FROM pg_user WHERE usename = \u0026#39;u1\u0026#39;; RESET ROLE; DROP USER u1; -- --------------------------------------------------- -- 3. auth: create/alter user: check password complexity -- --------------------------------------------------- ALTER SYSTEM SET password_policy TO default; \\! sleep 1 CREATE USER u2 PASSWORD \u0026#39;u2password\u0026#39;; -- error: need 3 types of characters ALTER SYSTEM SET password_policy TO 2; \\! sleep 1 CREATE USER u3 PASSWORD \u0026#39;u3.password\u0026#39;; -- error: need 4 types of characters ALTER SYSTEM SET password_policy TO 3; \\! sleep 1 CREATE USER u1 PASSWORD \u0026#39;upassword\u0026#39;; -- error: need 2 types of characters CREATE USER u2 PASSWORD \u0026#39;u2password\u0026#39;; -- succeed CREATE USER u3 PASSWORD \u0026#39;u3.password\u0026#39;; -- succeed ALTER USER u2 PASSWORD \u0026#39;upassword\u0026#39;; -- error: need 2 types of characters ALTER USER u3 PASSWORD \u0026#39;u2password\u0026#39;; -- -- succeed -- make sure can login u2 SET ROLE u2 PASSWORD \u0026#39;u2password\u0026#39;; CREATE TABLE t1(c1 INT); DROP TABLE t1; RESET ROLE; ALTER SYSTEM SET password_policy TO default; DROP USER IF EXISTS u1,u2,u3; -- --------------------------------------------------- -- 4. auth: create/alter user: super user -- --------------------------------------------------- CREATE USER u1 SUPERUSER PASSWORD \u0026#39;u1.password\u0026#39;; -- only pg cmpt support super user CREATE USER u2 SYSADMIN PASSWORD \u0026#39;u2.password\u0026#39;; CREATE USER u3 NOSUPERUSER PASSWORD \u0026#39;u3.password\u0026#39;; CREATE USER u4 NOSYSADMIN PASSWORD \u0026#39;u4.password\u0026#39;; SELECT rolname,rolsuper,rolsystemadmin,rolcreaterole,rolcreatedb FROM pg_authid WHERE rolname in (\u0026#39;u1\u0026#39;, \u0026#39;u2\u0026#39;, \u0026#39;u3\u0026#39;, \u0026#39;u4\u0026#39;) ORDER BY rolname; ALTER USER u1 NOSUPERUSER; ALTER USER u2 NOSYSADMIN; ALTER USER u3 SUPERUSER; ALTER USER u4 SYSADMIN; SELECT rolname,rolsuper,rolsystemadmin,rolcreaterole,rolcreatedb FROM pg_authid WHERE rolname in (\u0026#39;u1\u0026#39;, \u0026#39;u2\u0026#39;, \u0026#39;u3\u0026#39;, \u0026#39;u4\u0026#39;) ORDER BY rolname; -- try to alter again ALTER USER u1 NOSUPERUSER; ALTER USER u3 SUPERUSER; SELECT rolname,rolsuper,rolsystemadmin,rolcreaterole,rolcreatedb FROM pg_authid WHERE rolname in (\u0026#39;u1\u0026#39;, \u0026#39;u2\u0026#39;, \u0026#39;u3\u0026#39;, \u0026#39;u4\u0026#39;) ORDER BY rolname; DROP USER IF EXISTS u1,u2,u3,u4; -- --------------------------------------------------- -- 5. access control: permisson of schema for ordinary users -- --------------------------------------------------- CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; SET ROLE u1 PASSWORD \u0026#39;u1.password\u0026#39;; SET search_path TO public; SELECT current_schema; -- check create permisson under public (only pg cmpt allow this) CREATE DATABASE db1; -- no permisson CREATE SCHEMA sch1; -- no permisson CREATE TABLE t1(c1 INT); CREATE VIEW v1 AS SELECT * FROM t1; CREATE INDEX i1 ON t1(c1); CREATE SEQUENCE seq1; CREATE FUNCTION f1() RETURNS INT AS $$ SELECT count(*)::INT FROM t1 $$ LANGUAGE sql; CREATE PROCEDURE p1() IS BEGIN INSERT INTO t1 VALUES (3); END; / CREATE FUNCTION ft1() RETURNS TRIGGER AS $$ BEGIN SELECT count(*) FROM t1; RETURN NEW; END; $$ LANGUAGE plpgsql; CREATE TRIGGER tri1 AFTER INSERT ON t1 FOR EACH ROW EXECUTE PROCEDURE ft1(); CREATE TYPE typ1 AS ENUM(\u0026#39;v1\u0026#39;, \u0026#39;v2\u0026#39;); -- clean DROP TABLE t1 CASCADE; DROP SEQUENCE seq1; DROP FUNCTION f1; DROP PROCEDURE p1; DROP FUNCTION ft1; DROP TYPE typ1; RESET ROLE; RESET search_path; DROP USER IF EXISTS u1; -- --------------------------------------------------- -- 6. access control: permisson of database for ordinary users -- --------------------------------------------------- CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; \\c template1 SET ROLE u1 PASSWORD \u0026#39;u1.password\u0026#39;; SELECT current_database; SELECT current_user; CREATE TABLE tempt1(c1 INT); INSERT INTO tempt1 VALUES (3); DROP TABLE tempt1; \\c regression -- \\c postgres DROP USER u1; ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/8-requirement-hikvision-auth/","summary":"\u003cp\u003e本需求包含6个小需求：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e身份认证：创建用户：CREATE/SET USER .. PASSWORD ..，密码可以只设置2类字符\u003c/li\u003e\n\u003cli\u003e身份认证：创建用户：CREATE/SET [角色] USER ..，角色支持指定SUPERUSER和NOSUPERUSER\u003c/li\u003e\n\u003cli\u003e身份认证：查看用户：SELECT .. FROM pg_user，普通用户可查询pg_user视图（仅pg兼容性）\u003c/li\u003e\n\u003cli\u003e身份认证：登录用户：SET ROLE new_user [PASSWORD ..]，new_user是会话用户时，可以不指定PASSWORD\u003c/li\u003e\n\u003cli\u003e访问控制：Database权限：普通用户可访问template1数据库（仅pg兼容性）\u003c/li\u003e\n\u003cli\u003e访问控制：Schema权限：普通用户可在public下执行CREATE操作（仅pg兼容性）\u003c/li\u003e\n\u003c/ol\u003e\n\u003cul\u003e\n\u003cli\u003e描述\u003c/li\u003e\n\u003c/ul\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e身份认证：创建用户\u003cbr\u003e\n变更：用户密码可以只包含2类字符\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- password_polcy取值不同，密码需包含的字符种类数不同，为1时需3类，需2时需4类，为3时需2类\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSYSTEM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSET\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword_policy\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eOT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 修改取值范围[0,2]为[0,3]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;password1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 此时，密码可以只含2类字符\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eold_user\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORd\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;password1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e身份认证：创建用户\u003cbr\u003e\n变更：可以指定SUPERUSER角色\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUPERUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 支持设置 SUPERUSER 角色\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eNOSUPERUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 支持取消 SUPERUSER 角色\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eold_user\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUPERUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e身份认证：查看用户\u003cbr\u003e\n变更：普通用户可查询pg_user视图（仅pg兼容性）\u003c/p\u003e","title":"海量 8 需求 海康身份认证"},{"content":"假设集群里已经存在表级透明加密模块，在此基础上设计一个高性能、高易用性的 WAL 加密模块。\nWAL 加密的难点几乎不在\u0026quot;加密\u0026quot;本身，而在两件事：同一个 8KB 页会被反复重写，以及恢复路径要在拿不到 catalog 的时候就能解密。下面按设计决策的顺序展开。\n1 威胁模型 先划清边界，因为它直接决定后面几个取舍。\n要防的：磁盘 / 备份 / 归档介质被拖走；DBA 之外的运维人员直接读 pg_wal/；WAL 归档到对象存储。 不防的：有 root 权限的在线攻击者（内存里必然有明文）、旁路攻击。 1.1 为什么不用 dm-crypt 了事 如果只是防\u0026quot;介质丢失\u0026quot;，块设备加密（LUKS/dm-crypt）性价比高得多。在数据库内核里做 WAL 加密，真正的理由只有三个：\n密钥要由数据库自己管，不能落在 OS 层（密评 / 国测要求）； 归档件要天然带密； 和已有的表级 TDE 共用一套密钥体系。 设计要始终对齐这三个理由，否则很容易做成一个又慢、又没多大意义的模块。\n1.2 FPI 是必须堵的洞 既然表级 TDE 已经存在，那么 FPI（full page image）就是个必堵的泄漏点。\n如果 TDE 是在 smgr 层做的（缓冲区里是明文、写盘时加密），那么 WAL 里的 FPI 记录的是明文页 —— 加密表的数据会原封不动地漏进 WAL。\n只要集群里存在任何一张加密表，WAL 加密就必须强制开启，不能是两个独立开关。\n实现上做成一个集群级的 data_encryption = on，或者至少让 CREATE ENCRYPTION POLICY 在 WAL 加密未开启时直接报错。这是易用性设计里最重要的一条：不要把一个\u0026quot;配错了就静默泄密\u0026quot;的组合留给用户。\n2 加密边界：页级，页头留明文 2.1 粒度选择 粒度 问题 按 record 记录平均才一百多字节，AES-NI 流水线跑不起来；XLogReader 要改得面目全非；record header 还得留明文 按 segment（16MB） 无法处理\u0026quot;写了一半的段\u0026quot;，直接出局 按 XLOG_BLCKSZ 页 ✅ 和 I/O 单位对齐，reader 天然按页读 选页级。\n2.2 页头必须留明文 +------------------------------+ | XLogPageHeaderData | ← 明文，24B（段首页 40B） +------------------------------+ | payload | ← 密文 | | +------------------------------+ 因为 IV / tweak 要从 xlp_pageaddr 和 xlp_tli 推导，而这两个字段本身就在页头里 —— 不留明文就是鸡生蛋。\n好处是 pg_waldump 不带密钥也能遍历页结构、判断段边界；坏处是泄露 LSN 和 TLI，这个可以接受。\npayload 里的一切都要加密，包括 record header（xl_rmid、xl_info、block refs）。否则攻击者能从 rmgr 序列反推出业务行为模式，密评评审时这算个实打实的扣分项。\n3 算法与 tweak：核心是前缀稳定性 这是整个设计里最容易踩坑的地方。\n3.1 反复重写带来的硬约束 WAL 页会被多次写盘：先写 02000 字节，后面填满了再写 05000 字节。这意味着：\n同一个磁盘位置的同一段字节，必须在每次重写时产生完全相同的密文。\n否则崩溃恢复时会读到前后不一致的页。\n这条要求排除了任何\u0026quot;每次随机 IV\u0026quot;的方案 —— 加密必须是位置确定性的。\n3.2 为什么选 XTS 而不是 CTR CTR 满足前缀稳定性，而且并行、无填充、能随机访问，看起来是最优解。但 CTR 有一个致命的失效模式：同一段密钥流加密两份不同的明文，两份明文直接异或泄露。\n而 WAL 里恰好有几个地方会让 LSN 重复：\n时间线切换：备库提升后，TLI=2 的 WAL 会在和 TLI=1 相同的 LSN 区间写入不同内容。如果 IV 只含 LSN，这里就是直接的密钥流复用。 pg_resetwal / 从备份重建后 LSN 回退。 所以如果用 CTR，IV 必须是 (system_identifier, timeline_id, LSN, block_counter) 的完整组合，少一个字段就是灾难 —— 而这个约束在代码里没有任何编译期保护。\nAES-256-XTS（国密场景下 SM4-XTS）在这里更稳：tweak 复用最坏只泄露\u0026quot;这两个 16 字节块相同\u0026quot;，不会泄露明文本身。\n对一个要长期维护、会被后人改动的模块，我更愿意选一个\u0026quot;用错了不会当场崩盘\u0026quot;的原语。\ntweak = f(segment_no, page_no_in_segment, timeline_id) 每 16B 块独立加密 → 天然前缀稳定 尾部不足 16 字节的部分用密文窃取（CTS）；或者更简单：重写时从 ≤ 写入起点的最近 16 字节边界开始重新加密。跨边界的那个半块会被重新加密成不同密文，但因为写的是同一个磁盘位置，没有正确性问题。\n3.3 国密与密码卡的性能陷阱 要过国测大概率要用 SM4。这里有个很实际的坑：\n千万不要把 WAL 的批量加解密走密码卡（SDF 接口）。\n一次 SDF 调用的往返在几十到几百微秒量级，而 WAL 刷盘路径上每页都要调一次，直接把提交延迟打穿。\n正确的分层是：\n层次 由谁做 频率 主密钥 wrap/unwrap、随机数、密钥生命周期证明 密码卡（SDF） 低频 WAL 页的批量加解密 软件实现 每页 x86 上 SM4 走 AVX2/GFNI 的实现能到 1~3 GB/s； ARMv8 有 SM4 专用指令； 启动时探测 CPU 特性并选择实现。 这个分层在评审时也站得住脚：密钥全生命周期在密码卡内，工作密钥只在受保护内存中以明文存在。\n4 性能设计：真正的瓶颈不在写路径 4.1 写路径 自然的挂载点是 XLogWrite() 里 pg_pwrite() 之前 —— 但那是 WALWriteLock 的临界区，把 crypto 塞进去会直接拉长 group commit 的串行段。\n方案 A：bounce buffer（推荐作为 v1） WAL buffers 保持明文，加密到一块独立的 scratch buffer 再写盘。\n代价：每页多一次 8KB memcpy。1 GB/s 的 WAL 产生率下大约多 10% 的一个核，可以接受。 buffer 必须按 PG_IO_ALIGN_SIZE（4KB）对齐，否则 direct I/O 路径会退化。 最大的好处是安全：不存在\u0026quot;某个字节被异或两次变回明文\u0026quot;这类静默泄密 bug。 方案 B：原地增量加密（后续优化） 在 XLogCtl 里维护一个和 xlblocks 平行的 encrypted_upto[] 数组，每次只加密 [encrypted_upto, write_end) 这一段，零拷贝。\n因为 WaitXLogInsertionsToFinish() 保证了写入点以下没有在途的 insert，并发上是安全的。\n但 encrypted_upto 只要算错一个字节，要么双重加密（磁盘上出现明文），要么漏加密 —— 这两种错误都不会报错，只会静默发生。所以要等 A 方案跑稳、有了完整回归用例之后再上 B。\n密钥流预计算（两个方案都适用） XTS/CTR 的密钥流（或 tweak 序列）只依赖位置，不依赖明文。所以可以让 walwriter 或一个辅助进程提前把未来 N 个页的密钥流算好，刷盘时临界区里只剩一次 XOR（≈ memcpy 速度）。\n注意：预计算出来的密钥流等价于密钥材料，必须 mlock 住、禁止进 core dump、时间线切换时立即作废。\n4.2 读路径才是真正要盯的 挂载点只有两处：XLogPageRead()（恢复）和 WALRead()（walsender / pg_waldump）。解密进 XLogReaderState.readBuf，每 8KB 一次，正好和现有的按页读取对齐。\n但受影响最大的是崩溃恢复和备库重放：\n路径 加密开销 主库写 WAL 可并行、可预计算，影响小 walreceiver 落盘 零开销（收到的就是密文，直接写） startup 进程重放 单线程串行解密，无法并行 恢复是单进程串行读 WAL 的。如果软件 SM4 只有 500 MB/s，而 NVMe 能吐 3 GB/s，恢复时间会被解密直接拖长数倍。\nRTO 才是这个模块真正的性能风险点。 验收时必须单独测崩溃恢复耗时和备库 apply lag，而不是只看 pgbench TPS。\n4.3 与 wal_compression 的顺序 wal_compression 是在 XLogRecordAssemble() 里做的，加密在写盘时做，所以顺序天然是\u0026quot;先压缩后加密\u0026quot;，是对的 —— 反过来就完全压不动了。\n这个不用改，但值得在注释里写一句，防止后人调整层次时搞反。\n5 密钥管理：易用性主要体现在这里 5.1 密钥必须放在文件里，不能放 catalog 这是最容易设计错的一点。\nstartup 进程开始重放 WAL 时，catalog 还不可读（catalog 本身要靠重放才能一致）。所以 WAL 密钥不能存在 pg_key_data 这类系统表里。\n放在一个独立文件，比如 global/pg_wal_keys，内容自包含：\n{ key_id, wrapped_wal_key, kms_ref / 密码卡容器标识, algo, start_lsn, kcv } 这样 pg_waldump、pg_rewind、pg_basebackup 这些离线工具在没有 running server 的情况下也能拿到密钥（用主密钥解开即可）。这一条决定了整套工具链是否好用。\n5.2 LSN 密钥映射表 文件里存的不是一个密钥，而是一张有序映射：\nLSN 0/00000000 → NONE (加密启用前的历史段，保持明文) LSN 3/A0000000 → key_id = 1 LSN 9/1C000000 → key_id = 2 (轮转) 按段边界切换，不要按任意 LSN 切 —— 一个段一把密钥，归档和 restore 的逻辑会简单一个量级。\n这张表带来两个很大的易用性收益：\n在线轮转：生成新密钥 → 用主密钥包装 → 追加映射 → pg_switch_wal()。旧段依然可解密，旧密钥等归档过期后再退役。全程不停机。 存量集群可直接启用：不需要 initdb，也不需要重写任何东西。这和表级 TDE 必须重写表数据形成鲜明对比，是个很好卖的特性。 5.3 和表级 TDE 共用主密钥 WAL 密钥用同一个 MEK 包装，挂在已有的密钥层次下面。\n用户视角只有一个主密钥要轮转、一个 KMS 要配 —— 这是\u0026quot;高易用性\u0026quot;最实在的体现。\n6 周边生态：别让工具链崩掉 场景 设计 物理复制 walsender 直接发密文。备库零解密开销，且不依赖 TLS 配置是否正确。代价是备库必须先有密钥文件 —— 由 pg_basebackup 带过去 归档 archive_command 拷的就是密文，归档件天然加密，不需要额外做任何事 逻辑复制 解码时在 walsender 里解密成明文，再按逻辑格式发给订阅端。这条链路上的明文只能靠 TLS 保护，必须在文档里写清楚。另外解码要重复回读 WAL，解密开销比物理复制高，readBuf 级别的缓存能吃掉大部分 pg_waldump 加 -D \u0026lt;datadir\u0026gt; 让它能找到密钥文件；不带密钥时降级为只输出页结构 pg_rewind 要读 WAL 找分歧点，走同一套离线密钥加载 pg_receivewal 存密文即可，不需要密钥 7 失败模式：这个模块最危险的地方 7.1 用错密钥 = 静默数据丢失 这个必须单独拿出来说。\nWAL 记录的完整性靠 CRC32C。密钥错了 → 解出乱码 → CRC 校验失败 → 恢复代码会把它当成 \u0026ldquo;WAL 正常结束\u0026rdquo; 然后停止重放。\n结果就是：数据库起来了，看着一切正常，实际上丢了最后一大段事务。\n必须堵住：\n页头（明文区）里存 key_id，读的时候比对； 密钥文件里存 KCV（key check value，比如 E_K(0) 截断），加载密钥时就验证，而不是等到解密失败； 恢复过程中，如果一条记录 CRC 失败、但它所在的页 key_id 指向一个我们有的密钥，就不能当作 end-of-WAL —— 要 FATAL，宁可起不来也不能悄悄丢数据。 7.2 完整性的坦白 CTR/XTS 只给机密性，不给完整性。WAL 的 CRC32C 不是密码学 MAC，改了 WAL 再重算 CRC 是完全可行的。\n要真正抗篡改就得上 AEAD（GCM / SM4-GCM），但每页 16 字节的 tag 没地方放（要么改页格式压缩可用载荷，要么搞 sidecar 文件），而且和\u0026quot;页被反复重写\u0026quot;叠加之后逻辑相当绕。\n建议 v1 明确只做机密性，在设计文档里把这个边界写死，别让评审或用户误以为它防篡改；抗篡改作为后续版本，或者交给存储层 / 文件系统。\n8 落地与验收 8.1 代码结构 控制在一个 walcrypt.c 里，对外只暴露两个函数：\nvoid WALEncrypt(char *dst, const char *src, XLogRecPtr startptr, Size nbytes, TimeLineID tli); void WALDecrypt(char *buf, XLogRecPtr startptr, Size nbytes, TimeLineID tli); 调用点应该只有三处：\nXLogWrite() —— 写 XLogPageRead() —— 恢复时读 WALRead() —— walsender / 工具读 如果实现过程中发现需要往第四、第五个地方插钩子，说明抽象漏了，应该退回来重新想，而不是继续加钩子。这是判断设计是否还成立的标准。\n8.2 验收指标 项 目标 pgbench TPS 回退 \u0026lt; 3% 批量导入（WAL 密集）吞吐回退 \u0026lt; 5% 崩溃恢复耗时增加 \u0026lt; 10%（重点） 备库 apply lag 增加 基本为 0（密文传输） 密钥轮转 在线，无连接中断 8.3 最该覆盖的测试用例 都在\u0026quot;反复重写\u0026quot;的边界上：\n写了一半的页 + 崩溃 + 恢复 + 继续追加； 时间线切换后，同一 LSN 区间写入不同内容； 跨段边界的记录； 密钥轮转恰好落在段中间； 用错密钥启动（必须 FATAL，不能静默截断）。 这几个用例写扎实了，模块基本就稳了。\n9 待深挖 两块值得继续展开：\n原地增量加密的并发证明 —— 要论证 encrypted_upto 和 WaitXLogInsertionsToFinish() 的交互确实无隙； 逻辑解码路径上的解密开销 —— 解码要反复回读 WAL，解密可能会把已有的逻辑复制性能优化吃掉一部分。 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/wal-encryption-design/","summary":"\u003cp\u003e假设集群里已经存在表级透明加密模块，在此基础上设计一个高性能、高易用性的 WAL 加密模块。\u003c/p\u003e\n\u003cp\u003eWAL 加密的难点几乎不在\u0026quot;加密\u0026quot;本身，而在两件事：\u003cstrong\u003e同一个 8KB 页会被反复重写\u003c/strong\u003e，以及\u003cstrong\u003e恢复路径要在拿不到 catalog 的时候就能解密\u003c/strong\u003e。下面按设计决策的顺序展开。\u003c/p\u003e\n\u003ch2 id=\"1-威胁模型\"\u003e1 威胁模型\u003c/h2\u003e\n\u003cp\u003e先划清边界，因为它直接决定后面几个取舍。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e要防的\u003c/strong\u003e：磁盘 / 备份 / 归档介质被拖走；DBA 之外的运维人员直接读 \u003ccode\u003epg_wal/\u003c/code\u003e；WAL 归档到对象存储。\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e不防的\u003c/strong\u003e：有 root 权限的在线攻击者（内存里必然有明文）、旁路攻击。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"11-为什么不用-dm-crypt-了事\"\u003e1.1 为什么不用 dm-crypt 了事\u003c/h3\u003e\n\u003cp\u003e如果只是防\u0026quot;介质丢失\u0026quot;，块设备加密（LUKS/dm-crypt）性价比高得多。在数据库内核里做 WAL 加密，真正的理由只有三个：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e密钥要由数据库自己管，不能落在 OS 层（密评 / 国测要求）；\u003c/li\u003e\n\u003cli\u003e归档件要天然带密；\u003c/li\u003e\n\u003cli\u003e和已有的表级 TDE 共用一套密钥体系。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e设计要始终对齐这三个理由，否则很容易做成一个又慢、又没多大意义的模块。\u003c/p\u003e\n\u003ch3 id=\"12-fpi-是必须堵的洞\"\u003e1.2 FPI 是必须堵的洞\u003c/h3\u003e\n\u003cp\u003e既然表级 TDE 已经存在，那么 \u003cstrong\u003eFPI（full page image）就是个必堵的泄漏点\u003c/strong\u003e。\u003c/p\u003e\n\u003cp\u003e如果 TDE 是在 smgr 层做的（缓冲区里是明文、写盘时加密），那么 WAL 里的 FPI 记录的是\u003cstrong\u003e明文页\u003c/strong\u003e —— 加密表的数据会原封不动地漏进 WAL。\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e只要集群里存在任何一张加密表，WAL 加密就必须强制开启，不能是两个独立开关。\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003e实现上做成一个集群级的 \u003ccode\u003edata_encryption = on\u003c/code\u003e，或者至少让 \u003ccode\u003eCREATE ENCRYPTION POLICY\u003c/code\u003e 在 WAL 加密未开启时直接报错。这是易用性设计里最重要的一条：\u003cstrong\u003e不要把一个\u0026quot;配错了就静默泄密\u0026quot;的组合留给用户\u003c/strong\u003e。\u003c/p\u003e","title":"WAL 加密模块设计"},{"content":"","permalink":"https://my-blog.j8465383071.workers.dev/posts/compliance/sdl-process-security/","summary":"","title":"Vastbase 数据库研发过程安全分析报告"},{"content":"1 容器 1.1 基本概念 c++ stl\n对象 指针 引用 迭代器 容器接口 1.1 接口 // 1.1 vector —— 动态数组 vector\u0026lt;int\u0026gt; v = {1, 2, 3}; v.push_back(4); // 末尾添加 v.pop_back(); // 删除末尾 v.size(); // 元素个数 v.empty(); // 是否为空 v[0]; // 随机访问（无边界检查） v.at(0); // 随机访问（边界检查） v.front(); v.back(); // 首/尾元素 v.clear(); // 清空 // 1.2 deque —— 双端队列 deque\u0026lt;int\u0026gt; d = {1, 2}; d.push_front(0); // 头插 d.push_back(3); // 尾插 d.pop_front(); // 头删 d.pop_back(); // 尾删 d.front(); d.back(); // 首/尾访问 d.size(); d.empty(); // 1.3 list —— 双向链表 list\u0026lt;int\u0026gt; l = {1, 2, 3}; l.push_front(0); l.push_back(4); l.pop_front(); l.pop_back(); l.remove(2); // 删除所有值为2的元素 l.size(); l.empty(); l.front(); l.back(); // 1.4 set —— 有序唯一集合 set\u0026lt;int\u0026gt; s = {3, 1, 4, 1}; // 实际存储 {1,3,4} s.insert(2); // 插入 s.erase(3); // 删除指定值 s.find(4); // 查找，返回迭代器，未找到返回 end() s.count(1); // 计数（0或1） s.size(); s.empty(); // 允许重复元素用 multiset，接口基本相同 // 1.5 map —— 有序键值对 map\u0026lt;string, int\u0026gt; ages; ages[\u0026#34;Alice\u0026#34;] = 25; // 插入/修改；注意：若 key 不存在，[] 会自动插入一个默认值(0) ages[\u0026#34;Bob\u0026#34;] = 30; ages.erase(\u0026#34;Alice\u0026#34;); // 删除 ages.find(\u0026#34;Bob\u0026#34;); // 查找，不想触发自动插入就用 find 而不是 [] ages.count(\u0026#34;Tom\u0026#34;); // 计数 ages.size(); ages.empty(); // 允许重复key用 multimap，接口基本相同 // 1.6 unordered_set —— 哈希无序集合 unordered_set\u0026lt;int\u0026gt; us = {3, 1, 4, 1}; us.insert(2); us.erase(4); us.find(3); // O(1) 查找 us.count(1); us.size(); us.empty(); // 1.7 unordered_map —— 哈希无序键值对 unordered_map\u0026lt;string, int\u0026gt; scores; scores[\u0026#34;Tom\u0026#34;] = 95; scores[\u0026#34;Jerry\u0026#34;] = 88; scores.erase(\u0026#34;Tom\u0026#34;); scores.find(\u0026#34;Jerry\u0026#34;); scores.count(\u0026#34;Bob\u0026#34;); scores.size(); scores.empty(); // 1.8 stack —— 栈（LIFO） stack\u0026lt;int\u0026gt; st; st.push(1); // 入栈 st.push(2); st.top(); // 查看栈顶 st.pop(); // 出栈（无返回值） st.empty(); st.size(); // 1.9 priority_queue —— 优先队列（默认最大堆） priority_queue\u0026lt;int\u0026gt; pq; pq.push(5); pq.push(1); pq.push(10); pq.top(); // 最大元素（10） pq.pop(); // 移除堆顶 pq.empty(); pq.size(); // 想要最小堆：priority_queue\u0026lt;int, vector\u0026lt;int\u0026gt;, greater\u0026lt;int\u0026gt;\u0026gt; minPq; // 1.10 pair —— 两个值的组合，不用专门定义 struct pair\u0026lt;string, int\u0026gt; p1 = {\u0026#34;Alice\u0026#34;, 25}; p1.first; // \u0026#34;Alice\u0026#34; p1.second; // 25 pair\u0026lt;int, int\u0026gt; p2 = make_pair(1, 2); // 另一种构造写法 // 1.11 string —— 字符串（可以当成 char 的容器，替代 char* + strcpy/strcat 那一套） string s2 = \u0026#34;hello\u0026#34;; s2 += \u0026#34; world\u0026#34;; // 拼接 s2.size(); s2.length(); // 长度（两个等价） s2.empty(); s2[0]; // 下标访问 s2.substr(1, 3); // 从下标1开始取3个字符，\u0026#34;ell\u0026#34; s2.find(\u0026#34;wor\u0026#34;); // 查找子串，返回起始下标，找不到返回 string::npos s2.replace(0, 5, \u0026#34;Hi\u0026#34;); // 替换 s2.append(\u0026#34;!\u0026#34;); // 追加 to_string(42); // int -\u0026gt; string stoi(\u0026#34;123\u0026#34;); // string -\u0026gt; int s2.c_str(); // 要传给 C 函数（如 fopen）时转成 const char* // 1.12 array —— 固定大小数组（比原生C数组多了 .size() 等接口，但不能动态扩容） array\u0026lt;int, 3\u0026gt; a = {1, 2, 3}; a.size(); a[0]; a.fill(0); // 全部填充为0 1.2 其他 对所有容器通用\nvector\u0026lt;int\u0026gt; v = {10, 20, 30, 40}; // 1 正向遍历 for (auto it = v.begin(); it != v.end(); ++it) { cout \u0026lt;\u0026lt; *it \u0026lt;\u0026lt; \u0026#34; \u0026#34;; } // 2 反向遍历 for (auto it = v.rbegin(); it != v.rend(); ++it) { cout \u0026lt;\u0026lt; *it \u0026lt;\u0026lt; \u0026#34; \u0026#34;; } // 交换 vector\u0026lt;int\u0026gt; v2 = {100, 200}; v.swap(v2); // 现在 v={100,200}, v2={10,20,30,40} // 遍历 for (int x : v) { cout \u0026lt;\u0026lt; x \u0026lt;\u0026lt; \u0026#34; \u0026#34;; } // 遍历修改 for (int\u0026amp; x : v) { x = x * 2; // 每个元素翻倍（用 \u0026amp; 拿到的是引用，不加 \u0026amp; 修改的是拷贝，不会生效） } // 指定位置插入/删除 v.insert(v.begin() + 1, 99); // 在下标1处插入99 v.erase(v.begin()); // 删除第一个元素 v.emplace_back(10); // 等价于 push_back，但直接在容器内原地构造，少一次拷贝 // ⚠️ 迭代器失效：vector 在 push_back 触发扩容时， // 之前保存的迭代器/指针/引用会全部失效，不能再用 // （和 C 里 realloc 之后旧指针失效是一个道理） vector\u0026lt;int\u0026gt; vv = {1, 2, 3}; int* p = \u0026amp;vv[0]; vv.push_back(4); // 如果触发了扩容，p 就已经失效，不能再解引用 2 函数 vector\u0026lt;int\u0026gt; v = {5, 2, 8, 1, 9}; // ---------- 排序 ---------- sort(v.begin(), v.end()); // 升序：{1,2,5,8,9} sort(v.begin(), v.end(), greater\u0026lt;int\u0026gt;()); // 降序：{9,8,5,2,1} // ---------- 查找 ---------- auto it = find(v.begin(), v.end(), 5); // 线性查找 if (it != v.end()) cout \u0026lt;\u0026lt; \u0026#34;找到了 \u0026#34; \u0026lt;\u0026lt; *it; // ---------- 二分查找（必须有序） ---------- bool found = binary_search(v.begin(), v.end(), 8); // true // ---------- 区间查找（必须有序） ---------- auto lb = lower_bound(v.begin(), v.end(), 5); // 第一个 \u0026gt;=5 的位置 auto ub = upper_bound(v.begin(), v.end(), 5); // 第一个 \u0026gt;5 的位置 // ---------- 最值 ---------- auto maxIt = max_element(v.begin(), v.end()); // 迭代器，指向最大值 auto minIt = min_element(v.begin(), v.end()); // 迭代器，指向最小值 cout \u0026lt;\u0026lt; *maxIt \u0026lt;\u0026lt; \u0026#34; \u0026#34; \u0026lt;\u0026lt; *minIt; int m1 = max(3, 5); // 5，直接比较两个值（不是容器） int m2 = min(3, 5); // 3 // ---------- 计数 ---------- int c1 = count(v.begin(), v.end(), 2); // 值等于2的个数 int c2 = count_if(v.begin(), v.end(), [](int x){ // 满足条件的个数 return x % 2 == 0; }); // ---------- 遍历（替代循环） ---------- for_each(v.begin(), v.end(), [](int x) { cout \u0026lt;\u0026lt; x \u0026lt;\u0026lt; \u0026#34; \u0026#34;; }); // ---------- 变换 ---------- vector\u0026lt;int\u0026gt; squared(v.size()); transform(v.begin(), v.end(), squared.begin(), [](int x){ return x * x; }); // ---------- 反转 / 填充 ---------- reverse(v.begin(), v.end()); // 原地反转 fill(v.begin(), v.end(), 0); // 全部填充为0 // ---------- 累加 ---------- int sum = accumulate(v.begin(), v.end(), 0); // 0+所有元素 // ---------- 复制 ---------- vector\u0026lt;int\u0026gt; dest(v.size()); copy(v.begin(), v.end(), dest.begin()); // ---------- 迭代器距离 ---------- int idx = distance(v.begin(), it); // it 到 begin 的距离，常用来把迭代器转成下标 // ---------- 删除（配合 erase） ---------- v = {1, 2, 3, 2, 4}; auto new_end = remove(v.begin(), v.end(), 2); // 把2移到末尾，返回新逻辑末尾 v.erase(new_end, v.end()); // 实际删除，v 变成 {1,3,4} // ---------- 去重（必须有序） ---------- v = {1, 1, 2, 3, 3, 4}; sort(v.begin(), v.end()); // 先排序 auto last = unique(v.begin(), v.end()); v.erase(last, v.end()); 3 示例 lru缓存 https://leetcode.cn/problems/OrIXps/description/\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/cpp/","summary":"\u003ch1 id=\"1-容器\"\u003e1 容器\u003c/h1\u003e\n\u003ch2 id=\"11-基本概念\"\u003e1.1 基本概念\u003c/h2\u003e\n\u003cp\u003ec++ stl\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e对象\u003c/li\u003e\n\u003cli\u003e指针\u003c/li\u003e\n\u003cli\u003e引用\u003c/li\u003e\n\u003cli\u003e迭代器\u003c/li\u003e\n\u003cli\u003e容器接口\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"11-接口\"\u003e1.1 接口\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-cpp\" data-lang=\"cpp\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 1.1 vector —— 动态数组\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evector\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ev\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ev\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epush_back\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e          \u003cspan class=\"c1\"\u003e// 末尾添加\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ev\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epop_back\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e            \u003cspan class=\"c1\"\u003e// 删除末尾\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ev\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e                \u003cspan class=\"c1\"\u003e// 元素个数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ev\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eempty\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e               \u003cspan class=\"c1\"\u003e// 是否为空\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ev\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e                    \u003cspan class=\"c1\"\u003e// 随机访问（无边界检查）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ev\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eat\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e                 \u003cspan class=\"c1\"\u003e// 随机访问（边界检查）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ev\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efront\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"n\"\u003ev\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eback\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e     \u003cspan class=\"c1\"\u003e// 首/尾元素\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ev\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eclear\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e               \u003cspan class=\"c1\"\u003e// 清空\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 1.2 deque —— 双端队列\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003edeque\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ed\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epush_front\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e         \u003cspan class=\"c1\"\u003e// 头插\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epush_back\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e          \u003cspan class=\"c1\"\u003e// 尾插\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epop_front\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e            \u003cspan class=\"c1\"\u003e// 头删\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epop_back\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e             \u003cspan class=\"c1\"\u003e// 尾删\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efront\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eback\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e     \u003cspan class=\"c1\"\u003e// 首/尾访问\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eempty\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 1.3 list —— 双向链表\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003elist\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003el\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003el\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epush_front\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003el\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epush_back\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003el\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epop_front\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"n\"\u003el\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epop_back\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003el\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eremove\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e             \u003cspan class=\"c1\"\u003e// 删除所有值为2的元素\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003el\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"n\"\u003el\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eempty\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003el\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efront\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"n\"\u003el\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eback\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 1.4 set —— 有序唯一集合\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eset\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003es\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 实际存储 {1,3,4}\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003es\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003einsert\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e               \u003cspan class=\"c1\"\u003e// 插入\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003es\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eerase\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e                \u003cspan class=\"c1\"\u003e// 删除指定值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003es\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efind\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e                 \u003cspan class=\"c1\"\u003e// 查找，返回迭代器，未找到返回 end()\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003es\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e                \u003cspan class=\"c1\"\u003e// 计数（0或1）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003es\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"n\"\u003es\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eempty\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 允许重复元素用 multiset，接口基本相同\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 1.5 map —— 有序键值对\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003emap\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eages\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eages\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Alice\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e25\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e        \u003cspan class=\"c1\"\u003e// 插入/修改；注意：若 key 不存在，[] 会自动插入一个默认值(0)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eages\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Bob\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e30\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eages\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eerase\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Alice\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e       \u003cspan class=\"c1\"\u003e// 删除\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eages\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efind\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Bob\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e          \u003cspan class=\"c1\"\u003e// 查找，不想触发自动插入就用 find 而不是 []\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eages\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Tom\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e         \u003cspan class=\"c1\"\u003e// 计数\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eages\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"n\"\u003eages\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eempty\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 允许重复key用 multimap，接口基本相同\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 1.6 unordered_set —— 哈希无序集合\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eunordered_set\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003eus\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eus\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003einsert\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eus\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eerase\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e4\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eus\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efind\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e                \u003cspan class=\"c1\"\u003e// O(1) 查找\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eus\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eus\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"n\"\u003eus\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eempty\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 1.7 unordered_map —— 哈希无序键值对\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eunordered_map\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003escores\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003escores\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Tom\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e95\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003escores\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Jerry\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e88\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003escores\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eerase\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Tom\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003escores\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efind\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Jerry\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003escores\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ecount\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Bob\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003escores\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"n\"\u003escores\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eempty\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 1.8 stack —— 栈（LIFO）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003estack\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003est\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003est\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epush\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e                \u003cspan class=\"c1\"\u003e// 入栈\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003est\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epush\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003est\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etop\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e                  \u003cspan class=\"c1\"\u003e// 查看栈顶\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003est\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epop\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e                  \u003cspan class=\"c1\"\u003e// 出栈（无返回值）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003est\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eempty\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"n\"\u003est\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 1.9 priority_queue —— 优先队列（默认最大堆）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003epriority_queue\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003epq\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003epq\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epush\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003epq\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epush\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003epq\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epush\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003epq\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003etop\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e                  \u003cspan class=\"c1\"\u003e// 最大元素（10）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003epq\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003epop\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e                  \u003cspan class=\"c1\"\u003e// 移除堆顶\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003epq\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eempty\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"n\"\u003epq\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 想要最小堆：priority_queue\u0026lt;int, vector\u0026lt;int\u0026gt;, greater\u0026lt;int\u0026gt;\u0026gt; minPq;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 1.10 pair —— 两个值的组合，不用专门定义 struct\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003epair\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"n\"\u003estring\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ep1\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;Alice\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e25\u003c/span\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ep1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efirst\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e                  \u003cspan class=\"c1\"\u003e// \u0026#34;Alice\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003ep1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esecond\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e                 \u003cspan class=\"c1\"\u003e// 25\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003epair\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ep2\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003emake_pair\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e \u003cspan class=\"c1\"\u003e// 另一种构造写法\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 1.11 string —— 字符串（可以当成 char 的容器，替代 char* + strcpy/strcat 那一套）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003estring\u003c/span\u003e \u003cspan class=\"n\"\u003es2\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;hello\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e \u003cspan class=\"o\"\u003e+=\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34; world\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e            \u003cspan class=\"c1\"\u003e// 拼接\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e \u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003elength\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e    \u003cspan class=\"c1\"\u003e// 长度（两个等价）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eempty\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e                     \u003cspan class=\"c1\"\u003e// 下标访问\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esubstr\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e           \u003cspan class=\"c1\"\u003e// 从下标1开始取3个字符，\u0026#34;ell\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efind\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;wor\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e            \u003cspan class=\"c1\"\u003e// 查找子串，返回起始下标，找不到返回 string::npos\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ereplace\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e5\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;Hi\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e    \u003cspan class=\"c1\"\u003e// 替换\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eappend\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;!\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e            \u003cspan class=\"c1\"\u003e// 追加\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eto_string\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e42\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e              \u003cspan class=\"c1\"\u003e// int -\u0026gt; string\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003estoi\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s\"\u003e\u0026#34;123\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e                 \u003cspan class=\"c1\"\u003e// string -\u0026gt; int\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003es2\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003ec_str\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e                 \u003cspan class=\"c1\"\u003e// 要传给 C 函数（如 fopen）时转成 const char*\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e// 1.12 array —— 固定大小数组（比原生C数组多了 .size() 等接口，但不能动态扩容）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003earray\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003esize\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003efill\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e                  \u003cspan class=\"c1\"\u003e// 全部填充为0\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"12-其他\"\u003e1.2 其他\u003c/h2\u003e\n\u003cp\u003e对所有容器通用\u003c/p\u003e","title":"c++"},{"content":" 版本号 日期 修改说明 编制人 审核人 1.0 2026.07.24 完成初稿 沈坤 - 1、核心资产 VexDB 的核心资产分为七类，覆盖数据、结构、访问、运行、审计、内存和密码资源，是数据库安全保护的主要对象。\n核心资产 资产内容 资产价值 数据资产 业务数据、用户数据、交易数据等存储内容 数据库核心资源。泄露、篡改或丢失影响业务安全 数据库结构资产 模式、表、字段、索引、视图、存储过程、函数、约束等 描述数据组织和业务逻辑。非法修改影响业务正确性 数据库管理资产 用户、角色、权限、配置参数、安全策略等 控制访问范围和运行行为。错误配置影响整体安全 数据库运行资产 实例、进程、数据文件、日志文件及计算存储资源 支撑数据库服务运行。破坏导致服务不可用 数据库操作记录资产 访问日志、审计记录、运行日志、管理操作记录等 支撑安全分析、事件追踪和责任认定 数据库内存资产 内存中的业务数据、缓存、会话信息和认证凭证 运行过程中的敏感信息。泄露可能导致数据或凭证暴露 密码与密钥资产 加密密钥、口令摘要、认证凭证等密码资源 支撑身份认证和数据保护。泄露可能导致安全机制失效 核心资产的机密性、完整性和可用性，决定数据库安全运行和业务连续性。\n2、安全风险和应对措施 VexDB 面临外部攻击、内部误操作、权限滥用和运行环境异常等风险，可能导致非法访问、数据泄露、数据篡改、身份冒用和服务不可用。主要风险与应对措施如下。\n安全风险 风险描述 应对措施 非法访问风险 非授权主机连接数据库，获取非法访问入口 网络防火墙 身份认证风险 弱口令、凭证泄露或认证缺陷导致身份冒用 身份认证 通信安全风险 网络传输被窃听、伪造、重放或篡改 安全传输 权限控制风险 权限配置不当或权限提升导致越权访问 访问控制 数据安全风险 数据存储、传输、处理过程中发生泄露或篡改 透明加密、驱动加密、机密计算、动态脱敏、数据防篡改 密钥安全风险 密钥泄露、丢失或生命周期管理不足导致保护失效 密钥管理 操作追溯风险 数据访问和管理操作缺少记录，无法有效追责 数据库审计、数据防篡改 服务可用性风险 恶意请求或资源异常消耗导致性能下降或服务中断 资源安全 运行环境风险 不可信环境或异常运行环境导致数据暴露风险 驱动加密、机密计算、密钥管理 VexDB 通过网络防护、身份认证、访问控制、数据保护、密码保护、安全审计和资源管理等能力，降低非法访问、数据泄露、数据篡改和服务不可用等安全风险。 3、安全机制 VexDB 从接入、传输、访问、存储、计算、合规六个维度构建防御模型，各安全机制相互独立又相互配合。\n3.1 网络防火墙 安全威胁：\n非法来源接入：非授权 IP/网段主机尝试访问数据库服务，建立网络连接 数据库服务暴露：数据库监听地址或服务端口暴露于非可信网络，攻击者可进行端口扫描、服务探测等行为 非授权网络区域访问：不同安全区域之间缺少网络隔离，导致不满足要求的客户端尝试访问数据库服务 安全功能：\n多维度网络接入控制：按照网络来源、目标数据库等维度配置接入规则，实现数据库服务访问边界控制 主机级：按客户端 IP 地址/网段限制数据库服务允许接入的来源范围 数据库级：按目标数据库限制客户端可建立连接的数据库范围 连接策略级：针对不同来源配置允许、拒绝以及认证方式等连接策略 防御效果（与安全威胁一一对应）：\n非法来源接入：主机级接入控制，非授权 IP/网段的连接请求在数据库连接建立阶段被拒绝，避免非法客户端访问数据库服务 数据库服务暴露：通过网络访问规则限制数据库服务可访问范围，减少端口扫描、连接探测等攻击风险 非授权网络区域访问：通过来源地址控制和网络隔离策略，限制不同网络区域之间的数据库访问边界 其他效果：\n性能：规则在数据库连接建立阶段执行，不参与 SQL 请求处理流程，对查询性能无影响 易用性：基于 pg_hba.conf 文本配置，无需重启即可通过 pg_reload_conf() 重新加载生效 使用流程：\n-- 编辑 pg_hba.conf，按\u0026#34;主机/数据库/用户\u0026#34;维度配置接入规则（对应：非法来源接入、数据库服务暴露） -- 格式：host 数据库 用户 地址 认证方式；自上而下匹配，首条命中生效 host all u1 192.168.1.0/24 sm3 -- 仅允许可信网段，强制国密 SM3 认证 hostssl all all 0.0.0.0/0 cert -- 其余来源须 SSL 加密 + 证书认证 host all all 0.0.0.0/0 reject -- 显式拒绝兜底（对应：非授权网络区域访问） -- 重载配置生效（无需重启） SELECT pg_reload_conf(); -- 验证：非授权来源连接被拒 -- vsql -h 10.0.0.1 -U u1 -d vexdb → FATAL: no pg_hba.conf entry 3.2 身份认证 安全威胁：\n弱口令攻击：用户设置简单口令、常用口令或低复杂度口令，容易被字典攻击破解 暴力破解：攻击者通过大量认证请求持续尝试不同口令，获取合法用户访问权限 口令泄露：用户口令因配置泄露、人工泄露、凭证复用等原因被攻击者获取 认证信息窃取：攻击者通过截获或分析认证交互信息，尝试恢复用户认证凭证 默认账户风险：数据库默认账户未及时修改或未禁用，可能被攻击者利用进行非法登录 账户生命周期风险：长期未使用账户、过期账户或异常账户仍保持登录能力，增加非法访问风险 非法身份登录：攻击者使用窃取的账户凭证冒充合法用户尝试登录数据库 安全功能：\n用户生命周期管理：支持用户创建、修改、锁定、解锁、删除等账户管理操作 口令复杂度校验：支持口令长度、字符类型等复杂度策略配置，限制低强度口令使用 弱口令检测：支持常见弱口令检测，阻止高风险口令设置 口令安全存储：采用不可逆密码哈希方式存储用户认证信息，避免明文口令泄露 安全认证协议：支持基于挑战响应机制的认证协议，避免认证过程中直接传输明文口令 认证失败限制：支持连续认证失败次数限制，超过阈值后自动锁定账户 密码有效期管理：支持密码有效期配置，到期提醒或强制修改密码 多因素认证：支持证书认证、Kerberos 等增强认证方式，提高身份可信度 认证会话管理：支持认证会话超时控制，降低长期未使用会话风险 防御效果（与安全威胁一一对应）：\n弱口令攻击：口令复杂度校验 + 弱口令检测，在用户创建或修改密码阶段阻止低强度口令 暴力破解：认证失败限制，连续认证失败达到阈值后自动锁定账户，降低口令爆破风险 口令泄露：口令安全存储，系统中不保存明文密码，降低凭证泄露后的影响 认证信息窃取：安全认证协议采用挑战响应机制，避免认证过程中的明文口令传输 默认账户风险：用户生命周期管理 + 弱口令检测，支持默认账户修改、禁用及安全管理 账户生命周期风险：密码有效期管理 + 用户管理，对长期未使用或过期账户进行限制 非法身份登录：多因素认证增强身份可信度，降低凭证泄露导致的冒用风险 其他效果：\n性能：认证过程在连接建立阶段执行，认证成功后的 SQL 执行过程无额外性能开销 易用性：支持参数化配置认证策略，账户策略可统一管理 可扩展性：支持外部认证源扩展，如 LDAP、Kerberos 等认证方式 使用流程：\n-- 1. 配置口令复杂度与失败锁定策略（对应：弱口令攻击、暴力破解） ALTER SYSTEM SET password_policy = 1; -- 校验至少 1 类有效字符 ALTER SYSTEM SET password_min_length = 8; ALTER SYSTEM SET password_min_uppercase = 1; -- 至少 1 个大写字母 ALTER SYSTEM SET password_min_lowercase = 1; -- 至少 1 个小写字母 ALTER SYSTEM SET password_min_digital = 1; -- 至少 1 个数字 ALTER SYSTEM SET password_min_special = 1; -- 至少 1 个特殊字符 ALTER SYSTEM SET failed_login_attempts = 5; -- 连续失败 5 次锁定 ALTER SYSTEM SET password_lock_time = 1440; -- 锁定 1440 分钟 ALTER SYSTEM SET password_reuse_time = 60; -- 60 天内口令不可复用 SELECT pg_reload_conf(); -- 2. 载入弱口令字典，拦截常见弱口令（对应：弱口令攻击） CREATE WEAK PASSWORD DICTIONARY WITH VALUES (\u0026#39;123456\u0026#39;, \u0026#39;password\u0026#39;, \u0026#39;qwerty\u0026#39;); -- 3. 弱口令创建被拒 CREATE USER u1 PASSWORD \u0026#39;123456\u0026#39;; -- ERROR: Password is too weak -- 4. 合规口令 + 设置有效期（对应：账户生命周期风险） CREATE USER u1 PASSWORD \u0026#39;Vex@12345\u0026#39; VALID UNTIL \u0026#39;2026-12-31\u0026#39;; -- 5. 验证连续失败锁定（对应：暴力破解） -- 用错误口令连续登录 u1 五次 → 账户被自动锁定 3.3 安全传输 安全威胁：\n通信身份冒用：攻击者伪造客户端或服务端身份，尝试建立非法通信连接 通信数据重放：攻击者截获历史通信数据并重新发送，尝试影响正常业务流程 证书伪造：使用非法、自签或伪造证书冒充合法通信实体，实施中间人攻击 网络中间人窃听：攻击者在客户端与服务端之间监听通信内容，获取敏感数据 传输数据篡改：攻击者修改传输过程中的 SQL 请求或响应数据，影响数据完整性 明文传输泄露：未启用加密传输时，口令、SQL 语句及业务数据可能被网络窃取 安全功能：\nTLS 协议：支持 TLS 1.2 加密通信通道，对传输数据进行加密保护 TLCP 协议：支持国密 TLCP 协议，满足国密场景下安全传输需求 双向证书认证：支持客户端与服务端基于数字证书进行双向身份验证 证书有效校验：支持证书有效期、签发机构及合法性校验 算法套件配置：支持配置加密算法套件，限制弱加密算法使用 防御效果（与安全威胁一一对应）：\n通信身份冒用：通过证书认证机制验证通信双方身份，非法实体无法建立可信加密连接 通信数据重放：TLS/TLCP 协议通过记录序列号及完整性校验机制，异常重放数据无法通过校验 证书伪造：通过证书有效性校验，非法、过期或不可信证书无法用于建立安全连接 网络中间人窃听：TLS/TLCP 加密通信通道保护传输数据，防止网络窃听获取明文内容 传输数据篡改：TLS/TLCP 提供数据完整性校验，传输过程中被修改的数据无法通过验证 明文传输泄露：通过强制启用加密通信和限制弱算法套件，避免敏感数据明文传输 其他效果：\n性能：支持 TLS 硬件加速能力，加解密处理开销可控 可扩展性：支持 TLS/TLCP 双协议栈，满足国际算法与国密算法应用场景 使用流程：\n-- 1. 服务端开启 SSL 并强制国密套件（对应：中间人窃听、明文传输泄露） vb_guc set -D $PGDATA -c \u0026#34;ssl=on\u0026#34; vb_guc set -D $PGDATA -c \u0026#34;require_ssl=on\u0026#34; vb_guc set -D $PGDATA -c \u0026#34;ssl_ciphers=\u0026#39;ECDHE-ECDSA-SM4-CBC-SM3\u0026#39;\u0026#34; -- 仅启用国密 SM 套件（国密 TLCP） vb_guc set -D $PGDATA -c \u0026#34;ssl_cert_file=\u0026#39;$PGDATA/server.crt\u0026#39;\u0026#34; vb_guc set -D $PGDATA -c \u0026#34;ssl_key_file=\u0026#39;$PGDATA/server.key\u0026#39;\u0026#34; vb_guc set -D $PGDATA -c \u0026#34;ssl_ca_file=\u0026#39;$PGDATA/demoCA/cacert.pem\u0026#39;\u0026#34; vb_ctl restart -D $PGDATA -- 2. 在 pg_hba.conf 首行强制 SSL + 证书双向认证（对应：通信身份冒用、证书伪造） -- hostssl all u1 0.0.0.0/0 cert -- 3. 客户端配置证书后加密连接（对应：传输数据篡改、通信数据重放） -- export PGSSLMODE=verify-ca PGSSLCERT=.../client.crt PGSSLKEY=.../client.key PGSSLROOTCERT=.../cacert.pem -- vsql -h \u0026lt;db_ip\u0026gt; -p 5432 -d vexdb -U u1 -r 安全威胁：\n未授权访问：无数据库对象访问权限的用户尝试读取或修改数据 越权访问：已授权用户访问职责范围之外的数据库对象或敏感数据 权限提升：普通用户获取超出授权范围的角色或管理权限 权限滥用：合法用户利用已有权限执行超出业务职责范围的操作 权限集中风险：单一管理员同时拥有用户管理、权限管理、审计管理等全部权限，缺少职责分离 特权用户数据访问：高权限用户利用管理权限查看不应访问的业务数据 合规权责分离缺失：用户管理、权限管理、审计管理未进行角色隔离，无法满足等保/商密要求 敏感数据越权读取：用户访问安全级别高于自身权限的数据 敏感数据越权流动：高安全级别数据被低安全级别主体访问或传播 特权用户绕过访问控制：管理员权限绕过普通访问控制策略访问敏感对象 跨范围数据访问：通过复杂查询、关联查询等方式绕过数据隔离限制 安全功能：\n自主访问控制：基于 RBAC 角色权限模型，实现用户、角色与数据库对象权限关联，支持细粒度对象权限控制 三权分立：支持安全管理员、系统管理员、审计管理员角色分离，实现用户管理、权限管理、审计管理职责隔离 强制访问控制：支持表、行、列级安全标记，根据用户安全级别限制敏感数据访问范围 行级访问控制：支持基于策略的行级数据过滤，查询过程中自动添加访问约束，对应用透明 防御效果（与安全威胁一一对应）：\n未授权访问：通过对象权限校验，无访问权限的用户无法读取或修改数据库对象 越权访问：通过细粒度权限控制，仅允许用户访问授权范围内的数据对象 权限提升：通过 RBAC 角色管理和最小权限原则，限制用户获取额外权限 权限滥用：通过最小权限控制，降低用户持有过度权限导致的数据风险 权限集中风险：通过三权分立，用户、权限、安全策略等管理职责相互隔离 特权用户数据访问：通过强制访问控制，对敏感数据访问进行额外安全级别限制 合规权责分离缺失：通过三权分立满足等保/商密关于职责分离要求 敏感数据越权读取：通过强制访问控制，用户安全级别低于数据标记时禁止访问 敏感数据越权流动：通过强制访问控制和行级访问控制，限制敏感数据向低安全级别主体流动 特权用户绕过访问控制：通过强制访问控制策略，限制管理员绕过安全策略访问敏感数据 跨范围数据访问：通过行级访问控制，在查询执行过程中自动增加过滤条件，避免通过关联查询绕过隔离 其他效果：\n性能：权限检查、标签检查、行级过滤均在查询优化和执行阶段完成，对业务访问性能影响可控 易用性：支持角色批量授权、安全策略统一配置，行级访问控制对应用透明 可扩展性：支持对象、行、列多级访问控制粒度，满足不同安全等级保护需求 使用流程：\n-- 自主访问控制 RBAC：按最小权限授权（对应：未授权访问、越权访问、权限提升） CREATE ROLE r1; GRANT USAGE ON SCHEMA public TO r1; GRANT SELECT ON t1 TO r1; CREATE USER u1 PASSWORD \u0026#39;Vex@12345\u0026#39;; GRANT r1 TO u1; -- 验证：u1 执行 DELETE FROM t1 → ERROR: permission denied -- 三权分立：系统/安全/审计管理员相互制衡（对应：权限集中风险、合规权责分离缺失） ALTER SYSTEM SET enable_separation_of_duty = on; -- 重启生效 CREATE USER u2 PASSWORD \u0026#39;Vex@12345\u0026#39; SYSADMIN; -- 系统管理员：运维、对象、参数 CREATE USER u3 PASSWORD \u0026#39;Vex@12345\u0026#39; SSOADMIN; -- 安全管理员：用户与安全策略 CREATE USER u4 PASSWORD \u0026#39;Vex@12345\u0026#39; AUDITADMIN; -- 审计管理员：审计策略与日志 -- 验证：u3 无权创建用户 -- u3 执行 CREATE USER → ERROR: permission denied -- 强制访问控制 MAC：按密级限制敏感数据（对应：敏感数据越权读取、特权用户绕过访问控制） ALTER SYSTEM SET ogmac_enable_mac = on; -- 开启强制访问控制 CREATE SECURITY LABEL l1 \u0026#39;L10:G1\u0026#39;; -- 高密级 CREATE SECURITY LABEL l2 \u0026#39;L5:G1\u0026#39;; -- 低密级 SECURITY LABEL ON TABLE t1 IS \u0026#39;l1\u0026#39;; -- 客体（表）高密级 SECURITY LABEL ON ROLE u1 IS \u0026#39;l2\u0026#39;; -- 主体（用户）低密级 -- 验证：u1 密级低于 t1，读取被拒 -- u1 执行 SELECT * FROM t1 → ERROR -- 行级访问控制 RLS：按会话变量过滤行（对应：跨范围数据访问） CREATE ROW LEVEL SECURITY POLICY p1 ON t1 USING (c2 = current_setting(\u0026#39;app.dept\u0026#39;)); ALTER TABLE t1 ENABLE ROW LEVEL SECURITY; -- SET app.dept = \u0026#39;d1\u0026#39;; SELECT * FROM t1; -- 仅返回 c2=\u0026#39;d1\u0026#39; 的行 3.5 安全审计 安全威胁：\n审计日志篡改：攻击者修改或删除审计记录，隐藏真实操作行为 攻击行为隐匿：关闭审计功能或绕过审计策略，使关键操作无法被记录 恶意操作抵赖：用户否认执行过敏感操作，无法通过审计记录进行追溯 审计日志容量耗尽：大量无效操作产生海量日志，导致关键审计记录无法有效保存 特权用户操作不可追溯：管理员等高权限用户操作缺少独立审计记录，无法进行责任认定 安全功能：\n细粒度审计策略：支持按照用户、操作类型、数据库对象、操作结果等维度配置审计范围 系统审计：支持对权限变更、访问操作、密码变更、登录失败等关键安全事件进行记录 日志安全保护：支持审计日志安全存储，防止未授权修改或删除 日志容量控制：支持审计日志空间、文件数量阈值配置，避免日志无限增长 日志查询分析：支持按照时间、用户等条件查询审计记录（pg_query_audit） 审计员独立管理：支持独立审计管理员管理审计数据，降低高权限用户篡改审计记录风险 防御效果（与安全威胁一一对应）：\n审计日志篡改：日志安全保护 + 审计员独立管理，限制非授权用户修改或删除审计记录 攻击行为隐匿：系统审计 + 细粒度审计策略，对关键安全事件进行持续记录，避免操作无痕 恶意操作抵赖：细粒度审计策略，记录操作用户、时间、对象及操作内容，实现行为追溯 审计日志容量耗尽：日志容量控制，通过空间和文件数量限制保障审计记录持续保存 特权用户操作不可追溯：审计员独立管理，对管理员等特权用户行为进行独立记录和审查 其他效果：\n性能：审计日志采用异步记录机制，降低审计功能对事务处理性能影响 易用性：支持标准 SQL 查询审计日志（pg_query_audit），无需额外分析工具 使用流程：\n-- 1. 开启审计并配置日志目录与容量（对应：攻击行为隐匿、审计日志容量耗尽） ALTER SYSTEM SET enable_audit = on; ALTER SYSTEM SET audit_directory = \u0026#39;$PGDATA/vb_audit_log\u0026#39;; ALTER SYSTEM SET audit_directory_size = 10240; -- 目录最大 10240MB ALTER SYSTEM SET audit_directory_full_policy = 1; -- 满目录处理策略 SELECT pg_reload_conf(); -- 2. 创建审计策略，细粒度记录指定表操作（对应：恶意操作抵赖、特权用户操作不可追溯） CREATE AUDIT POLICY ap1 ON TABLE t1; SELECT * FROM audit_policy; -- 查看已建策略 -- 3. 按时间区间查询审计日志 SELECT * FROM vb_audit_log(\u0026#39;2026-07-22 00:00:00\u0026#39;, now()) WHERE polname = \u0026#39;ap1\u0026#39;; 3.6 驱动加密 安全威胁：\n传输环节信息泄露：客户端与数据库服务端通信过程中，敏感列数据可能被窃听 存储环节信息泄露：数据库以明文形式存储敏感数据，数据库文件泄露可能导致数据暴露 存储介质泄露：磁盘文件、备份文件或数据镜像被非法获取，导致敏感数据泄露 服务端数据窥探：数据库管理员、云环境或不可信运行环境可能直接查看敏感业务数据 密文数据篡改：攻击者修改、替换数据库中的密文数据，导致业务数据被非法改变 应用侧密钥泄露：加密密钥管理不当可能导致加密数据被恢复 安全功能：\n客户端透明加密：通过数据库驱动实现数据自动加密和解密，业务应用无需修改 SQL 列级数据加密：支持指定敏感列进行加密存储，实现不同数据列差异化保护 密文等值查询：支持基于密文的等值查询，客户端对查询条件自动加密，服务端完成密文匹配 密文完整性校验：加密数据同时生成 MAC 校验值，客户端读取数据时自动验证完整性 客户端密钥管理：加密密钥和 MAC 密钥由客户端管理，数据库服务端不保存用户明文密钥 密文存储保护：数据库存储内容、索引数据等持久化内容均以密文形式保存 防御效果（与安全威胁一一对应）：\n传输环节信息泄露：客户端驱动对敏感数据进行加密后传输，网络窃听无法获取明文数据 存储环节信息泄露：敏感列以密文形式存储，数据库文件泄露后无法直接读取业务数据 存储介质泄露：磁盘文件、备份文件中的敏感字段为密文，无客户端密钥无法恢复明文 服务端数据窥探：服务端仅保存和处理密文数据，数据库管理员无法直接查看敏感字段内容 密文数据篡改：通过 MAC 完整性校验机制，检测密文非法修改或替换，校验失败的数据无法正常解密使用 应用侧密钥泄露：通过客户端密钥管理机制，降低密钥集中存储导致的数据泄露风险 与机密计算的关系：\n驱动加密主要解决数据在客户端、传输过程以及数据库存储阶段的机密性和完整性保护，通过客户端加密实现密文存储、密文等值查询以及密文完整性校验。 机密计算主要解决服务端参与复杂计算场景下的数据保护，通过可信执行环境保护计算过程中的明文数据。 其他效果：\n性能：加解密和 MAC 计算主要在客户端完成，减少服务端明文处理开销 易用性：通过驱动自动完成加密、完整性校验、查询改写及解密，业务 SQL 基本无需调整 安全性：数据库服务端无法直接获取敏感字段明文，同时可检测密文数据非法修改 使用流程：\n-- 1. 创建客户端主密钥 CMK（密钥存于客户端，对应：应用侧密钥泄露） CREATE CLIENT MASTER KEY cmk1 WITH (KEY_STORE = localkms, KEY_PATH = \u0026#34;key_path_value\u0026#34;, ALGORITHM = RSA_2048); -- 2. 创建列加密密钥 CEK，绑定 CMK CREATE COLUMN ENCRYPTION KEY cek1 WITH VALUES (CLIENT_MASTER_KEY = cmk1, ALGORITHM = AEAD_AES_256_CBC_HMAC_SHA256); -- 3. 创建加密表，敏感列经驱动加密后密文落盘（对应：存储环节泄露、服务端数据窥探） CREATE TABLE t1 ( c1 INT, c2 TEXT ENCRYPTED WITH (column_encryption_key = cek1, encryption_type = DETERMINISTIC) ); -- 4. 经密态驱动写入与等值查询（对应：传输环节泄露、密文数据篡改） -- 客户端驱动自动加解密并校验 MAC，服务端全程只处理密文 INSERT INTO t1 VALUES (1, \u0026#39;v1\u0026#39;); SELECT * FROM t1 WHERE c2 = \u0026#39;v1\u0026#39;; -- 5. 验证：服务端存储为密文 -- \\d t1 → c2 列 Modifiers = encrypted 3.7 机密计算 规划中。\n3.8 密码函数 安全威胁：\n弱密码算法风险：使用 DES、MD5 等已淘汰算法保护数据，导致加密数据或摘要结果易被破解 密码算法不合规：未采用符合国家密码管理要求或行业标准的密码算法，无法满足安全合规要求 存储数据明文风险：敏感数据未经过密码函数加密直接存储，数据库泄露后可能造成数据暴露 数据完整性校验不足：存储或传输过程中缺少密码校验机制，无法发现数据被非法修改 随机数可预测：随机数生成能力不足导致密钥、盐值、初始化向量等密码参数安全性降低 口令派生强度不足：直接使用低强度口令生成密钥，导致密钥容易被暴力破解 安全功能：\n加密函数：支持 AES、SM4 等对称密码算法，实现数据加密保护 解密函数：支持密文恢复明文，用于授权场景下的数据访问 哈希函数：支持 SHA256、SM3 等密码杂凑算法，实现数据摘要和完整性校验 密钥派生函数：支持 PBKDF2 等算法，将用户口令安全派生为密码密钥 随机数函数：提供安全随机数生成能力，用于密钥、盐值、初始化向量等密码参数生成 国密 + 国际双算法体系：同时支持 SM 系列国密算法和国际通用密码算法 防御效果（与安全威胁一一对应）：\n弱密码算法风险：提供 AES、SM4、SHA256、SM3 等安全密码算法，避免使用已淘汰弱算法保护敏感数据 密码算法不合规：支持国密 SM 系列和国际标准密码算法，满足不同安全合规场景需求 存储数据明文风险：通过加密函数对敏感数据进行加密后存储，数据库泄露后无法直接获取明文数据 数据完整性校验不足：通过哈希函数生成数据摘要，检测数据是否发生非法修改 随机数可预测：通过安全随机数函数生成高质量随机值，提高密钥、盐值及初始化向量安全性 口令派生强度不足：通过 PBKDF2 等密钥派生算法增加口令破解成本，提高派生密钥安全性 其他效果：\n性能：密码函数作为数据库内置能力提供，减少外部密码服务调用开销 易用性：支持 SQL 直接调用密码函数，无需额外部署密码组件 可扩展性：同时支持国际密码算法和国密算法，适配不同安全应用场景 使用流程：\n-- 1. 对称加密：敏感数据加密后存储（对应：存储数据明文风险、弱密码算法） SELECT gs_encrypt(\u0026#39;data\u0026#39;, \u0026#39;1\u0026#39;, \u0026#39;SM4\u0026#39;); -- 国密 SM4 SELECT gs_decrypt(gs_encrypt(\u0026#39;data\u0026#39;, \u0026#39;1\u0026#39;, \u0026#39;SM4\u0026#39;), \u0026#39;1\u0026#39;, \u0026#39;SM4\u0026#39;); -- 解密还原 SELECT gs_encrypt(\u0026#39;data\u0026#39;, \u0026#39;1\u0026#39;, \u0026#39;AES128\u0026#39;); -- 国际 AES128 -- 2. 哈希：数据摘要与完整性校验（对应：数据完整性校验不足、弱密码算法） SELECT gs_hash(\u0026#39;data\u0026#39;, \u0026#39;sm3\u0026#39;); -- 国密 SM3 SELECT gs_hash(\u0026#39;data\u0026#39;, \u0026#39;sha256\u0026#39;); -- 国际 SHA256 -- 3. 安全随机数：生成密钥、盐值（对应：随机数可预测） SELECT gen_random_uuid(); -- 4. 口令派生：认证与口令存储内部基于 PBKDF2 派生，避免低强度口令直接生成密钥（对应：口令派生强度不足） 安全威胁：\n磁盘窃取：物理存储介质、虚拟磁盘文件被非法获取，导致数据库数据泄露 数据文件泄露：操作系统用户、存储管理员直接访问数据库文件获取明文数据 存储残留泄露：WAL、临时文件、备份文件等持久化内容包含敏感明文信息 备份介质丢失：脱机备份文件被带离安全环境后，数据失去保护 存储层数据篡改：攻击者直接修改数据库底层文件，影响数据完整性 安全功能：\n全量存储加密：支持对表数据、索引、日志、临时文件等存储内容自动加解密，对业务应用透明 密钥分层管理：支持根密钥、主密钥、数据加密密钥多级密钥体系，实现密钥隔离管理 外部密钥管理：支持通过密码卡/HSM 等外部密钥设备保护根密钥 密钥轮转机制：支持密钥周期性更新，降低长期密钥泄露风险 透明访问控制：数据库正常运行过程中自动完成加解密，应用无需感知加密过程 防御效果（与安全威胁一一对应）：\n磁盘窃取：全量存储加密，数据库文件以密文形式保存，非法获取存储介质无法直接读取数据 数据文件泄露：存储层自动加密，操作系统用户或存储管理员仅能获取密文数据 存储残留泄露：对 WAL、临时文件、备份文件等敏感存储内容进行加密保护，避免残留数据泄露 备份介质丢失：备份数据以密文形式保存，介质丢失后无密钥无法恢复明文 存储层数据篡改：通过密文完整性校验机制检测非法修改，防止底层文件被无感篡改 其他效果：\n性能：支持硬件密码设备加速密码运算，降低透明加密对数据库读写性能影响 易用性：创建加密存储空间后，业务 SQL 无需修改，数据库自动完成加解密 安全性：数据库文件、备份文件与日志文件均受到统一加密保护 使用流程：\n-- 0. 配置密码卡环境变量（写入 ~/.bashrc 后 source 生效） -- export CRYPTDEV_TYPE=gdaccard CRYPTDEV_LIBPATH=/opt/card/lib CRYPTDEV_KEY=master_key -- 1. 开启透明加密（POSTMASTER 参数，需重启）（对应：磁盘窃取、存储残留泄露） ALTER SYSTEM SET enable_tde = on; -- vb_ctl restart -D $PGDATA -- 2. 创建加密表，数据自动加解密（对应：数据文件泄露、备份介质丢失） CREATE TABLE t1 ( c1 INT, c2 TEXT ) WITH (enable_tde = on, dek_info = 1); -- dek_info 指定密钥索引 -- 3. 正常读写，对应用透明 INSERT INTO t1 VALUES (1, \u0026#39;v1\u0026#39;); CHECKPOINT; -- 触发落盘 -- 4. 验证：物理文件为密文 SELECT pg_relation_filepath(\u0026#39;t1\u0026#39;); -- hexdump -C $PGDATA/base/\u0026lt;...\u0026gt;/\u0026lt;file\u0026gt; → 密文，无可读明文 3.10 数据防篡改 安全威胁：\n业务数据非法修改：攻击者直接修改业务数据，伪造交易记录或历史状态 历史记录删除：删除历史变更记录，破坏数据演变过程的完整性 历史记录伪造：非法插入虚假历史记录，制造错误业务轨迹 操作行为抵赖：用户否认执行过的数据修改操作，无法证明原始变更过程 审计证据破坏：篡改数据变更记录，影响安全审计和责任追踪 安全功能：\n防篡改数据表：支持创建防篡改表，对业务数据变更自动生成历史记录 历史版本记录：每次 INSERT、UPDATE、DELETE 操作自动记录变更前后状态 哈希完整性校验：基于数据摘要生成完整性校验信息，检测历史记录非法修改 追加式历史存储：历史记录仅支持追加，不允许用户直接修改或删除 全局事件链管理：通过全局事件记录表关联多个数据变更事件，形成完整追溯链 防御效果（与安全威胁一一对应）：\n业务数据非法修改：防篡改数据表 + 哈希完整性校验，数据修改过程自动生成历史记录，非法修改可被检测 历史记录删除：追加式历史存储，历史记录禁止直接删除，删除行为会破坏完整性校验链 历史记录伪造：历史版本记录 + 哈希校验，伪造记录无法通过完整性验证 操作行为抵赖：历史记录保存用户、时间、操作类型等信息，支持对数据变更行为进行追溯 审计证据破坏：全局事件链管理，数据变更记录形成关联链路，提高审计证据可信度 其他效果：\n性能：哈希摘要在数据变更阶段同步生成，额外计算开销可控 易用性：通过数据库表属性开启防篡改能力，业务 SQL 无需额外改造 可追溯性：历史记录自动维护，无需额外 ETL 或外部审计系统 使用流程：\n-- 1. 创建防篡改模式（账本 Schema），其下行存表自动具备防篡改属性（对应：业务数据非法修改） CREATE SCHEMA s1 WITH BLOCKCHAIN; -- 2. 建表，系统自动追加 hash 列并登记历史表（对应：历史记录伪造） CREATE TABLE s1.t1 (c1 INT, c2 TEXT, c3 NUMERIC); -- 3. 正常 DML，操作记入历史表与全局区块表（对应：操作行为抵赖） INSERT INTO s1.t1 VALUES (1, \u0026#39;v1\u0026#39;, 5000.00); UPDATE s1.t1 SET c3 = 5500.00 WHERE c1 = 1; -- 4. 校验数据一致性（对应：历史记录删除、历史记录伪造） SELECT pg_catalog.ledger_hist_check(\u0026#39;s1\u0026#39;, \u0026#39;t1\u0026#39;); -- t 完整 / f 检测到篡改 SELECT pg_catalog.ledger_gchain_check(\u0026#39;s1\u0026#39;, \u0026#39;t1\u0026#39;); -- 校验全局区块表 -- 5. 审计管理员查看历史记录（历史表只追加，不可改；对应：审计证据破坏） -- SELECT * FROM blockchain.s1_t1_hist; -- SELECT * FROM gs_global_chain; 3.11 动态脱敏 安全威胁：\n敏感信息泄露：身份证号、手机号、银行卡号等敏感字段查询时直接返回明文 权限范围外信息暴露：具有数据查询权限的用户查看超出业务职责范围的敏感信息 查询输出泄露：查询结果、数据导出等输出渠道包含敏感明文，导致二次传播风险 应用场景差异化需求不足：不同角色、不同业务场景无法按照安全要求展示不同数据内容 安全功能：\n细粒度脱敏策略：支持按照用户、角色、数据库对象、字段等维度配置脱敏规则 多种脱敏算法：支持遮蔽、替换、哈希等脱敏方式，满足不同敏感数据保护需求 实时动态脱敏：查询结果返回阶段实时执行脱敏处理，不改变数据库中原始数据 角色差异化展示：根据访问主体身份动态返回不同数据视图 访问路径防绕过：支持 SQL 查询、视图访问、数据导出等数据库访问路径统一执行脱敏策略 防御效果（与安全威胁一一对应）：\n敏感信息泄露：细粒度脱敏策略 + 脱敏算法，根据策略自动隐藏敏感字段内容，避免明文暴露 权限范围外信息暴露：角色差异化展示，根据访问用户身份返回对应脱敏结果，降低敏感数据泄露风险 查询输出泄露：访问路径防绕过，查询和导出等数据库输出场景统一返回脱敏数据 应用场景差异化需求不足：动态脱敏策略支持不同角色采用不同展示规则，满足多业务场景数据共享需求 其他效果：\n性能：脱敏处理在查询结果返回阶段完成，对数据存储和查询执行影响较小 易用性：通过策略配置实现动态生效，无需修改应用代码 安全性：敏感数据保持原始存储状态，仅在展示阶段进行保护 使用流程：\n-- 1. 为敏感列定义资源标签（对应：敏感信息泄露） CREATE RESOURCE LABEL rl1 ADD COLUMN(u1.t1.c2); -- 2. 创建脱敏策略，绑定业务角色 r1（对应：权限范围外信息暴露、角色差异化展示） CREATE MASKING POLICY mp1 creditcardmasking ON LABEL(rl1) FILTER ON ROLES(r1); -- 3. 同一 SQL，不同身份返回不同结果 -- 管理员（不在 FILTER 覆盖范围）查询： SELECT c1, c2 FROM t1; -- 返回：1 | 13812345678 -- 业务角色 r1（被策略覆盖）查询： SELECT c1, c2 FROM t1; -- 返回：1 | 138****5678 -- 4. 访问路径统一脱敏，导出同样脱敏（对应：查询输出泄露、防绕过） -- COPY (SELECT c2 FROM t1) TO \u0026#39;/tmp/out.csv\u0026#39;; → 导出内容仍为脱敏值 3.12 密钥管理 安全威胁：\n密钥泄露：根密钥、主密钥或数据密钥泄露导致加密保护失效 密钥明文存储：密钥以明文形式保存在配置文件或磁盘中，被非法获取 默认密钥风险：产品内置固定密钥或交付过程中的密钥管理不当导致密钥泄露 密钥生命周期失控：密钥长期不更新、不轮换或无法安全销毁，增加泄露风险 密钥集中管理不足：多个系统独立管理密钥，导致密钥分散、权限失控和审计困难 安全功能：\n外部密钥管理服务对接：支持通过 PKCS#11 等接口对接企业级 KMS/HSM，实现密钥统一管理 硬件密钥保护：支持密码卡等硬件安全设备保存根密钥，提高密钥抗提取能力 密钥不落盘：数据库不保存用户密钥明文，通过密钥标识、索引等方式调用外部密钥服务 密钥生命周期管理：支持密钥生成、启用、停用、轮换、销毁等全生命周期管理 密钥分层管理：支持根密钥、密钥加密密钥、数据密钥多级密钥体系，降低单密钥泄露影响范围 国密密码体系支持：支持 SM2/SM3/SM4 等国密算法相关密钥管理 防御效果（与安全威胁一一对应）：\n密钥泄露：硬件密钥保护 + 外部密钥管理服务，密钥与业务数据分离，服务器被攻击时无法直接获取密钥 密钥明文存储：密钥不落盘，数据库本地仅保存密钥引用信息，避免配置文件或数据目录泄露密钥 默认密钥风险：外部密钥管理服务，使用企业自主管理密钥，避免产品默认密钥或固定密钥风险 密钥生命周期失控：密钥生命周期管理，支持定期轮换和安全销毁，降低长期使用风险 密钥集中管理不足：统一密钥管理接口，实现多业务场景下密钥集中管理、权限控制和审计追踪 其他效果：\n安全性：密钥独立于业务数据管理，降低数据泄露后密钥同时暴露风险 可扩展性：支持企业级 KMS/HSM 接入，满足不同部署环境下密钥管理要求 易用性：数据库通过密钥标识自动调用密钥服务，业务无需感知密钥管理过程 使用流程：\n-- 0. 配置密码卡环境（写入 ~/.bashrc 后 source 生效） -- export CRYPTDEV_TYPE=gdaccard CRYPTDEV_LIBPATH=/opt/card/lib -- 1. 开启审计，密钥管理函数执行即产生审计记录 ALTER SYSTEM SET enable_audit = on; -- 2. 在密码卡内生成/导出/备份/销毁密钥（对应：密钥泄露、密钥生命周期失控） SELECT cryptocard_generate_key(256, 1, \u0026#39;UEK_SM2\u0026#39;, \u0026#39;Aa123456\u0026#39;); -- 生成密钥，存于卡内 SELECT cryptocard_export_key(1, \u0026#39;UEK_SM2\u0026#39;); -- 导出密钥信息 SELECT cryptocard_backup_key(\u0026#39;bk1.dat\u0026#39;, \u0026#39;Aa123456\u0026#39;); -- 备份 SELECT cryptocard_delete_key(1, \u0026#39;USER_KEK\u0026#39;); -- 销毁 -- 3. 验证：密钥存于密码卡，数据库目录无密钥明文（对应：密钥明文存储、默认密钥风险） -- grep -r \u0026#34;UEK_SM2\u0026#34; $PGDATA → 无密钥明文 3.13 资源安全 安全威胁：\n资源耗尽攻击：攻击者通过大量连接、复杂查询等方式消耗数据库 CPU、内存和连接资源，导致服务不可用 恶意 SQL 长时间占用：用户提交大查询、全表扫描或长事务，占用系统资源影响其他业务 单用户资源独占：单个用户大量创建连接或执行高消耗任务，影响其他用户正常访问 空间资源耗尽：数据持续增长导致磁盘空间不足，影响数据库正常运行 异常会话长期占用：空闲连接、异常事务长期占用数据库资源，降低系统可用性 安全功能：\n连接资源控制：限制数据库最大连接数以及单用户最大连接数量 用户资源配额：支持按照用户设置连接、计算等资源使用限制，避免单用户占用全部资源 SQL 执行控制：支持查询超时、事务超时等机制，限制长时间运行任务 空间资源监控：支持数据库、表空间空间使用阈值告警，提前发现资源风险 资源参数配置：支持通过参数配置资源限制策略，适配不同业务场景 防御效果（与安全威胁一一对应）：\n资源耗尽攻击：连接资源控制 + 用户资源配额，限制异常连接数量，避免实例资源被耗尽 恶意 SQL 长时间占用：SQL 执行控制，限制超长查询和异常事务，降低资源长期占用风险 单用户资源独占：用户资源配额，限制单用户连接和资源使用范围，保障多用户公平访问 空间资源耗尽：空间资源监控，通过阈值告警及时发现空间增长风险，避免业务中断 异常会话长期占用：连接控制 + SQL 执行控制，限制异常会话持续占用系统资源 其他效果：\n性能：资源限制在连接建立和任务调度阶段执行，对正常业务性能影响较小 可扩展性：支持多用户、多业务场景下资源隔离，避免单一业务影响整体数据库服务 易用性：通过参数和角色级配置实现资源策略管理，无需修改业务代码 使用流程：\n-- 1. 限制实例最大连接数（POSTMASTER 参数，需重启）（对应：资源耗尽攻击） ALTER SYSTEM SET max_connections = 500; -- vb_ctl restart -D $PGDATA -- 2. 限制单用户连接配额（对应：单用户资源独占） ALTER ROLE u1 CONNECTION LIMIT 50; -- 3. 限制单语句执行时长，防长事务拖垮实例（对应：恶意 SQL 长时间占用、异常会话长期占用） ALTER SYSTEM SET statement_timeout = 60000; -- 单语句最长 60 秒 SELECT pg_reload_conf(); -- 4. 监控连接与空间使用（对应：空间资源耗尽） SELECT usename, count(*) FROM pg_stat_activity GROUP BY usename; -- 各用户连接数 SELECT pg_size_pretty(pg_database_size(\u0026#39;vexdb\u0026#39;)); -- 数据库空间占用 -- 5. 验证：u1 超过 50 连接被拒 -- FATAL: too many connections for role \u0026#34;u1\u0026#34; 4、未来安全能力规划 VexDB 将持续完善数据库安全体系，面向云环境、多租户场景和更高等级安全需求，规划建设以下安全能力。\n4.1 机密计算 面向不可信基础设施环境，提供数据使用过程中的安全保护能力。\n支持在可信执行环境中处理敏感数据； 降低数据库运行环境对明文数据的可见性； 扩展密态查询能力，支持更多 SQL 运算场景； 优化密态计算性能，提升业务适用范围。 4.2 入侵检测与安全告警 建设数据库运行过程中的主动检测能力。\n基于访问行为、审计记录识别异常操作； 检测暴力破解、异常登录、异常查询、批量数据访问等行为； 支持安全事件告警通知； 支持与安全运营平台联动。 4.3 数据安全治理 完善敏感数据识别和保护能力。\n自动发现数据库中的敏感字段； 支持数据分类分级管理； 根据数据等级关联访问控制、脱敏和审计策略； 提供敏感数据分布和使用情况分析。 4.4 安全运维增强 提升数据库安全管理自动化能力。\n支持安全配置检查； 检测弱口令、风险权限和不安全配置； 提供安全基线检查能力； 支持安全策略统一管理。 4.5 密钥管理增强 完善密钥生命周期管理能力。\n支持更多企业级 KMS/HSM 接入方式； 支持密钥自动轮换； 支持密钥使用审计； 提升多实例、多集群场景下的密钥管理能力。 4.6 数据保护增强 扩展数据保护范围。\n支持更多存储对象加密，包括备份文件、归档日志等； 增强主备、容灾场景下的数据保护能力； 扩展数据脱敏算法和应用场景； 提升数据共享过程中的安全控制能力。 4.7 安全分析与运营 提升安全事件发现和处置能力。\n支持多维度安全事件分析； 支持操作行为关联分析； 支持安全风险统计和报告生成； 缩短安全事件定位和处置时间。 附1　安全机制统计表 本产品安全机制覆盖网络访问、身份认证、权限控制、数据保护、密码管理、安全审计和资源控制等方面。主要安全机制及实现来源如下。\n序号 安全机制 简要说明 是否自研 1 网络防火墙 提供基于主机地址、用户角色、目标数据库的连接访问控制 基于开源增强 2 身份认证 提供用户管理、口令策略、认证协议、失败限制、多因素认证等身份保护能力 基于开源增强 3 安全传输 提供 TLS/TLCP 加密通信、双向认证和安全算法配置能力 基于开源增强 4 访问控制 提供 RBAC、自主访问控制、三权分立、强制访问控制和行级访问控制能力 部分自研，部分基于开源增强 5 数据库审计 提供细粒度审计、关键操作记录、审计查询和审计数据保护能力 基于开源增强 6 驱动加密 提供客户端加密、列级加密、密文存储、密文等值查询和完整性保护能力 基于开源增强 7 机密计算 提供密态查询和密态计算能力，降低运行环境对明文数据的访问 规划建设 8 密码函数 提供加密、哈希、密钥派生、随机数等密码基础能力，支持国密算法 基于开源增强 9 透明加密 提供数据库存储加密、日志加密、多级密钥管理和密钥轮换能力 基于开源增强 10 数据防篡改 提供数据变更记录、历史追踪、完整性校验和防删除保护能力 基于开源增强 11 动态脱敏 提供敏感字段动态脱敏、角色差异化展示和访问路径保护能力 基于开源增强 12 密钥管理 提供 KMS/HSM 对接、密钥生命周期管理、硬件保护和密钥不落盘能力 基于开源增强 13 资源安全 提供连接控制、资源限制、空间监控和异常资源占用防护能力 基于开源增强 附2　证明材料（商密证书等） 送测产品已取得或正在办理的资质证书如下：\n商用密码模块认证 CC EAL 4+证书 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/compliance/security-self-assessment/","summary":"\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e版本号\u003c/th\u003e\n          \u003cth\u003e日期\u003c/th\u003e\n          \u003cth\u003e修改说明\u003c/th\u003e\n          \u003cth\u003e编制人\u003c/th\u003e\n          \u003cth\u003e审核人\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e1.0\u003c/td\u003e\n          \u003ctd\u003e2026.07.24\u003c/td\u003e\n          \u003ctd\u003e完成初稿\u003c/td\u003e\n          \u003ctd\u003e沈坤\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003chr\u003e\n\u003ch2 id=\"1核心资产\"\u003e1、核心资产\u003c/h2\u003e\n\u003cp\u003eVexDB 的核心资产分为七类，覆盖数据、结构、访问、运行、审计、内存和密码资源，是数据库安全保护的主要对象。\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e核心资产\u003c/th\u003e\n          \u003cth\u003e资产内容\u003c/th\u003e\n          \u003cth\u003e资产价值\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e数据资产\u003c/td\u003e\n          \u003ctd\u003e业务数据、用户数据、交易数据等存储内容\u003c/td\u003e\n          \u003ctd\u003e数据库核心资源。泄露、篡改或丢失影响业务安全\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e数据库结构资产\u003c/td\u003e\n          \u003ctd\u003e模式、表、字段、索引、视图、存储过程、函数、约束等\u003c/td\u003e\n          \u003ctd\u003e描述数据组织和业务逻辑。非法修改影响业务正确性\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e数据库管理资产\u003c/td\u003e\n          \u003ctd\u003e用户、角色、权限、配置参数、安全策略等\u003c/td\u003e\n          \u003ctd\u003e控制访问范围和运行行为。错误配置影响整体安全\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e数据库运行资产\u003c/td\u003e\n          \u003ctd\u003e实例、进程、数据文件、日志文件及计算存储资源\u003c/td\u003e\n          \u003ctd\u003e支撑数据库服务运行。破坏导致服务不可用\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e数据库操作记录资产\u003c/td\u003e\n          \u003ctd\u003e访问日志、审计记录、运行日志、管理操作记录等\u003c/td\u003e\n          \u003ctd\u003e支撑安全分析、事件追踪和责任认定\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e数据库内存资产\u003c/td\u003e\n          \u003ctd\u003e内存中的业务数据、缓存、会话信息和认证凭证\u003c/td\u003e\n          \u003ctd\u003e运行过程中的敏感信息。泄露可能导致数据或凭证暴露\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e密码与密钥资产\u003c/td\u003e\n          \u003ctd\u003e加密密钥、口令摘要、认证凭证等密码资源\u003c/td\u003e\n          \u003ctd\u003e支撑身份认证和数据保护。泄露可能导致安全机制失效\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003e核心资产的机密性、完整性和可用性，决定数据库安全运行和业务连续性。\u003c/p\u003e\n\u003chr\u003e\n\u003ch2 id=\"2安全风险和应对措施\"\u003e2、安全风险和应对措施\u003c/h2\u003e\n\u003cp\u003eVexDB 面临外部攻击、内部误操作、权限滥用和运行环境异常等风险，可能导致非法访问、数据泄露、数据篡改、身份冒用和服务不可用。主要风险与应对措施如下。\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e安全风险\u003c/th\u003e\n          \u003cth\u003e风险描述\u003c/th\u003e\n          \u003cth\u003e应对措施\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003e非法访问风险\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003e非授权主机连接数据库，获取非法访问入口\u003c/td\u003e\n          \u003ctd\u003e网络防火墙\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003e身份认证风险\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003e弱口令、凭证泄露或认证缺陷导致身份冒用\u003c/td\u003e\n          \u003ctd\u003e身份认证\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003e通信安全风险\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003e网络传输被窃听、伪造、重放或篡改\u003c/td\u003e\n          \u003ctd\u003e安全传输\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003e权限控制风险\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003e权限配置不当或权限提升导致越权访问\u003c/td\u003e\n          \u003ctd\u003e访问控制\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003e数据安全风险\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003e数据存储、传输、处理过程中发生泄露或篡改\u003c/td\u003e\n          \u003ctd\u003e透明加密、驱动加密、机密计算、动态脱敏、数据防篡改\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003e密钥安全风险\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003e密钥泄露、丢失或生命周期管理不足导致保护失效\u003c/td\u003e\n          \u003ctd\u003e密钥管理\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003e操作追溯风险\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003e数据访问和管理操作缺少记录，无法有效追责\u003c/td\u003e\n          \u003ctd\u003e数据库审计、数据防篡改\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003e服务可用性风险\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003e恶意请求或资源异常消耗导致性能下降或服务中断\u003c/td\u003e\n          \u003ctd\u003e资源安全\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e\u003cstrong\u003e运行环境风险\u003c/strong\u003e\u003c/td\u003e\n          \u003ctd\u003e不可信环境或异常运行环境导致数据暴露风险\u003c/td\u003e\n          \u003ctd\u003e驱动加密、机密计算、密钥管理\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"vexdb-通过网络防护身份认证访问控制数据保护密码保护安全审计和资源管理等能力降低非法访问数据泄露数据篡改和服务不可用等安全风险\"\u003eVexDB 通过网络防护、身份认证、访问控制、数据保护、密码保护、安全审计和资源管理等能力，降低非法访问、数据泄露、数据篡改和服务不可用等安全风险。\u003c/h2\u003e\n\u003ch2 id=\"3安全机制\"\u003e3、安全机制\u003c/h2\u003e\n\u003cp\u003eVexDB 从接入、传输、访问、存储、计算、合规六个维度构建防御模型，各安全机制相互独立又相互配合。\u003c/p\u003e","title":"VexDB 数据库安全自评价报告"},{"content":"CREATE SCHEMA s1 WITH BLOCKCHAIN; CREATE TABLE s1.t1(c1 INT, c2 TEXT); \\d s1.t1 \\d blockchain.s1_t1_hist INSERT INTO s1.t1 VALUES(1, \u0026#39;aa\u0026#39;), (3, \u0026#39;bb\u0026#39;), (7, \u0026#39;cc\u0026#39;), (10, \u0026#39;dd\u0026#39;); SELECT *,hash FROM s1.t1; SELECT * FROM blockchain.s1_t1_hist; # hahs_ins,hash_del,pre_hash SELECT * FROM gs_global_chain; # relnsp,relname,relhash,globalhash,txcommand SELECT ledger_hist_check(\u0026#39;s1\u0026#39;, \u0026#39;t1\u0026#39;); SELECT ledger_gchain_check(\u0026#39;s1\u0026#39;, \u0026#39;t1\u0026#39;); 分布式 CREATE SCHEMA s1 WITH BLOCKCHAIN; CREATE TABLE s1.t1(c1 INT, c2 TEXT); SELECT create_distributed_table(\u0026#39;s1.t1\u0026#39;, \u0026#39;c1\u0026#39;); INSERT INTO s1.t1 VALUES(1, \u0026#39;aa\u0026#39;), (2, \u0026#39;bb\u0026#39;), (3, \u0026#39;cc\u0026#39;), (7, \u0026#39;dd\u0026#39;), (10, \u0026#39;ee\u0026#39;); SELECT *,hash FROM s1.t1; SELECT * FROM blockchain.s1_t1_hist; -- hahs_ins,hash_del,pre_hash, 其中，pre_hash没用上，无作用 SELECT * FROM gs_global_chain; -- relnsp,relname,relhash,globalhash,txcommand SELECT * FROM ledger_hist(\u0026#39;s1\u0026#39;, \u0026#39;t1\u0026#39;); SELECT * FROM ledger_gchain(); SELECT ledger_hist_check(\u0026#39;s1\u0026#39;, \u0026#39;t1\u0026#39;); SELECT ledger_hist_archive(\u0026#39;s1\u0026#39;, \u0026#39;t1\u0026#39;); SELECT ledger_hist_repair(\u0026#39;s1\u0026#39;, \u0026#39;t1\u0026#39;); SELECT ledger_gchain_check(\u0026#39;s1\u0026#39;, \u0026#39;t1\u0026#39;); SELECT ledger_gchain_archive(); SELECT ledger_gchain_repair(\u0026#39;s1\u0026#39;, \u0026#39;t1\u0026#39;); 集中式 CREATE SCHEMA s1 WITH BLOCKCHAIN; CREATE TABLE s1.t1(c1 INT, c2 TEXT); INSERT INTO s1.t1 VALUES(1, \u0026#39;aa\u0026#39;), (2, \u0026#39;bb\u0026#39;), (3, \u0026#39;cc\u0026#39;), (7, \u0026#39;dd\u0026#39;), (10, \u0026#39;ee\u0026#39;); SELECT *,hash FROM s1.t1; SELECT * FROM blockchain.s1_t1_hist; SELECT * FROM gs_global_chain; SELECT ledger_hist_check(\u0026#39;s1\u0026#39;, \u0026#39;t1\u0026#39;); SELECT ledger_hist_archive(\u0026#39;s1\u0026#39;, \u0026#39;t1\u0026#39;); SELECT ledger_hist_repair(\u0026#39;s1\u0026#39;, \u0026#39;t1\u0026#39;); SELECT ledger_gchain_check(\u0026#39;s1\u0026#39;, \u0026#39;t1\u0026#39;); SELECT ledger_gchain_archive(); SELECT ledger_gchain_repair(\u0026#39;s1\u0026#39;, \u0026#39;t1\u0026#39;); -- 下面2个函数，不用适配，别动代码，告诉我当前表现 -- SELECT * FROM ledger_hist(\u0026#39;s1\u0026#39;, \u0026#39;t1\u0026#39;); -- SELECT * FROM ledger_gchain(); CREATE SCHEMA s1 WITH BLOCKCHAIN;\nCREATE TABLE s1.t1(c1 INT, c2 TEXT);\n– 非分布式表：历史表、全局历史表\nSELECT * FROM blockchain.s1_t1_hist;\nSELECT * FROM gs_global_chain;\n– 分布式表：（历史信息存储在dn，只能用函数去dn收集）\nSELECT * FROM ledger_hist(‘s1’, ‘t1’);\nSELECT * FROM ledger_gchain();\nexec_simple_query(INSERT INTO s1.t1 VALUES(1, \u0026#39;aa\u0026#39;), (3, \u0026#39;bb\u0026#39;)) pg_parse_query pg_analyze_and_rewrite pg_plan_query PortalStart ExecutorStart .. PortalRun ExecutorRun .. CREATE SCHEMA s1 WITH BLOCKCHAIN; CREATE TABLE s1.t1(c1 INT, c2 TEXT); \\d s1.t1 \\d blockchain.s1_t1_hist -- 自动生成，存储tuple hash值 exec_simple_query(INSERT INTO s1.t1 VALUES(1, \u0026#39;aa\u0026#39;), (3, \u0026#39;bb\u0026#39;), (7, \u0026#39;cc\u0026#39;), (10, \u0026#39;dd\u0026#39;)) pg_parse_query pg_analyze_and_rewrite pg_plan_query PortalStart PortalRun PortalRunMulti ProcessQuery ExecutorStart standard_ExecutorStart InitPlan ExecInitNode ExecInitModifyTable ExecutorRun standard_ExecutorRun ExecutePlan ExecProcNode ExecModifyTable ExecInsert tuple = tableam_tslot_get_tuple_from_slot tuple = set_user_tuple_hash # 新增hash列 gen_user_tuple_hash hash_combine_tuple_data pg_md5_binary tableam_tuple_insert(\u0026#39;s1.t1\u0026#39;) reshash = hist_table_record_insert(\u0026#39;blockchain.s1_t1_hist\u0026#39; tuple) # 写 s1_t1_hist hist_table_record_internal fill_hist_block gen_hist_tuple_hash simple_heap_insert(\u0026#39;blockchain.s1_t1_hist\u0026#39;) lappend(estate-\u0026gt;es_modifiedRowHash, reshash) # 保留 gs_blocal_chain 数据 ExecutorFinish ExecutorEnd ledger_ExecutorEnd hashsum = hash_combiner(estate-\u0026gt;es_modifiedRowHash) # 计算1个或多个tuple的hash ledger_gchain_append(hashsum) # 写 gs_blocal_chain set_gchain_comb_string gen_global_hash # simple_heap_insert standard_ExecutorEnd ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/blockchain-tamper-proof/","summary":"\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSCHEMA\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eBLOCKCHAIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eblockchain\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003es1_t1_hist\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aa\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;bb\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e7\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;cc\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;dd\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ehash\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eblockchain\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003es1_t1_hist\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e#\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ehahs_ins\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ehash_del\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003epre_hash\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egs_global_chain\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e#\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erelnsp\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003erelname\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003erelhash\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eglobalhash\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003etxcommand\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eledger_hist_check\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;s1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eledger_gchain_check\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;s1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"分布式\"\u003e分布式\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSCHEMA\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eBLOCKCHAIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecreate_distributed_table\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;s1.t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;c1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aa\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;bb\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;cc\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e7\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;dd\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;ee\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ehash\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eblockchain\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003es1_t1_hist\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- hahs_ins,hash_del,pre_hash, 其中，pre_hash没用上，无作用\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egs_global_chain\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- relnsp,relname,relhash,globalhash,txcommand\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eledger_hist\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;s1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eledger_gchain\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eledger_hist_check\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;s1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eledger_hist_archive\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;s1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eledger_hist_repair\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;s1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eledger_gchain_check\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;s1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eledger_gchain_archive\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eledger_gchain_repair\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;s1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"集中式\"\u003e集中式\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSCHEMA\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eBLOCKCHAIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aa\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;bb\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;cc\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e7\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;dd\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;ee\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ehash\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eblockchain\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003es1_t1_hist\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egs_global_chain\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eledger_hist_check\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;s1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eledger_hist_archive\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;s1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eledger_hist_repair\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;s1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eledger_gchain_check\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;s1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eledger_gchain_archive\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eledger_gchain_repair\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;s1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 下面2个函数，不用适配，别动代码，告诉我当前表现\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- SELECT * FROM ledger_hist(\u0026#39;s1\u0026#39;, \u0026#39;t1\u0026#39;);\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- SELECT * FROM ledger_gchain();\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eCREATE SCHEMA s1 WITH BLOCKCHAIN;\u003cbr\u003e\nCREATE TABLE s1.t1(c1 INT, c2 TEXT);\u003c/p\u003e","title":"数据库安全 防篡改"},{"content":"VSCode Claude Code 扩展配置 本文记录如何在 VSCode 中配置 Claude Code 扩展，接入第三方（海量/glm）模型服务，无需在本机维护环境变量，扩展启动时自动注入。\n配置位置 VSCode 用户级配置文件：\nWindows：%APPDATA%\\Code\\User\\settings.json\n（即 C:\\Users\\\u0026lt;用户名\u0026gt;\\AppData\\Roaming\\Code\\User\\settings.json） macOS：~/Library/Application Support/Code/User/settings.json Linux：~/.config/Code/User/settings.json 打开方式：VSCode 中按 Ctrl + , 打开设置 → 右上角「打开设置 (JSON)」图标，或直接 Ctrl + Shift + P 输入 Preferences: Open User Settings (JSON)。\n完整配置 将以下内容合并进 settings.json（注意 JSON 语法，最后一项末尾不要多逗号）：\n{ \u0026#34;claudeCode.environmentVariables\u0026#34;: [ { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_BASE_URL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;http://172.16.105.104:3000\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_AUTH_TOKEN\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;sk-hR1tQQloyPW0ax9b7404D51285Ae4737A118457535Fc33Ae\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;glm-5.2\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_DEFAULT_OPUS_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;glm-5.2\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_DEFAULT_SONNET_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;glm-5.2\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_DEFAULT_HAIKU_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;glm-5\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;CLAUDE_CODE_SUBAGENT_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;glm-5\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;CLAUDE_CODE_EFFORT_LEVEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;max\u0026#34; } ], \u0026#34;claudeCode.preferredLocation\u0026#34;: \u0026#34;panel\u0026#34; } 环境变量说明 变量名 作用 说明 ANTHROPIC_BASE_URL API 基础地址 指向第三方中转服务（兼容 Anthropic 协议）。海量外网网关示例：http://172.16.105.104:3000 ANTHROPIC_AUTH_TOKEN 鉴权令牌 中转服务下发的 sk-xxx，等价于官方的 API Key ANTHROPIC_MODEL 默认模型 主对话使用的模型 ANTHROPIC_DEFAULT_OPUS_MODEL Opus 档模型 覆盖官方 Opus 映射，通常设为最强模型 ANTHROPIC_DEFAULT_SONNET_MODEL Sonnet 档模型 覆盖官方 Sonnet 映射，日常主力 ANTHROPIC_DEFAULT_HAIKU_MODEL Haiku 档模型 覆盖官方 Haiku 映射，轻量快模型，用于补全/摘要 CLAUDE_CODE_SUBAGENT_MODEL 子 Agent 模型 Task/Explore 等子任务使用的模型，建议用快模型省钱 CLAUDE_CODE_EFFORT_LEVEL 推理强度 max 表示最高推理强度（思考最深），可选 low/medium/high/max 扩展项 claudeCode.preferredLocation：控制 Claude Code 面板的默认停靠位置，可选 panel（底部面板）或 editor（作为编辑器标签页）。\n配置步骤 安装扩展：在 VSCode 扩展市场搜索 Claude Code（Anthropic 官方）并安装。 打开 settings.json：按上面「配置位置」的方式打开用户设置 JSON。 粘贴配置：把上方「完整配置」中的两个键合并进 JSON。 重启扩展：保存后重新打开 VSCode，或 Ctrl + Shift + P → Developer: Reload Window，让环境变量生效。 验证：打开 Claude Code 面板，输入 /doctor 或 /model 确认当前指向的是 glm-5.2。 多环境切换 只需改 ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN 和一组模型名即可切换。常用组合：\n外网 · 海量网关 + GLM（当前默认） { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_BASE_URL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;http://172.16.105.104:3000\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_AUTH_TOKEN\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;sk-hR1tQQloyPW0ax9b7404D51285Ae4737A118457535Fc33Ae\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;glm-5.2\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_DEFAULT_OPUS_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;glm-5.2\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_DEFAULT_SONNET_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;glm-5.2\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_DEFAULT_HAIKU_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;glm-5\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;CLAUDE_CODE_SUBAGENT_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;glm-5\u0026#34; } 内网 · GLM { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_BASE_URL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;http://172.16.99.137:8081\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_AUTH_TOKEN\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;sk-hR1tQQloyPW0ax9b7404D51285Ae4737A118457535Fc33Ae\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;glm-5.2\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_DEFAULT_OPUS_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;glm-5.2\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_DEFAULT_SONNET_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;glm-5.2\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_DEFAULT_HAIKU_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;glm-5\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;CLAUDE_CODE_SUBAGENT_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;glm-5\u0026#34; } DeepSeek 官方（直连） { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_BASE_URL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;https://api.deepseek.com/anthropic\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_AUTH_TOKEN\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;sk-e435fe4629934fc892c226fc26d7ac92\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;deepseek-v4-pro[1m]\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_DEFAULT_OPUS_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;deepseek-v4-pro[1m]\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_DEFAULT_SONNET_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;deepseek-v4-pro[1m]\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;ANTHROPIC_DEFAULT_HAIKU_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;deepseek-v4-flash\u0026#34; }, { \u0026#34;name\u0026#34;: \u0026#34;CLAUDE_CODE_SUBAGENT_MODEL\u0026#34;, \u0026#34;value\u0026#34;: \u0026#34;deepseek-v4-flash\u0026#34; } 命令行环境（非 VSCode）下，等价配置请见 9-工具/claude.md，用 export 或 PowerShell $env: 的方式设置同名变量。\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/claude-code-vscode/","summary":"\u003ch1 id=\"vscode-claude-code-扩展配置\"\u003eVSCode Claude Code 扩展配置\u003c/h1\u003e\n\u003cp\u003e本文记录如何在 VSCode 中配置 Claude Code 扩展，接入第三方（海量/glm）模型服务，无需在本机维护环境变量，扩展启动时自动注入。\u003c/p\u003e\n\u003ch2 id=\"配置位置\"\u003e配置位置\u003c/h2\u003e\n\u003cp\u003eVSCode 用户级配置文件：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eWindows\u003c/strong\u003e：\u003ccode\u003e%APPDATA%\\Code\\User\\settings.json\u003c/code\u003e\u003cbr\u003e\n（即 \u003ccode\u003eC:\\Users\\\u0026lt;用户名\u0026gt;\\AppData\\Roaming\\Code\\User\\settings.json\u003c/code\u003e）\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003emacOS\u003c/strong\u003e：\u003ccode\u003e~/Library/Application Support/Code/User/settings.json\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eLinux\u003c/strong\u003e：\u003ccode\u003e~/.config/Code/User/settings.json\u003c/code\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e打开方式：VSCode 中按 \u003ccode\u003eCtrl + ,\u003c/code\u003e 打开设置 → 右上角「打开设置 (JSON)」图标，或直接 \u003ccode\u003eCtrl + Shift + P\u003c/code\u003e 输入 \u003ccode\u003ePreferences: Open User Settings (JSON)\u003c/code\u003e。\u003c/p\u003e\n\u003ch2 id=\"完整配置\"\u003e完整配置\u003c/h2\u003e\n\u003cp\u003e将以下内容合并进 \u003ccode\u003esettings.json\u003c/code\u003e（注意 JSON 语法，最后一项末尾不要多逗号）：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-json\" data-lang=\"json\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026#34;claudeCode.environmentVariables\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"p\"\u003e[\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;ANTHROPIC_BASE_URL\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;value\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;http://172.16.105.104:3000\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;ANTHROPIC_AUTH_TOKEN\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;value\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;sk-hR1tQQloyPW0ax9b7404D51285Ae4737A118457535Fc33Ae\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;ANTHROPIC_MODEL\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;value\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;glm-5.2\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;ANTHROPIC_DEFAULT_OPUS_MODEL\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;value\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;glm-5.2\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;ANTHROPIC_DEFAULT_SONNET_MODEL\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;value\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;glm-5.2\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;ANTHROPIC_DEFAULT_HAIKU_MODEL\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;value\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;glm-5\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;CLAUDE_CODE_SUBAGENT_MODEL\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;value\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;glm-5\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e},\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e{\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;name\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;CLAUDE_CODE_EFFORT_LEVEL\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nt\"\u003e\u0026#34;value\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;max\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e],\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nt\"\u003e\u0026#34;claudeCode.preferredLocation\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;panel\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"环境变量说明\"\u003e环境变量说明\u003c/h2\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth style=\"text-align: left\"\u003e变量名\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e作用\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e说明\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003eANTHROPIC_BASE_URL\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eAPI 基础地址\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e指向第三方中转服务（兼容 Anthropic 协议）。海量外网网关示例：\u003ccode\u003ehttp://172.16.105.104:3000\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003eANTHROPIC_AUTH_TOKEN\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e鉴权令牌\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e中转服务下发的 \u003ccode\u003esk-xxx\u003c/code\u003e，等价于官方的 API Key\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003eANTHROPIC_MODEL\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e默认模型\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e主对话使用的模型\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003eANTHROPIC_DEFAULT_OPUS_MODEL\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eOpus 档模型\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e覆盖官方 Opus 映射，通常设为最强模型\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003eANTHROPIC_DEFAULT_SONNET_MODEL\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eSonnet 档模型\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e覆盖官方 Sonnet 映射，日常主力\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003eANTHROPIC_DEFAULT_HAIKU_MODEL\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eHaiku 档模型\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e覆盖官方 Haiku 映射，轻量快模型，用于补全/摘要\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003eCLAUDE_CODE_SUBAGENT_MODEL\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e子 Agent 模型\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eTask/Explore 等子任务使用的模型，建议用快模型省钱\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003eCLAUDE_CODE_EFFORT_LEVEL\u003c/code\u003e\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e推理强度\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e\u003ccode\u003emax\u003c/code\u003e 表示最高推理强度（思考最深），可选 \u003ccode\u003elow/medium/high/max\u003c/code\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cblockquote\u003e\n\u003cp\u003e扩展项 \u003ccode\u003eclaudeCode.preferredLocation\u003c/code\u003e：控制 Claude Code 面板的默认停靠位置，可选 \u003ccode\u003epanel\u003c/code\u003e（底部面板）或 \u003ccode\u003eeditor\u003c/code\u003e（作为编辑器标签页）。\u003c/p\u003e","title":"国测 claude"},{"content":"-- cn: 50000 -- dn1: 50005 -- dn2: 50010 vsql -d postgres -p 50000 -r SELECT * FROM PG_DIST_NODE; CREATE TABLE t1(c1 INT, c2 TEXT); SELECT create_distributed_table(\u0026#39;t1\u0026#39;, \u0026#39;c1\u0026#39;); -- 创建8个分片，dn1和dn2，每个dn有4个分片，即4个表，表名为 t1_$oid SELECT * FROM pg_dist_shard; -- min和max是hash之后的值 SELECT * FROM pg_dist_shard_placement; SELECT * FROM pg_dist_partition; INSERT INTO t1 VALUES(1, \u0026#39;aa\u0026#39;), (3, \u0026#39;bb\u0026#39;), (7, \u0026#39;cc\u0026#39;), (10, \u0026#39;dd\u0026#39;); vsql -d postgres -p 50005 -r SELECT oid,relname FROM pg_class WHERE relname like \u0026#39;%t1%\u0026#39;; vsql -d postgres -p 50010 -r SELECT oid,relname FROM pg_class WHERE relname like \u0026#39;%t1%\u0026#39;; # cn SELECT create_distributed_table(\u0026#39;t1\u0026#39;, \u0026#39;c1\u0026#39;); # --\u0026gt; shard 1 (dn1) SELECT worker_apply_shard_ddl_command (12042, \u0026#39;CREATE TABLE public.t1 (c1 integer, c2 text) WITH (orientation=row, compression=no, fillfactor=80)\u0026#39;); # dn1 worker_apply_shard_ddl_command ddlnode = ParseTreeNode(sql) RelayEventExtendNames(ddlnode, sharid) # 在语法解析树中，把t1名称，修改为t1_$shardid ProcessUtilityParseTree SELECT worker_apply_shard_ddl_command (12042, \u0026#39;ALTER TABLE public.t1 OWNER TO shenkun\u0026#39;); # --\u0026gt; shard 2 (dn2) SELECT worker_apply_shard_ddl_command (12043, \u0026#39;CREATE TABLE public.t1 (c1 integer, c2 text) WITH (orientation=row, compression=no, fillfactor=80)\u0026#39;); SELECT worker_apply_shard_ddl_command (12043, \u0026#39;ALTER TABLE public.t1 OWNER TO shenkun\u0026#39;); # --\u0026gt; shared 3 (dn1) ... # --\u0026gt; 一共8个分片，每个分片2条SQL！ # cn INSERT INTO t1 VALUES(1,\u0026#39;aa\u0026#39;),(3,\u0026#39;bb\u0026#39;),(7,\u0026#39;cc\u0026#39;),(10,\u0026#39;dd\u0026#39;); exec_simple_query pg_parse_query pg_analyze_and_rewrite pg_plan_query [planner hook] distributed_planner CreateDistributedPlan CreateModifyPlan RouterInsertJob (deferredPruning=true) # 返回 CustomScan PortalStart ExecutorStart [DVecExecutorStart] DVecExecutorStart BeginCustomScan → DVecBeginScan DVecBeginModifyScan RegenerateTaskListForInsert BuildRoutesForInsert FindShardInterval ActiveShardPlacementList RebuildQueryStrings DeparseTaskQuery AppendShardIdToName # 生成改名后SQL PortalRun ExecutorRun [ExecutorRun_hook] DVecExecutorRun ExecCustomScan DVecExecScan AdaptiveExecutor RunDistributedExecution ... SendRemoteCommand StartRemoteTransactionBegin BeginTransactiionCommand # 生成：BEGIN ISOLATION LEVEL READ COMMITTED; AssignDistributedTransactionIdCommand # 生成：SELECT assign_distributed_transaction_id(0,20,\u0026#39;...\u0026#39;); SendRemoteCommand # 一次发送2条事务SQL SendRemoteCommand PQsendQuery # INTO t1_$shardid .. CoordinatedRemoteTransactionsPrepare .. SendRemoteCommand # 发送 REPARE TRANSACTION .. SendRemoteCommand # 发送 COMMIT PREPARED .. # --\u0026gt; shard 1 (dn1) BEGIN ISOLATION LEVEL READ COMMITTED; SELECT assign_distributed_transaction_id(0,20,\u0026#39;...\u0026#39;); INSERT INTO public.t1_12042 AS dvec_table_alias (c1, c2) VALUES (1,\u0026#39;aa\u0026#39;::text) REPARE TRANSACTION \u0026#39;dvecx_...\u0026#39;; COMMIT PREPARED \u0026#39;dvecx_...\u0026#39;; # 执行分布式事务 INSERT INTO public.t1_12042 AS dvec_table_alias (c1, c2) VALUES (1,\u0026#39;aa\u0026#39;::text) # --\u0026gt; shard 2 (dn2) INSERT INTO public.t1_12043 AS dvec_table_alias (c1, c2) VALUES (10,\u0026#39;dd\u0026#39;::text) # --\u0026gt; shared 3 (d1) ... # --\u0026gt; 一共8个分片，其中4个分片，各收到1条INSERT语句 # 多行在同一分片，INSERT语句合并 # cn SELECT * FROM t1 WHERE c1 \u0026gt; 10; exec_simple_query pg_parse_query pg_analyze_and_rewrite pg_plan_query [planner hook] distributed_planner CreateDistributedPlan GetRouterPlanType (一造 multi-shard fan-out(非 router 计划)) MultiLogicalPlanCreate (logical planner:建逻辑计划) CreatePhysicalDistributedPlan (physical planner) ├─ 为命中的每个分片建一个 Task(本表 8 个分片 → 8 个 Task) UpdateTaskQueryString DeparseTaskQuery deparse_shard_query AppendShardIdToName # t1 → t1_\u0026lt;shardId\u0026gt; # SELECT * + c1,c2 ; WHERE c1\u0026gt;10 → (c1 OPERATOR(pg_catalog.\u0026gt;) 10) # 包成 CustomScan 返回 PortalStart ExecutorStart [DVecExecutorStart] DVecExecutorStart BeginCustomScan → DVecBeginScan PortalRun ExecutorRun [ExecutorRun_hook] DVecExecutorRun ExecCustomScan DVecExecScan AdaptiveExecutor RunDistributedExecution AssignTasksToConnectionsOrWorkerPool # 8 个 Task 分给 DN1/DN2 的连接 ConnectionStateMachine StartRemoteTransactionBegin *发送: BEGIN + assign(每条 DN 连接首次用,只发一次) BeginTransactionCommand # 生成: BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED AssignDistributedTransactionIdCommand # 生成: SELECT assign_distributed_transaction_id(...) SendRemoteCommand → PQsendQuery *两条合并成一条发出 # 发送: SELECT c1,c2 FROM t1_\u0026lt;shardId\u0026gt; WHERE (c1\u0026gt;10) # DN1 上 4 条 (12042/12044/12046/12048), DN2 上 4 条 (COMMIT) RemoteTransactionCommit SendRemoteCommand → PQsendQuery # 只读 → 普通 COMMIT(无 PREPARE/COMMIT PREPARED,无 2PC) # COMMIT # --\u0026gt; shard 1 (dn1) SELECT c1, c2 FROM public.t1_12042 t1 WHERE (c2 OPERATOR(pg_catalog.\u0026gt;) \u0026#39;cc\u0026#39;::text) SELECT * FROM t1 WHERE c2 \u0026gt; \u0026#39;cc\u0026#39;; 密态： cn CREATE TABLE t1 (c1 ..) INSERT INTO t1 VALUES (..) SELECT c1,c2 FROM t1 WHERE .. dn CREATE TABLE t1_$shardid (c1 ..) INSERT INTO t1_$shardid VALUES (..) # values的值不变 SELECT c1,c2 FROM t1_$shardid WHERE .. # WHERE子句不变 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/vexdb/","summary":"\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- cn: 50000\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- dn1: 50005\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- dn2: 50010\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e50000\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePG_DIST_NODE\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecreate_distributed_table\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;c1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 创建8个分片，dn1和dn2，每个dn有4个分片，即4个表，表名为 t1_$oid\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_dist_shard\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- min和max是hash之后的值\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_dist_shard_placement\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_dist_partition\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aa\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;bb\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e7\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;cc\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;dd\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e50005\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eoid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003erelname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_class\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erelname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003elike\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;%t1%\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ep\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e50010\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eoid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003erelname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_class\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erelname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003elike\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;%t1%\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# cn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eSELECT\u003c/span\u003e \u003cspan class=\"n\"\u003ecreate_distributed_table\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;c1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# --\u0026gt; shard 1 (dn1)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eSELECT\u003c/span\u003e \u003cspan class=\"n\"\u003eworker_apply_shard_ddl_command\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e12042\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;CREATE TABLE public.t1 (c1 integer, c2 text) WITH (orientation=row, compression=no, fillfactor=80)\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"c1\"\u003e# dn1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eworker_apply_shard_ddl_command\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eddlnode\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eParseTreeNode\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003esql\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eRelayEventExtendNames\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eddlnode\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003esharid\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 在语法解析树中，把t1名称，修改为t1_$shardid\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eProcessUtilityParseTree\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eSELECT\u003c/span\u003e \u003cspan class=\"n\"\u003eworker_apply_shard_ddl_command\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e12042\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;ALTER TABLE public.t1 OWNER TO shenkun\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# --\u0026gt; shard 2 (dn2)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eSELECT\u003c/span\u003e \u003cspan class=\"n\"\u003eworker_apply_shard_ddl_command\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e12043\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;CREATE TABLE public.t1 (c1 integer, c2 text) WITH (orientation=row, compression=no, fillfactor=80)\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eSELECT\u003c/span\u003e \u003cspan class=\"n\"\u003eworker_apply_shard_ddl_command\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e12043\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;ALTER TABLE public.t1 OWNER TO shenkun\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# --\u0026gt; shared 3 (dn1)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"o\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# --\u0026gt; 一共8个分片，每个分片2条SQL！\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# cn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eINSERT\u003c/span\u003e \u003cspan class=\"n\"\u003eINTO\u003c/span\u003e \u003cspan class=\"n\"\u003et1\u003c/span\u003e \u003cspan class=\"n\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aa\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),(\u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;bb\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),(\u003c/span\u003e\u003cspan class=\"mi\"\u003e7\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;cc\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e),(\u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;dd\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eexec_simple_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_parse_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_analyze_and_rewrite\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_plan_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eplanner\u003c/span\u003e \u003cspan class=\"n\"\u003ehook\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"n\"\u003edistributed_planner\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eCreateDistributedPlan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eCreateModifyPlan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eRouterInsertJob\u003c/span\u003e                      \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003edeferredPruning\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"n\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"c1\"\u003e# 返回 CustomScan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ePortalStart\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eExecutorStart\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eDVecExecutorStart\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"n\"\u003eDVecExecutorStart\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eBeginCustomScan\u003c/span\u003e \u003cspan class=\"err\"\u003e→\u003c/span\u003e \u003cspan class=\"n\"\u003eDVecBeginScan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eDVecBeginModifyScan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eRegenerateTaskListForInsert\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eBuildRoutesForInsert\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eFindShardInterval\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eActiveShardPlacementList\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eRebuildQueryStrings\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eDeparseTaskQuery\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eAppendShardIdToName\u003c/span\u003e  \u003cspan class=\"c1\"\u003e# 生成改名后SQL\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ePortalRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eExecutorRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eExecutorRun_hook\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"n\"\u003eDVecExecutorRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eExecCustomScan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eDVecExecScan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eAdaptiveExecutor\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eRunDistributedExecution\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"o\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eSendRemoteCommand\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003eStartRemoteTransactionBegin\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eBeginTransactiionCommand\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 生成：BEGIN ISOLATION LEVEL READ COMMITTED;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eAssignDistributedTransactionIdCommand\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 生成：SELECT assign_distributed_transaction_id(0,20,\u0026#39;...\u0026#39;);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003eSendRemoteCommand\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 一次发送2条事务SQL\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003eSendRemoteCommand\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003ePQsendQuery\u003c/span\u003e \u003cspan class=\"c1\"\u003e# INTO t1_$shardid ..\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eCoordinatedRemoteTransactionsPrepare\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"o\"\u003e..\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eSendRemoteCommand\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 发送 REPARE TRANSACTION ..\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eSendRemoteCommand\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 发送 COMMIT PREPARED ..\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# --\u0026gt; shard 1 (dn1)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eBEGIN\u003c/span\u003e \u003cspan class=\"n\"\u003eISOLATION\u003c/span\u003e \u003cspan class=\"n\"\u003eLEVEL\u003c/span\u003e \u003cspan class=\"n\"\u003eREAD\u003c/span\u003e \u003cspan class=\"n\"\u003eCOMMITTED\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eSELECT\u003c/span\u003e \u003cspan class=\"n\"\u003eassign_distributed_transaction_id\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"mi\"\u003e20\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;...\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eINSERT\u003c/span\u003e \u003cspan class=\"n\"\u003eINTO\u003c/span\u003e \u003cspan class=\"n\"\u003epublic\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003et1_12042\u003c/span\u003e \u003cspan class=\"n\"\u003eAS\u003c/span\u003e \u003cspan class=\"n\"\u003edvec_table_alias\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003eVALUES\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aa\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eREPARE\u003c/span\u003e \u003cspan class=\"n\"\u003eTRANSACTION\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;dvecx_...\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eCOMMIT\u003c/span\u003e \u003cspan class=\"n\"\u003ePREPARED\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;dvecx_...\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"c1\"\u003e# 执行分布式事务\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eINSERT\u003c/span\u003e \u003cspan class=\"n\"\u003eINTO\u003c/span\u003e \u003cspan class=\"n\"\u003epublic\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003et1_12042\u003c/span\u003e \u003cspan class=\"n\"\u003eAS\u003c/span\u003e \u003cspan class=\"n\"\u003edvec_table_alias\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003eVALUES\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aa\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# --\u0026gt; shard 2 (dn2)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eINSERT\u003c/span\u003e \u003cspan class=\"n\"\u003eINTO\u003c/span\u003e \u003cspan class=\"n\"\u003epublic\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003et1_12043\u003c/span\u003e \u003cspan class=\"n\"\u003eAS\u003c/span\u003e \u003cspan class=\"n\"\u003edvec_table_alias\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"n\"\u003eVALUES\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;dd\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# --\u0026gt; shared 3 (d1)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"o\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# --\u0026gt; 一共8个分片，其中4个分片，各收到1条INSERT语句\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 多行在同一分片，INSERT语句合并\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# cn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eSELECT\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003eFROM\u003c/span\u003e \u003cspan class=\"n\"\u003et1\u003c/span\u003e \u003cspan class=\"n\"\u003eWHERE\u003c/span\u003e \u003cspan class=\"n\"\u003ec1\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eexec_simple_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_parse_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_analyze_and_rewrite\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epg_plan_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eplanner\u003c/span\u003e \u003cspan class=\"n\"\u003ehook\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"n\"\u003edistributed_planner\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eCreateDistributedPlan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eGetRouterPlanType\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e一造\u003c/span\u003e \u003cspan class=\"n\"\u003emulti\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eshard\u003c/span\u003e \u003cspan class=\"n\"\u003efan\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eout\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e非\u003c/span\u003e \u003cspan class=\"n\"\u003erouter\u003c/span\u003e \u003cspan class=\"n\"\u003e计划\u003c/span\u003e\u003cspan class=\"p\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eMultiLogicalPlanCreate\u003c/span\u003e                      \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003elogical\u003c/span\u003e \u003cspan class=\"n\"\u003eplanner\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"n\"\u003e建逻辑计划\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eCreatePhysicalDistributedPlan\u003c/span\u003e               \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ephysical\u003c/span\u003e \u003cspan class=\"n\"\u003eplanner\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"err\"\u003e├─\u003c/span\u003e \u003cspan class=\"n\"\u003e为命中的每个分片建一个\u003c/span\u003e \u003cspan class=\"n\"\u003eTask\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e本表\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e \u003cspan class=\"n\"\u003e个分片\u003c/span\u003e \u003cspan class=\"err\"\u003e→\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e \u003cspan class=\"n\"\u003e个\u003c/span\u003e \u003cspan class=\"n\"\u003eTask\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eUpdateTaskQueryString\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eDeparseTaskQuery\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003edeparse_shard_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eAppendShardIdToName\u003c/span\u003e                   \u003cspan class=\"c1\"\u003e# t1 → t1_\u0026lt;shardId\u0026gt;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"c1\"\u003e# SELECT * + c1,c2 ; WHERE c1\u0026gt;10 → (c1 OPERATOR(pg_catalog.\u0026gt;) 10)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"c1\"\u003e# 包成 CustomScan 返回\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ePortalStart\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eExecutorStart\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eDVecExecutorStart\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"n\"\u003eDVecExecutorStart\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eBeginCustomScan\u003c/span\u003e \u003cspan class=\"err\"\u003e→\u003c/span\u003e \u003cspan class=\"n\"\u003eDVecBeginScan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ePortalRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eExecutorRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eExecutorRun_hook\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"n\"\u003eDVecExecutorRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eExecCustomScan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eDVecExecScan\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eAdaptiveExecutor\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eRunDistributedExecution\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eAssignTasksToConnectionsOrWorkerPool\u003c/span\u003e     \u003cspan class=\"c1\"\u003e# 8 个 Task 分给 DN1/DN2 的连接\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eConnectionStateMachine\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eStartRemoteTransactionBegin\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003e发送\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"n\"\u003eBEGIN\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003eassign\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003e每条\u003c/span\u003e \u003cspan class=\"n\"\u003eDN\u003c/span\u003e \u003cspan class=\"n\"\u003e连接首次用\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003e只发一次\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eBeginTransactionCommand\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"c1\"\u003e# 生成: BEGIN TRANSACTION ISOLATION LEVEL READ COMMITTED\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eAssignDistributedTransactionIdCommand\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"c1\"\u003e# 生成: SELECT assign_distributed_transaction_id(...)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eSendRemoteCommand\u003c/span\u003e \u003cspan class=\"err\"\u003e→\u003c/span\u003e \u003cspan class=\"n\"\u003ePQsendQuery\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003e两条合并成一条发出\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"c1\"\u003e# 发送: SELECT c1,c2 FROM t1_\u0026lt;shardId\u0026gt; WHERE (c1\u0026gt;10)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"c1\"\u003e#     DN1 上 4 条 (12042/12044/12046/12048), DN2 上 4 条\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eCOMMIT\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eRemoteTransactionCommit\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eSendRemoteCommand\u003c/span\u003e \u003cspan class=\"err\"\u003e→\u003c/span\u003e \u003cspan class=\"n\"\u003ePQsendQuery\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"c1\"\u003e# 只读 → 普通 COMMIT(无 PREPARE/COMMIT PREPARED,无 2PC)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"c1\"\u003e# COMMIT\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# --\u0026gt; shard 1 (dn1)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eSELECT\u003c/span\u003e \u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ec2\u003c/span\u003e \u003cspan class=\"n\"\u003eFROM\u003c/span\u003e \u003cspan class=\"n\"\u003epublic\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003et1_12042\u003c/span\u003e \u003cspan class=\"n\"\u003et1\u003c/span\u003e \u003cspan class=\"n\"\u003eWHERE\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e \u003cspan class=\"n\"\u003eOPERATOR\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epg_catalog\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u0026gt;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;cc\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003etext\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eSELECT\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003eFROM\u003c/span\u003e \u003cspan class=\"n\"\u003et1\u003c/span\u003e \u003cspan class=\"n\"\u003eWHERE\u003c/span\u003e \u003cspan class=\"n\"\u003ec2\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;cc\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"err\"\u003e密态：\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003ecn\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(..)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003edn\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1_$shardid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1_$shardid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(..)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e#\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evalues的值不变\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1_$shardid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e#\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eWHERE子句不变\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"国测 vexdb"},{"content":"1 专利名称 一种基于可信执行环境的数据库密态索引访问方法、系统及介质\n2 技术背景 全密态数据库：一种由数据库提供的安全特性，指数据库在处理数据的过程中，确保数据在传输、计算、存储等全生命周期阶段，于任何不可信的介质或环境中，始终处于加密状态。 全密态数据库实现方案：目前，业界较成熟的方案，是基于可信执行环境，实现全密态数据库，该方案主要分为2个模块：1)驱动加密：应用向数据库发送SQL语句时，应用侧的数据驱动自动加密SQL语句中的数据，数据库接收与处理数据密文。2)机密计算：数据库无法再密文上进行计算，将密文发送至可信执行环境（TEE）中，由可信模块完成解密与计算。 数据库索引结构：数据库中，最常见的索引为b+树索引。以tpcc测试模型为例，数据量低于100亿条时，b+树一般不超过4层。每一层的节点，即索引节点，是固定大小的page，分root index-page，internal index-page，leaf index-page。1个index-page中，存储多个index-item。其中，root和internal index-page中的index-item，存储数据和下一层index-page的位置。leaf index-page中的index-item，存储数据和table-page的位置。 加密性能：在加解密数据时，影响加密性能的因素中，加密次数的影响远高于数据长度。例如，1次加密8k数据，比40次加密200字节数据的性能高10+倍。 密态索引：在全密态数据库中，数据库只存储数据密文，在等值、范围查询等场景，为提高查询效率，避免全表扫描，需要在密文上构造索引。因此，需要见密文传输至可行执行环境TEE中，在TEE中临时解密数据，比较数据大小，构造索引。 现有方案缺陷：在构造密态索引时，现有方案存在以下缺陷：1)交互开销高：以索引元组为粒度，与TEE交互，交互次数多，交互开销高。2)加解密开销高：在索引页内比较元组大小时，需要多次解密索引元组。对于顶层的索引页，访问评率高，加解密频率也较高。3)内核修改多：为适配TEE，对索引构造、索引查询、并发控制等修改多，破坏生态兼容性等。 3 发明内容 发明目的：本发明针对在密文数据上构造索引、扫描索引的场景，提供一种通用的、高性能、低改造的方案，基于可信执行环境，大幅降低交互开销、加解密开销，并且，充分复用索引分裂、并发访问的机制，对内核侵入修改度低。\n技术方案：\n本发明的关键创新如下：\n构造索引：应用插入数据时，驱动以字段为粒度，加密数据。数据库接收数据密文，TEE解密数据，构造索引，并以索引页为粒度，重新加密数据。 访问索引：结合索引的访问特点，每个index-item不独立加密与解密，每次以index-page为粒度加密与解密，降低加解密次数。 发送索引：数据库向TEE发生索引时，每次以index-page为粒度发送，降低交互次数。 缓存索引：在TEE中，针对索引中root和internal page访问频率高、修改频率低的特点，缓存解密后的page，降低解密次数、与TEE的交互次数。 内核改造：数据库中，访问索引时，只在需要比较大小时，才与TEE交互，保留已有索引分裂、并发访问机制。 以tpcc模型为例，当warhouse为10000时：\n基表：bmsql_customer表中，数据行数为3亿，表大小约250G 索引：bmsql_customer主键索引中，index-item数为3亿，索引文件大小约9.5G，索引层数为4层，每层page数量分别：1、17、4400、114万，每个page中page-item数量约260个。插入1条数据，index-page平均分裂次数为0.0034次。 在该场景中，使用本发明的方案，考虑index-page分裂、TEE缓存偶尔未命中等所有可能产生额外交互、加密、解密的情况下：\n场景 与TEE交互次数 加密次数（TEE内） 解密次数（TEE内） 插入1条数据 \u0026lt; 2.01 \u0026lt; 1.01 \u0026lt; 1.01 查询1条数据 \u0026lt; 2.01 0 \u0026lt; 1.01 删除1条数据 \u0026lt; 2.01 \u0026lt; 1.01 \u0026lt; 1.01 4 附图及附图的简单说明 4.1 密态索引结构 密态索引中，所有index-page中，只存储数据密文。在TEE中，以page为粒度加密，PageHeader、PageTail中，不存储用户数据，无需加密。\n此处，以一个简单的3层索引为例，展示明文索引、密态索引的区别：\n4.2 密态索引插入流程 在图1的示例中，向索引中插入1条数据，流程如下：\n上述流程中，步骤12至20可通过缓存优化。以tpcc为例，index-item为3亿时，索引层数为4，索引文件大小约9.5G，root page数为1，internal page数为17+4000，缓存大小为31.38MB。\n5 具体实施方式 5.1 创建密态索引 管理员：创建密钥 CREATE DATA KEY dk1(..); 数据库驱动：通过密钥服务或密码机生成密钥，缓存密钥，向数据库发送密钥信息 数据库：在系统表中，存储密钥信息，包括：密钥名、密钥Oid等。 管理员：创建加密表和索引：CREATE TABLE t1(c1 INT ENCRYPTED BY dk1, c2 TEXT)，CREATE INDEX i1 ON t1(c1); 数据库：存储加密信息，包括：表名、列名、密钥名等。 5.2 向索引插入1条数据 前置条件：已创建密态索引 应用：连接数据库 数据驱动：连接数据库，查询加密信息、密钥信息，并缓存 数据库驱动：从密钥服务或密码机获取密钥，与可信执行环境建立安全通道，并传输密钥 可信执行环境：缓存密钥 应用：向数据库存储数据：INSERT INTO t1 VALUES (13, ‘data1’); 数据库驱动：对SQL进行语法解析，识别加密列字段，并加密字段，并改写SQL：INSERT INTO t1 VALUESS (cipher[13], ‘data1’); 数据库：向基表t1插入数据(cipher[13], ‘data1’)，准备构造索引 数据库：向TEE中，发送密文 cipher[13] 可信执行环境：解密cipher[13]，获取明文(13) 可信执行环境：查找缓存的root page，如果未找到，请求数据库发送root page，解密并缓存root page 可信执行环境：在root page中，二分查找，获取internal page位置 可信执行环境：查找缓存的internal page，如果未找到，请求数据库发送internal page，解密并缓存internal page 可信执行环境：在internal page中，二分查找，获取leaf page位置 可信执行环境：请求数据库发送leaf page。解密leaf page 可信执行环境：如果leaf page已满，触发分裂流程，此处不展开说明 可信执行环境：在leaf pag中，二分查找，获取插入位置 可信执行环境：在leaf page中，插入数据(13, 基表t1中13的存储位置) 可信执行环境：加密leaf page，向数据库返回加密后的leaf page 数据库：重新存储加密后的leaf page 5.3 从索引中查找1条数据 查询流程，与插入流程大部分一致：\n前置条件：已创建密态索引 应用：连接数据库 数据驱动：连接数据库，查询加密信息、密钥信息，并缓存 数据库驱动：从密钥服务或密码机获取密钥，与可信执行环境建立安全通道，并传输密钥 可信执行环境：缓存密钥 应用：从数据库中查询数据：SELECT * FROM t1 WHERE c1 = 13; 数据库驱动：对SQL进行语法解析，识别加密列字段，并加密字段，并改写SQL：SELECT * FROM t1 WHERE c1 = cipher[13]; 数据库：向TEE中，发送密文 cipher[13] 可信执行环境：解密cipher[13]，获取明文(13) 可信执行环境：查找缓存的root page，如果未找到，请求数据库发送root page，解密并缓存root page 可信执行环境：在root page中，二分查找，获取internal page位置 可信执行环境：查找缓存的internal page，如果未找到，请求数据库发送internal page，解密并缓存internal page 可信执行环境：在internal page中，二分查找，获取leaf page位置 可信执行环境：请求数据库发送leaf page。解密leaf page 可信执行环境：在leaf pag中，二分查找，获取数据(13)对应的索引项 可信执行环境：从数据(13)对应的索引项中，获取基表t1中对应的位置 可信执行环境：向数据库返回基表t1中(13)的存储位置 数据库：从基表t1中，获取数据(13)对应的数据(cipher[13], ‘data1’) 数据库：向数据库驱动返回数据(cipher[13], ‘data1’) 数据库驱动：接受(cipher[13], ‘data1’)，解密cipher[13]为数据(13) 应用：获取数据(13, ‘data1’) ","permalink":"https://my-blog.j8465383071.workers.dev/posts/compliance/patent-encrypted-index/","summary":"\u003ch1 id=\"1-专利名称\"\u003e1 专利名称\u003c/h1\u003e\n\u003cp\u003e一种基于可信执行环境的数据库密态索引访问方法、系统及介质\u003c/p\u003e\n\u003ch1 id=\"2-技术背景\"\u003e2 技术背景\u003c/h1\u003e\n\u003cul\u003e\n\u003cli\u003e全密态数据库：一种由数据库提供的安全特性，指数据库在处理数据的过程中，确保数据在传输、计算、存储等全生命周期阶段，于任何不可信的介质或环境中，始终处于加密状态。\u003c/li\u003e\n\u003cli\u003e全密态数据库实现方案：目前，业界较成熟的方案，是基于可信执行环境，实现全密态数据库，该方案主要分为2个模块：1)驱动加密：应用向数据库发送SQL语句时，应用侧的数据驱动自动加密SQL语句中的数据，数据库接收与处理数据密文。2)机密计算：数据库无法再密文上进行计算，将密文发送至可信执行环境（TEE）中，由可信模块完成解密与计算。\u003c/li\u003e\n\u003cli\u003e数据库索引结构：数据库中，最常见的索引为b+树索引。以tpcc测试模型为例，数据量低于100亿条时，b+树一般不超过4层。每一层的节点，即索引节点，是固定大小的page，分root index-page，internal index-page，leaf index-page。1个index-page中，存储多个index-item。其中，root和internal index-page中的index-item，存储数据和下一层index-page的位置。leaf index-page中的index-item，存储数据和table-page的位置。\u003c/li\u003e\n\u003cli\u003e加密性能：在加解密数据时，影响加密性能的因素中，加密次数的影响远高于数据长度。例如，1次加密8k数据，比40次加密200字节数据的性能高10+倍。\u003c/li\u003e\n\u003cli\u003e密态索引：在全密态数据库中，数据库只存储数据密文，在等值、范围查询等场景，为提高查询效率，避免全表扫描，需要在密文上构造索引。因此，需要见密文传输至可行执行环境TEE中，在TEE中临时解密数据，比较数据大小，构造索引。\u003c/li\u003e\n\u003cli\u003e现有方案缺陷：在构造密态索引时，现有方案存在以下缺陷：1)交互开销高：以索引元组为粒度，与TEE交互，交互次数多，交互开销高。2)加解密开销高：在索引页内比较元组大小时，需要多次解密索引元组。对于顶层的索引页，访问评率高，加解密频率也较高。3)内核修改多：为适配TEE，对索引构造、索引查询、并发控制等修改多，破坏生态兼容性等。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"3-发明内容\"\u003e3 发明内容\u003c/h1\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e发明目的\u003c/strong\u003e：本发明针对在密文数据上构造索引、扫描索引的场景，提供一种通用的、高性能、低改造的方案，基于可信执行环境，大幅降低交互开销、加解密开销，并且，充分复用索引分裂、并发访问的机制，对内核侵入修改度低。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003e技术方案\u003c/strong\u003e：\u003cbr\u003e\n本发明的关键创新如下：\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003col\u003e\n\u003cli\u003e构造索引：应用插入数据时，驱动以字段为粒度，加密数据。数据库接收数据密文，TEE解密数据，构造索引，并以索引页为粒度，重新加密数据。\u003c/li\u003e\n\u003cli\u003e访问索引：结合索引的访问特点，每个index-item不独立加密与解密，每次以index-page为粒度加密与解密，降低加解密次数。\u003c/li\u003e\n\u003cli\u003e发送索引：数据库向TEE发生索引时，每次以index-page为粒度发送，降低交互次数。\u003c/li\u003e\n\u003cli\u003e缓存索引：在TEE中，针对索引中root和internal page访问频率高、修改频率低的特点，缓存解密后的page，降低解密次数、与TEE的交互次数。\u003c/li\u003e\n\u003cli\u003e内核改造：数据库中，访问索引时，只在需要比较大小时，才与TEE交互，保留已有索引分裂、并发访问机制。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e以tpcc模型为例，当warhouse为10000时：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e基表：bmsql_customer表中，数据行数为3亿，表大小约250G\u003c/li\u003e\n\u003cli\u003e索引：bmsql_customer主键索引中，index-item数为3亿，索引文件大小约9.5G，索引层数为4层，每层page数量分别：1、17、4400、114万，每个page中page-item数量约260个。插入1条数据，index-page平均分裂次数为0.0034次。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e在该场景中，使用本发明的方案，考虑index-page分裂、TEE缓存偶尔未命中等所有可能产生额外交互、加密、解密的情况下：\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e场景\u003c/th\u003e\n          \u003cth\u003e与TEE交互次数\u003c/th\u003e\n          \u003cth\u003e加密次数（TEE内）\u003c/th\u003e\n          \u003cth\u003e解密次数（TEE内）\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e插入1条数据\u003c/td\u003e\n          \u003ctd\u003e\u0026lt; 2.01\u003c/td\u003e\n          \u003ctd\u003e\u0026lt; 1.01\u003c/td\u003e\n          \u003ctd\u003e\u0026lt; 1.01\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e查询1条数据\u003c/td\u003e\n          \u003ctd\u003e\u0026lt; 2.01\u003c/td\u003e\n          \u003ctd\u003e0\u003c/td\u003e\n          \u003ctd\u003e\u0026lt; 1.01\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e删除1条数据\u003c/td\u003e\n          \u003ctd\u003e\u0026lt; 2.01\u003c/td\u003e\n          \u003ctd\u003e\u0026lt; 1.01\u003c/td\u003e\n          \u003ctd\u003e\u0026lt; 1.01\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch1 id=\"4-附图及附图的简单说明\"\u003e4 附图及附图的简单说明\u003c/h1\u003e\n\u003ch2 id=\"41-密态索引结构\"\u003e4.1 密态索引结构\u003c/h2\u003e\n\u003cp\u003e密态索引中，所有index-page中，只存储数据密文。在TEE中，以page为粒度加密，PageHeader、PageTail中，不存储用户数据，无需加密。\u003cbr\u003e\n此处，以一个简单的3层索引为例，展示明文索引、密态索引的区别：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"idx-diff\" loading=\"lazy\" src=\"/images/Compliance/patent-encrypted-index/idx-diff.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"42-密态索引插入流程\"\u003e4.2 密态索引插入流程\u003c/h2\u003e\n\u003cp\u003e在图1的示例中，向索引中插入1条数据，流程如下：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"idx-ins\" loading=\"lazy\" src=\"/images/Compliance/patent-encrypted-index/idx-ins.png\"\u003e\u003c/p\u003e\n\u003cp\u003e上述流程中，步骤12至20可通过缓存优化。以tpcc为例，index-item为3亿时，索引层数为4，索引文件大小约9.5G，root page数为1，internal page数为17+4000，缓存大小为31.38MB。\u003c/p\u003e\n\u003ch1 id=\"5-具体实施方式\"\u003e5 具体实施方式\u003c/h1\u003e\n\u003ch2 id=\"51-创建密态索引\"\u003e5.1 创建密态索引\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e管理员：创建密钥 CREATE DATA KEY dk1(..);\u003c/li\u003e\n\u003cli\u003e数据库驱动：通过密钥服务或密码机生成密钥，缓存密钥，向数据库发送密钥信息\u003c/li\u003e\n\u003cli\u003e数据库：在系统表中，存储密钥信息，包括：密钥名、密钥Oid等。\u003c/li\u003e\n\u003cli\u003e管理员：创建加密表和索引：CREATE TABLE t1(c1 INT ENCRYPTED BY dk1, c2 TEXT)，CREATE INDEX i1 ON t1(c1);\u003c/li\u003e\n\u003cli\u003e数据库：存储加密信息，包括：表名、列名、密钥名等。\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"52-向索引插入1条数据\"\u003e5.2 向索引插入1条数据\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e前置条件：已创建密态索引\u003c/li\u003e\n\u003cli\u003e应用：连接数据库\u003c/li\u003e\n\u003cli\u003e数据驱动：连接数据库，查询加密信息、密钥信息，并缓存\u003c/li\u003e\n\u003cli\u003e数据库驱动：从密钥服务或密码机获取密钥，与可信执行环境建立安全通道，并传输密钥\u003c/li\u003e\n\u003cli\u003e可信执行环境：缓存密钥\u003c/li\u003e\n\u003cli\u003e应用：向数据库存储数据：INSERT INTO t1 VALUES (13, ‘data1’);\u003c/li\u003e\n\u003cli\u003e数据库驱动：对SQL进行语法解析，识别加密列字段，并加密字段，并改写SQL：INSERT INTO t1 VALUESS (cipher[13], ‘data1’);\u003c/li\u003e\n\u003cli\u003e数据库：向基表t1插入数据(cipher[13], ‘data1’)，准备构造索引\u003c/li\u003e\n\u003cli\u003e数据库：向TEE中，发送密文 cipher[13]\u003c/li\u003e\n\u003cli\u003e可信执行环境：解密cipher[13]，获取明文(13)\u003c/li\u003e\n\u003cli\u003e可信执行环境：查找缓存的root page，如果未找到，请求数据库发送root page，解密并缓存root page\u003c/li\u003e\n\u003cli\u003e可信执行环境：在root page中，二分查找，获取internal page位置\u003c/li\u003e\n\u003cli\u003e可信执行环境：查找缓存的internal page，如果未找到，请求数据库发送internal page，解密并缓存internal page\u003c/li\u003e\n\u003cli\u003e可信执行环境：在internal page中，二分查找，获取leaf page位置\u003c/li\u003e\n\u003cli\u003e可信执行环境：请求数据库发送leaf page。解密leaf page\u003c/li\u003e\n\u003cli\u003e可信执行环境：如果leaf page已满，触发分裂流程，此处不展开说明\u003c/li\u003e\n\u003cli\u003e可信执行环境：在leaf pag中，二分查找，获取插入位置\u003c/li\u003e\n\u003cli\u003e可信执行环境：在leaf page中，插入数据(13, 基表t1中13的存储位置)\u003c/li\u003e\n\u003cli\u003e可信执行环境：加密leaf page，向数据库返回加密后的leaf page\u003c/li\u003e\n\u003cli\u003e数据库：重新存储加密后的leaf page\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"53-从索引中查找1条数据\"\u003e5.3 从索引中查找1条数据\u003c/h2\u003e\n\u003cp\u003e查询流程，与插入流程大部分一致：\u003c/p\u003e","title":"专利 全密态 索引"},{"content":"4 安全架构 4.1 威胁模型 数据库运行在复杂的环境中，在计算、传输、存储数据等阶段，攻击者可利用硬件、软件等漏洞，威胁数据库安全。本文以数据库为核心，缩短攻击链路，排除攻击者身份演变、攻击阶段演进等因素，构造简化的威胁模型：\n一、角色 黑客 内部运维人员 内部研发人员 系统维护人员 供应链 网络中间人 机房管理人员 二、动机 售卖获利 勒索获利 情报窃取 蓄意报复 规避审计 炫耀技能 人为过失 三、目标 鉴别数据 用户表 系统表 事务日志 审计日志 内存数据 配置文件 四、技术 不可信IP登录 默认账户攻击 过期账号攻击 弱口令攻击 密码泄露 暴力破解 凭证重放 内存凭证残留 流量伪造 流量重放 证书伪造 未授权访问 越权访问 权限提升 权限滥用 磁盘窃取 恶意软件 操作系统隔离失效 数据文件篡改 供应链后门 侧信道内存嗅探 调试工具滥用 特权用户窥探 审计日志伪造 攻击行为隐匿 恶意操作抵赖 合规审计证据缺失 五、分类 欺骗 篡改 否认 信息泄露 拒绝服务 权限提升 4.2 防御模型 针对威胁模型，本文从接入、传输、访问、存储、计算、合规6个维度，提供以下安全功能，构建防御模型：\n接入安全：合法用户，才能接入数据库 网络防火墙 身份认证 传输安全：与数据库的通信数据， 安全传输 访问安全 访问控制 计算安全 驱动加密 机密计算 密码函数 存储安全 透明加密 合法合规 安全审计 动态脱敏 密钥管理 防御模型如下图所示：\n4.3 安全功能 内核提供多种安全功能，有效解决各类威胁，保障数据在各阶段的机密性、完整性、可用性、可认证性、不可抵赖性等。目前，内核中各安全功能的关键功能点如下：\n网络防火墙 多维度接入控制：主机、角色、数据库等 身份认证 用户管理：创建、锁定、解锁、过期、删除 口令复杂度校验：长度、字符、重复 弱口令校验 口令安全存储：sha256、sm3 认证失败限制 密码有效限制：失效提醒、账号锁定 内存凭证清理 多因素认证：证书、Kerberos、peer等 安全传输 TLS协议 TLCP协议 双向证书认证 证书有效校验 算法套件可配 访问控制 自主访问控制 强制访问控制 角色访问控制 行级访问控制 三权分立 视图访问控制：SECURITY DEFINER 驱动加密 密文端到端处理 列级加密 多级密钥 密态等值查询 机密计算 密态范围查询 密态模糊查询 密态排序 密态表达式计算 密态连接 密码函数 加密函数 哈希函数 密钥派生函数 随机数函数 透明加密 表级加密 索引加密 预写日志加密 双写加密 多级密钥 密钥轮转 数据防篡改 操作记录 篡改校验 安全审计 细粒度策略：用户、操作类型、对象、操作结果等 系统审计 日志存储 日志查询 日志加密 日志清理 动态脱敏 细粒度策略：角色、会话 脱敏算法可选 密钥管理 密钥服务可配 硬件加密 国密算法 未来：数据治理：敏感数据识别、分类分级、血缘分析、风险评估。隐私增强计算：差分隐私、联邦学习接口、匿名化\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/compliance/security-architecture/","summary":"\u003ch1 id=\"4-安全架构\"\u003e4 安全架构\u003c/h1\u003e\n\u003ch2 id=\"41-威胁模型\"\u003e4.1 威胁模型\u003c/h2\u003e\n\u003cp\u003e数据库运行在复杂的环境中，在计算、传输、存储数据等阶段，攻击者可利用硬件、软件等漏洞，威胁数据库安全。本文以数据库为核心，缩短攻击链路，排除攻击者身份演变、攻击阶段演进等因素，构造简化的威胁模型：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e一、角色\n\u003col\u003e\n\u003cli\u003e黑客\u003c/li\u003e\n\u003cli\u003e内部运维人员\u003c/li\u003e\n\u003cli\u003e内部研发人员\u003c/li\u003e\n\u003cli\u003e系统维护人员\u003c/li\u003e\n\u003cli\u003e供应链\u003c/li\u003e\n\u003cli\u003e网络中间人\u003c/li\u003e\n\u003cli\u003e机房管理人员\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e二、动机\n\u003col\u003e\n\u003cli\u003e售卖获利\u003c/li\u003e\n\u003cli\u003e勒索获利\u003c/li\u003e\n\u003cli\u003e情报窃取\u003c/li\u003e\n\u003cli\u003e蓄意报复\u003c/li\u003e\n\u003cli\u003e规避审计\u003c/li\u003e\n\u003cli\u003e炫耀技能\u003c/li\u003e\n\u003cli\u003e人为过失\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e三、目标\n\u003col\u003e\n\u003cli\u003e鉴别数据\u003c/li\u003e\n\u003cli\u003e用户表\u003c/li\u003e\n\u003cli\u003e系统表\u003c/li\u003e\n\u003cli\u003e事务日志\u003c/li\u003e\n\u003cli\u003e审计日志\u003c/li\u003e\n\u003cli\u003e内存数据\u003c/li\u003e\n\u003cli\u003e配置文件\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e四、技术\n\u003col\u003e\n\u003cli\u003e不可信IP登录\u003c/li\u003e\n\u003cli\u003e默认账户攻击\u003c/li\u003e\n\u003cli\u003e过期账号攻击\u003c/li\u003e\n\u003cli\u003e弱口令攻击\u003c/li\u003e\n\u003cli\u003e密码泄露\u003c/li\u003e\n\u003cli\u003e暴力破解\u003c/li\u003e\n\u003cli\u003e凭证重放\u003c/li\u003e\n\u003cli\u003e内存凭证残留\u003c/li\u003e\n\u003cli\u003e流量伪造\u003c/li\u003e\n\u003cli\u003e流量重放\u003c/li\u003e\n\u003cli\u003e证书伪造\u003c/li\u003e\n\u003cli\u003e未授权访问\u003c/li\u003e\n\u003cli\u003e越权访问\u003c/li\u003e\n\u003cli\u003e权限提升\u003c/li\u003e\n\u003cli\u003e权限滥用\u003c/li\u003e\n\u003cli\u003e磁盘窃取\u003c/li\u003e\n\u003cli\u003e恶意软件\u003c/li\u003e\n\u003cli\u003e操作系统隔离失效\u003c/li\u003e\n\u003cli\u003e数据文件篡改\u003c/li\u003e\n\u003cli\u003e供应链后门\u003c/li\u003e\n\u003cli\u003e侧信道内存嗅探\u003c/li\u003e\n\u003cli\u003e调试工具滥用\u003c/li\u003e\n\u003cli\u003e特权用户窥探\u003c/li\u003e\n\u003cli\u003e审计日志伪造\u003c/li\u003e\n\u003cli\u003e攻击行为隐匿\u003c/li\u003e\n\u003cli\u003e恶意操作抵赖\u003c/li\u003e\n\u003cli\u003e合规审计证据缺失\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e五、分类\n\u003col\u003e\n\u003cli\u003e欺骗\u003c/li\u003e\n\u003cli\u003e篡改\u003c/li\u003e\n\u003cli\u003e否认\u003c/li\u003e\n\u003cli\u003e信息泄露\u003c/li\u003e\n\u003cli\u003e拒绝服务\u003c/li\u003e\n\u003cli\u003e权限提升\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"42-防御模型\"\u003e4.2 防御模型\u003c/h2\u003e\n\u003cp\u003e针对威胁模型，本文从接入、传输、访问、存储、计算、合规6个维度，提供以下安全功能，构建防御模型：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e接入安全：合法用户，才能接入数据库\n\u003cul\u003e\n\u003cli\u003e网络防火墙\u003c/li\u003e\n\u003cli\u003e身份认证\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e传输安全：与数据库的通信数据，\n\u003cul\u003e\n\u003cli\u003e安全传输\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e访问安全\n\u003cul\u003e\n\u003cli\u003e访问控制\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e计算安全\n\u003cul\u003e\n\u003cli\u003e驱动加密\u003c/li\u003e\n\u003cli\u003e机密计算\u003c/li\u003e\n\u003cli\u003e密码函数\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e存储安全\n\u003cul\u003e\n\u003cli\u003e透明加密\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e合法合规\n\u003cul\u003e\n\u003cli\u003e安全审计\u003c/li\u003e\n\u003cli\u003e动态脱敏\u003c/li\u003e\n\u003cli\u003e密钥管理\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e防御模型如下图所示：\u003c/p\u003e","title":"国测 安全架构"},{"content":"# 角色 你是一名 PostgreSQL 16 内核开发工程师，精通 src/backend/access/transam 及相关模块源码。 # 约束 1. 所有回答必须严格基于 PostgreSQL 16 Release 源码。 2. 解释机制时，必须引用具体的 .c/.h 文件路径和关键函数名。 3. 涉及数据结构时，请给出 struct 定义所在的头文件及字段含义。 4. 禁止使用“可能”、“通常”等模糊词汇描述内核行为；若不确定或版本不符，请明确告知。 5. 代码片段必须标注来源文件及大致行号范围（或函数上下文）。 # 当前任务 - 请梳理 XactBegin() 到 XactCommit() 的核心调用链，重点说明 CriticalSection 的作用。 - 解释 PG16 中 clog (pg_xact) 的写入与刷盘时机，结合 TransactionIdSetPageStatus 函数分析。 - MVCC 快照获取逻辑在 GetSnapshotData 中是如何与活跃事务列表交互的？ - 两阶段提交 (2PC) 在 PG16 中的状态持久化流程是什么？涉及哪些 WAL record 类型？ # 输出格式 1. 核心流程图/调用链（文字描述即可） 2. 关键源码位置（文件:函数） 3. 设计意图与权衡（Why it is implemented this way） 4. 相关 GUC 参数及其对代码路径的影响 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/ai/","summary":"\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 角色\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e你是一名 PostgreSQL \u003cspan class=\"m\"\u003e16\u003c/span\u003e 内核开发工程师，精通 src/backend/access/transam 及相关模块源码。\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 约束\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e1. 所有回答必须严格基于 PostgreSQL \u003cspan class=\"m\"\u003e16\u003c/span\u003e Release 源码。\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e2. 解释机制时，必须引用具体的 .c/.h 文件路径和关键函数名。\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e3. 涉及数据结构时，请给出 struct 定义所在的头文件及字段含义。\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e4. 禁止使用“可能”、“通常”等模糊词汇描述内核行为；若不确定或版本不符，请明确告知。\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e5. 代码片段必须标注来源文件及大致行号范围（或函数上下文）。\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 当前任务\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e- 请梳理 XactBegin\u003cspan class=\"o\"\u003e()\u003c/span\u003e 到 XactCommit\u003cspan class=\"o\"\u003e()\u003c/span\u003e 的核心调用链，重点说明 CriticalSection 的作用。\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e- 解释 PG16 中 clog \u003cspan class=\"o\"\u003e(\u003c/span\u003epg_xact\u003cspan class=\"o\"\u003e)\u003c/span\u003e 的写入与刷盘时机，结合 TransactionIdSetPageStatus 函数分析。\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e- MVCC 快照获取逻辑在 GetSnapshotData 中是如何与活跃事务列表交互的？\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e- 两阶段提交 \u003cspan class=\"o\"\u003e(\u003c/span\u003e2PC\u003cspan class=\"o\"\u003e)\u003c/span\u003e 在 PG16 中的状态持久化流程是什么？涉及哪些 WAL record 类型？\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 输出格式\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e1. 核心流程图/调用链（文字描述即可）\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e2. 关键源码位置（文件:函数）\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e3. 设计意图与权衡（Why it is implemented this way）\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e4. 相关 GUC 参数及其对代码路径的影响\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"ai"},{"content":"# 单文件 pg_xlogdump 000000010000000000000001 # 多文件，指定lsn开始 pg_xlogdump -s 0/1000020 000000010000000000000001 # 多文件，整个目录 pg_xlogdump -p /opt/openGauss/data/pg_xlog SELECT pg_current_wal_lsn(); \\! pg_xlogdump -p $GAUSSHOME/data/pg_xlog -s num=1640180680 printf \u0026#34;%X/%X\\n\u0026#34; $((num \u0026gt;\u0026gt; 32)) $((num \u0026amp; 0xFFFFFFFF)) # 示例： 0/61c32bc8 pg_xlogdump -s 0/61c32bc8 -x 131128 printf \u0026#34;%x\\n\u0026#34; 1640180680 # 示例： 61c32bc8 pg_xlogdump -s 000000010000000100000061 -x 131128 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/pg-xlogdump/","summary":"\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 单文件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epg_xlogdump \u003cspan class=\"m\"\u003e000000010000000000000001\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 多文件，指定lsn开始\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epg_xlogdump -s 0/1000020 \u003cspan class=\"m\"\u003e000000010000000000000001\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 多文件，整个目录\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epg_xlogdump -p /opt/openGauss/data/pg_xlog\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eSELECT pg_current_wal_lsn\u003cspan class=\"o\"\u003e()\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"se\"\u003e\\!\u003c/span\u003e pg_xlogdump -p \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data/pg_xlog -s\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003enum\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"m\"\u003e1640180680\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eprintf\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;%X/%X\\n\u0026#34;\u003c/span\u003e \u003cspan class=\"k\"\u003e$((\u003c/span\u003enum \u0026gt;\u0026gt; \u003cspan class=\"m\"\u003e32\u003c/span\u003e\u003cspan class=\"k\"\u003e))\u003c/span\u003e \u003cspan class=\"k\"\u003e$((\u003c/span\u003enum \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e \u003cspan class=\"m\"\u003e0\u003c/span\u003exFFFFFFFF\u003cspan class=\"k\"\u003e))\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 示例： 0/61c32bc8\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epg_xlogdump -s 0/61c32bc8  -x \u003cspan class=\"m\"\u003e131128\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eprintf\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;%x\\n\u0026#34;\u003c/span\u003e \u003cspan class=\"m\"\u003e1640180680\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 示例： 61c32bc8\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epg_xlogdump -s \u003cspan class=\"m\"\u003e000000010000000100000061\u003c/span\u003e  -x \u003cspan class=\"m\"\u003e131128\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"工具 pg_xlogdump"},{"content":"1 磁盘 # 各文件夹大小 du -sh ./* | sort -hr ","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/hardware-resource/","summary":"\u003ch1 id=\"1-磁盘\"\u003e1 磁盘\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 各文件夹大小\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edu -sh ./* \u003cspan class=\"p\"\u003e|\u003c/span\u003e sort -hr\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"工具 硬件资源"},{"content":"1 背景 1.1 友商分析 oracle\n范围：行级、列级 实现：动态谓词过滤 金仓\n范围：列级 mysql\n无 sql server\n范围：行级 实现：谓词过滤 oracle\n基于标签的访问控制OLS：绝密HS、机密S、秘密C、公开P https://docs.oracle.com/en/database/oracle/oracle-database/26/olsag/part1.html#GUID-C20C62AE-2A30-45F9-AEEA-52A0D3286FBA\n-- 1 定义策略 SA_SYSDBA.CREATE_POLICY(policy_name =\u0026gt; \u0026#39;HR_POLICY\u0026#39;, column_name =\u0026gt; \u0026#39;HR_LABEL\u0026#39;) -- 2 定义标签 SA_COMPONENTS.CREATE_LEVEL(\u0026#39;HR_POLICY\u0026#39;, 1000, \u0026#39;PUBLIC\u0026#39;, \u0026#39;P\u0026#39;); -- 3 设置标签属性 SA_USER_ADMIN.SET_LEVELS(\u0026#39;HR_POLICY\u0026#39;, \u0026#39;SCOTT\u0026#39;, \u0026#39;C\u0026#39;, \u0026#39;S\u0026#39;); SA_USER_ADMIN.SET_COMPARTMENTS(\u0026#39;HR_POLICY\u0026#39;, \u0026#39;SCOTT\u0026#39;, \u0026#39;FIN\u0026#39;); -- 4 插入数据（主动定义标签） INSERT INTO employees (emp_id, emp_name, salary, HR_LABEL) VALUES (1001, \u0026#39;John Doe\u0026#39;, 50000, CHAR_TO_LABEL(\u0026#39;HR_POLICY\u0026#39;, \u0026#39;C:FIN\u0026#39;)); sql server：无\nkngbase\n行级\n链接：https://help.kingbase.com.cn/v8/safety/safety-guide/label-and-mac.html#id5\n范围：table, view, index, procedure, function, package, sequence, trigger, synonym\n原则：下读、区间写\n-- 创建策略 SELECT sysmac.create_policy (\u0026#39;p1\u0026#39;,\u0026#39;p1_c\u0026#39;,false); -- 策略名、在表上新增1列p1_c、是否隐藏策略列 -- 创建等级 SELECT sysmac.create_level(\u0026#39;p1\u0026#39;,\u0026#39;l1\u0026#39;,10); -- 策略名、等级名、等级值 -- 创建范围 SELECT sysmac.create_compartment(\u0026#39;p1\u0026#39;,\u0026#39;c4\u0026#39;,100); -- 策略名、策略下的范围、范围的ID -- 创建标记 SELECT sysmac.create_label(\u0026#39;p1\u0026#39;,\u0026#39;l1:c4\u0026#39;,11); -- 策略名、标记名、标记的ID -- 设置用户等级 SELECT sysmac.set_levels(\u0026#39;p1\u0026#39;,\u0026#39;u1\u0026#39;,\u0026#39;l5\u0026#39;,\u0026#39;l2\u0026#39;,\u0026#39;l4\u0026#39;,\u0026#39;l3\u0026#39;); -- 策略名、用户名、读写最高等级、写最低等级、用户默认等级、写等级 -- 设置用户范围 SELECT sysmac.set_compartments(\u0026#39;p1\u0026#39;,\u0026#39;u1\u0026#39;,\u0026#39;c1,c2,c3,c4,c5\u0026#39;,\u0026#39;c1,c2,c3\u0026#39;,\u0026#39;c1,c2,c4\u0026#39;, \u0026#39;c1,c2\u0026#39;); -- 策略名、用户名、读权限范围列表、最大写权限范围列表、默认读权限范围列表、默认写范围列表、最小写权限范围 -- 设置用户标记 SELECT sysmac.set_user_labels(\u0026#39;p1\u0026#39;, \u0026#39;u1\u0026#39;, \u0026#39;l5:c1,c2,c3,c4,c5\u0026#39;, \u0026#39;l5:c1,c2,c3\u0026#39;, \u0026#39;l2:\u0026#39;, \u0026#39;l4:c1,c2,c4\u0026#39;, \u0026#39;l3:c1,c2\u0026#39;); -- 策略名、用户名、最大读标记、最大写标记、写标记、最小写标记、用户默认标记 -- 设置用户特权 -- 设置表行级策略 sysmac.apply_table_policy(policy_name, schema_name, table_name) -- 设置对象策略 sysmac.apply_obj_policy(policy_name,object_type,schema_name,object_name,label) -- .. 完整实例\nalter system set sysmac.enable_mac=on; -- 创建策略 select sysmac.create_policy (\u0026#39;p1\u0026#39;,\u0026#39;p1_column\u0026#39;,true); -- 创建等级 select sysmac.create_level(\u0026#39;p1\u0026#39;,\u0026#39;general\u0026#39;,10); select sysmac.create_level(\u0026#39;p1\u0026#39;,\u0026#39;privacy\u0026#39;,20); select sysmac.create_level(\u0026#39;p1\u0026#39;,\u0026#39;secret\u0026#39;,30); -- 设置范围 select sysmac.create_compartment(\u0026#39;p1\u0026#39;,\u0026#39;manager\u0026#39;,40); -- 创建用户 urd_manager uqa_manager ugeneral_manager 00 为用户设置 select sysmac.set_user_labels(\u0026#39;p1\u0026#39;,\u0026#39;ugeneral_manager\u0026#39;, \u0026#39;secret:manager,qa,unimportant\u0026#39;, \u0026#39;secret:manager,qa\u0026#39;,\u0026#39;secret:\u0026#39;, \u0026#39;secret:\u0026#39;, \u0026#39;secret:manager,qa\u0026#39;); -- 1.2 友商实现 oracle实现\nCREATE TABLE t1 ( id NUMBER, sec_label DB2SECURITYLABEL -- 标签列 ) SECURITY POLICY DataAccess; GRANT SECURITY LABEL DataAccess.SecretLabel TO USER JOE FOR READ ACCESS; ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/mandatory-access-control/","summary":"\u003ch1 id=\"1-背景\"\u003e1 背景\u003c/h1\u003e\n\u003ch2 id=\"11-友商分析\"\u003e1.1 友商分析\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eoracle\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e范围：行级、列级\u003c/li\u003e\n\u003cli\u003e实现：动态谓词过滤\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e金仓\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e范围：列级\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003emysql\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e无\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003esql server\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e范围：行级\u003c/li\u003e\n\u003cli\u003e实现：谓词过滤\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eoracle\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e基于标签的访问控制OLS：绝密HS、机密S、秘密C、公开P\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://docs.oracle.com/en/database/oracle/oracle-database/26/olsag/part1.html#GUID-C20C62AE-2A30-45F9-AEEA-52A0D3286FBA\"\u003ehttps://docs.oracle.com/en/database/oracle/oracle-database/26/olsag/part1.html#GUID-C20C62AE-2A30-45F9-AEEA-52A0D3286FBA\u003c/a\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 1 定义策略\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSA_SYSDBA\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_POLICY\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epolicy_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;HR_POLICY\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecolumn_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;HR_LABEL\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2 定义标签\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSA_COMPONENTS\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_LEVEL\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;HR_POLICY\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1000\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;PUBLIC\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;P\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 设置标签属性\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSA_USER_ADMIN\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eSET_LEVELS\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;HR_POLICY\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;SCOTT\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;C\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;S\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSA_USER_ADMIN\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eSET_COMPARTMENTS\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;HR_POLICY\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;SCOTT\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;FIN\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 4 插入数据（主动定义标签）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eemployees\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eemp_id\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eemp_name\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esalary\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eHR_LABEL\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1001\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;John Doe\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e50000\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eCHAR_TO_LABEL\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;HR_POLICY\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;C:FIN\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003esql server：无\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ekngbase\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e行级\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e链接：\u003ca href=\"https://help.kingbase.com.cn/v8/safety/safety-guide/label-and-mac.html#id5\"\u003ehttps://help.kingbase.com.cn/v8/safety/safety-guide/label-and-mac.html#id5\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e范围：table, view, index, procedure, function, package, sequence, trigger, synonym\u003c/p\u003e","title":"强制访问控制"},{"content":"安装 wget https://unofficial-builds.nodejs.org/download/release/v20.18.1/node-v20.18.1-linux-x64-glibc-217.tar.xz tar -Jxvf node-v20.18.1-linux-x64-glibc-217.tar.xz mv node-v20.18.1-linux-x64-glibc-217 node-20 touch envn echo \u0026#39; export NODEHOME=`pwd`/node-20 export PATH=$NODEHOME/bin:$PATH export LD_LIBRARY_PATH=$NODEHOME/lib:$LD_LIBRARY_PATH \u0026#39; \u0026gt; envn source envn mkdir npm-global npm config set prefix `pwd`/npm-global npm config set prefix $NODEHOME/npm-global echo \u0026#39;export PATH=$NODEHOME/../npm-global/bin:$PATH\u0026#39; \u0026gt;\u0026gt; envn source envn npm pack @anthropic-ai/claude-code npm install -g ./anthropic-ai-claude-code-2.1.162.tgz claude --version https://www.tapd.cn/43100420/markdown_wikis/show/#1143100420001007544 export ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic export ANTHROPIC_AUTH_TOKEN=\u0026#34;sk-e435fe4629934fc892c226fc26d7ac92\u0026#34; export ANTHROPIC_MODEL=deepseek-v4-pro[1m] export ANTHROPIC_DEFAULT_OPUS_MODEL=deepseek-v4-pro[1m] export ANTHROPIC_DEFAULT_SONNET_MODEL=deepseek-v4-pro[1m] export ANTHROPIC_DEFAULT_HAIKU_MODEL=deepseek-v4-flash export CLAUDE_CODE_SUBAGENT_MODEL=deepseek-v4-flash export CLAUDE_CODE_EFFORT_LEVEL=max # 内网 export ANTHROPIC_BASE_URL=http://172.16.99.137:8081 export ANTHROPIC_AUTH_TOKEN=sk-q49Joop5Yz2BuS1ZPBPWJuCvwnS5elwKy9nP7PaLSi6fWrdy export ANTHROPIC_MODEL=deepseek-v4-pro[1m] export ANTHROPIC_DEFAULT_OPUS_MODEL=deepseek-v4-pro[1m] export ANTHROPIC_DEFAULT_SONNET_MODEL=deepseek-v4-pro[1m] export ANTHROPIC_DEFAULT_HAIKU_MODEL=deepseek-v4-flash export CLAUDE_CODE_SUBAGENT_MODEL=deepseek-v4-flash export CLAUDE_CODE_EFFORT_LEVEL=max # 内网 glm export ANTHROPIC_BASE_URL=http://172.16.99.137:8081 export ANTHROPIC_AUTH_TOKEN=sk-q49Joop5Yz2BuS1ZPBPWJuCvwnS5elwKy9nP7PaLSi6fWrdy export ANTHROPIC_MODEL=glm-5.2 export ANTHROPIC_DEFAULT_OPUS_MODEL=glm-5.2 export ANTHROPIC_DEFAULT_SONNET_MODEL=glm-5.2 export ANTHROPIC_DEFAULT_HAIKU_MODEL=glm-5 export CLAUDE_CODE_SUBAGENT_MODEL=glm-5 export CLAUDE_CODE_EFFORT_LEVEL=max # 外网： http://172.16.105.104:3000 $env:ANTHROPIC_BASE_URL = \u0026#34;https://api.deepseek.com/anthropic\u0026#34; $env:ANTHROPIC_AUTH_TOKEN = \u0026#34;sk-e435fe4629934fc892c226fc26d7ac92\u0026#34; $env:ANTHROPIC_MODEL = \u0026#34;deepseek-v4-flash\u0026#34; $env:ANTHROPIC_DEFAULT_OPUS_MODEL = \u0026#34;deepseek-v4-flash\u0026#34; $env:ANTHROPIC_DEFAULT_SONNET_MODEL = \u0026#34;deepseek-v4-flash\u0026#34; $env:ANTHROPIC_DEFAULT_HAIKU_MODEL = \u0026#34;deepseek-v4-flash\u0026#34; $env:CLAUDE_CODE_SUBAGENT_MODEL = \u0026#34;deepseek-v4-flash\u0026#34; $env:CLAUDE_CODE_EFFORT_LEVEL = \u0026#34;max\u0026#34; # 外网 海量 $env:ANTHROPIC_BASE_URL = \u0026#34;http://172.16.105.104:3000\u0026#34; $env:ANTHROPIC_AUTH_TOKEN = \u0026#34;sk-q49Joop5Yz2BuS1ZPBPWJuCvwnS5elwKy9nP7PaLSi6fWrdy\u0026#34; $env:ANTHROPIC_MODEL = \u0026#34;glm-5.2\u0026#34; $env:ANTHROPIC_DEFAULT_OPUS_MODEL = \u0026#34;glm-5.2\u0026#34; $env:ANTHROPIC_DEFAULT_SONNET_MODEL = \u0026#34;glm-5.2\u0026#34; $env:ANTHROPIC_DEFAULT_HAIKU_MODEL = \u0026#34;glm-5\u0026#34; $env:CLAUDE_CODE_SUBAGENT_MODEL = \u0026#34;glm-5\u0026#34; $env:CLAUDE_CODE_EFFORT_LEVEL = \u0026#34;max\u0026#34; export ANTHROPIC_BASE_URL=http://172.16.105.104:3000 export ANTHROPIC_AUTH_TOKEN=sk-q49Joop5Yz2BuS1ZPBPWJuCvwnS5elwKy9nP7PaLSi6fWrdy export ANTHROPIC_MODEL=glm-5.2 export ANTHROPIC_DEFAULT_OPUS_MODEL=glm-5.2 export ANTHROPIC_DEFAULT_SONNET_MODEL=glm-5.2 export ANTHROPIC_DEFAULT_HAIKU_MODEL=glm-5 export CLAUDE_CODE_SUBAGENT_MODEL=glm-5 export CLAUDE_CODE_EFFORT_LEVEL=max # 外网 海量 $env:ANTHROPIC_BASE_URL = \u0026#34;http://172.16.105.104:3000\u0026#34; $env:ANTHROPIC_AUTH_TOKEN = \u0026#34;sk-q49Joop5Yz2BuS1ZPBPWJuCvwnS5elwKy9nP7PaLSi6fWrdy\u0026#34; $env:ANTHROPIC_MODEL = \u0026#34;deepseek-v4-flash\u0026#34; $env:ANTHROPIC_DEFAULT_OPUS_MODEL = \u0026#34;deepseek-v4-flash\u0026#34; $env:ANTHROPIC_DEFAULT_SONNET_MODEL = \u0026#34;deepseek-v4-flash\u0026#34; $env:ANTHROPIC_DEFAULT_HAIKU_MODEL = \u0026#34;deepseek-v4-flash\u0026#34; $env:CLAUDE_CODE_SUBAGENT_MODEL = \u0026#34;deepseek-v4-flash\u0026#34; $env:CLAUDE_CODE_EFFORT_LEVEL = \u0026#34;max\u0026#34; export ANTHROPIC_BASE_URL=http://172.16.105.104:3000 export ANTHROPIC_AUTH_TOKEN=sk-q49Joop5Yz2BuS1ZPBPWJuCvwnS5elwKy9nP7PaLSi6fWrdy export ANTHROPIC_MODEL=deepseek-v4-pro[1m] export ANTHROPIC_DEFAULT_OPUS_MODEL=deepseek-v4-pro[1m] export ANTHROPIC_DEFAULT_SONNET_MODEL=deepseek-v4-pro[1m] export ANTHROPIC_DEFAULT_HAIKU_MODEL=deepseek-v4-flash export CLAUDE_CODE_SUBAGENT_MODEL=deepseek-v4-flash export CLAUDE_CODE_EFFORT_LEVEL=max [System.Environment]::SetEnvironmentVariable(\u0026#34;ANTHROPIC_BASE_URL\u0026#34;, \u0026#34;https://api.deepseek.com/anthropic\u0026#34;, \u0026#34;User\u0026#34;) [System.Environment]::SetEnvironmentVariable(\u0026#34;ANTHROPIC_AUTH_TOKEN\u0026#34;, \u0026#34;sk-e435fe4629934fc892c226fc26d7ac92\u0026#34;, \u0026#34;User\u0026#34;) [System.Environment]::SetEnvironmentVariable(\u0026#34;ANTHROPIC_MODEL\u0026#34;, \u0026#34;deepseek-v4-pro[1m]\u0026#34;, \u0026#34;User\u0026#34;) [System.Environment]::SetEnvironmentVariable(\u0026#34;ANTHROPIC_DEFAULT_OPUS_MODEL\u0026#34;, \u0026#34;deepseek-v4-pro[1m]\u0026#34;, \u0026#34;User\u0026#34;) [System.Environment]::SetEnvironmentVariable(\u0026#34;ANTHROPIC_DEFAULT_SONNET_MODEL\u0026#34;, \u0026#34;deepseek-v4-pro[1m]\u0026#34;, \u0026#34;User\u0026#34;) [System.Environment]::SetEnvironmentVariable(\u0026#34;ANTHROPIC_DEFAULT_HAIKU_MODEL\u0026#34;, \u0026#34;deepseek-v4-flash\u0026#34;, \u0026#34;User\u0026#34;) [System.Environment]::SetEnvironmentVariable(\u0026#34;CLAUDE_CODE_SUBAGENT_MODEL\u0026#34;, \u0026#34;deepseek-v4-flash\u0026#34;, \u0026#34;User\u0026#34;) [System.Environment]::SetEnvironmentVariable(\u0026#34;CLAUDE_CODE_EFFORT_LEVEL\u0026#34;, \u0026#34;max\u0026#34;, \u0026#34;User\u0026#34;) # 安装nodejs yum install -y nodejs mkdir ~/.npm-global npm config set prefix \u0026#39;~/.npm-global\u0026#39; echo \u0026#39;export PATH=~/.npm-global/bin:$PATH\u0026#39; \u0026gt;\u0026gt; ~/.bashrc source ~/.bashrc # 安装claude npm install -g @anthropic-ai/claude-code # 验证 claude --version cd /data/postgresql17 # 5. 启动 Claude Code 并进行首次认证 # 运行后，终端会提供一个链接，在浏览器中完成账号授权即可 claude # 6. (可选但推荐) 生成项目记忆文件 # 在 Claude 交互界面中，输入以下命令，它会分析项目并生成 CLAUDE.md 文件 /init # linux 使用代理 curl -L https://github.com/MetaCubeX/mihomo/releases/latest/download/mihomo-linux-amd64-compatible.gz | gunzip \u0026gt; /usr/local/bin/mihomo chmod +x /usr/local/bin/mihomo mkdir -p /etc/clash curl -o /etc/clash/config.yaml http://43.135.139.219:9999/clash.yaml # 3. 启动 Clash nohup mihomo -f /etc/clash/config.yaml \u0026gt; /var/log/clash.log 2\u0026gt;\u0026amp;1 \u0026amp; # 4. 设置代理环境变量（Clash 默认 mixed-port 7890） export http_proxy=http://127.0.0.1:7890 export https_proxy=http://127.0.0.1:7890 # 5. 测试 curl -I https://www.google.com git config --global user.name \u0026#34;shenkun\u0026#34; git config --global user.email \u0026#34;shenkun@bupt.cn\u0026#34; ssh-keygen -t rsa -C \u0026#34;shenkun@bupt.cn\u0026#34; cat ~/.ssh/id_rsa yum install proxychains-ng -y echo \u0026#34;socks5 10.255.255.254 1080\u0026#34; \u0026gt;\u0026gt; /etc/proxychains.conf # windows11 安装clash https://github.com/clash-verge-rev/clash-verge-rev/releases yum install -y shadowsocks-libev cat \u0026gt; /etc/shadowsocks-libev/client.json \u0026lt;\u0026lt; \u0026#39;EOF\u0026#39; { \u0026#34;server\u0026#34;: \u0026#34;43.135.139.219\u0026#34;, \u0026#34;server_port\u0026#34;: 443, \u0026#34;local_address\u0026#34;: \u0026#34;127.0.0.1\u0026#34;, \u0026#34;local_port\u0026#34;: 1080, \u0026#34;password\u0026#34;: \u0026#34;gauss@123\u0026#34;, \u0026#34;method\u0026#34;: \u0026#34;aes-256-gcm\u0026#34; } EOF ss-local -c /etc/shadowsocks-libev/client.json -f /var/run/ss-local.pid export https_proxy=socks5://127.0.0.1:1080 # githup 使用 # 启动 claude claude --resume # 恢复最近一次对话 claude --continue # 继续上一次对话 claude --model \u0026lt;name\u0026gt; # 指定模型 claude --dangerously-skip-permissions # 跳过所有权限确认 claude update # 命令 /clear # 清楚所有对话 /compact # 压缩上下文，保留摘要 /rewind # 回滚上一次对话 /memory # 编辑记忆文件，记住偏好 /resume # 恢复历史会话 /context # 显示上下文窗口使用量 # 项目 /init 初始化项目，生成CLAUDE.md /review # 代码审查 /commit # 提交 # 环境 /config # 调整主题、模型等 /model [name] # 切换模型 /permissions # 工具权限白名单 /doctor # 检查环境 /mcp /cost # token用量和费用 /usage # 扩展 /skill /自定义skill # 快捷键 | 快捷键 | 功能 | | :--- | :--- | | `Shift + Tab` | 循环切换三种模式：计划模式 → 默认模式 → 自动编辑模式 | | `!command` | 直接在终端执行 bash 命令（不发给 AI） | | `Ctrl + B` | 将阻塞的进程放到后台，继续对话 | | `Esc Esc` | 双击 Esc 等同于 `/rewind` 回滚 | | `Ctrl + V` | 粘贴图片到对话框 | | `Option/Ctrl + Enter` | 输入框换行（Enter 是直接发送） | 模型名称 厂商 发布时间 核心亮点（精简） 定位/优势场景 GPT-5.6 (Sol/Terra/Luna) OpenAI 2026.07.09 7月9日刚全球开放；三档分层+速度拨盘；Codex与ChatGPT合一 全能旗舰、超级智能体 GPT-5.5 OpenAI 2026.04.24 首个从零重训基础模型；100万tokens；MoE+Verifier架构 真实工作流、编程调试 DeepSeek-V4 (Pro/Flash) 深度求索 2026.04.24 万亿参数MoE开源；百万token原生上下文；成本仅OpenAI 1/100 开源性价比之王、Agent Qwen3.7-Max 阿里巴巴 2026.05.20 国产Arena盲测第一；全域思考模式；Agentic Coding全球前三 国产旗舰、智能体编程 Claude Opus 4.7/4.8 Anthropic 2026 Q2 代码质量最优；长文本推理首选；WebDev Arena排名第一 编程审校、深度推理 Gemini 3.5 Pro Google 2026.06 Artificial Analysis智能指数登顶；集成计算机使用(CU)能力 复杂推理、多模态科研 Grok 4 / 4.5 xAI 2026.05-07 实时接入X平台；编码与Agent能力持续强化；百亿~千亿参数 实时信息、社交分析 Kimi-K2.6 月之暗面 2026 H1 长文本办公统治级；JSON输出稳定；指令遵循能力强 办公自动化、Agent GLM-5.1 智谱AI 2026 Q2 国产第一梯队；编程能力进入Top7；综合能力稳居前列 通用对话、编程辅助 豆包 2.1 Pro 字节跳动 2026.06 中文口语最自然；移动端交互最佳；多模态细节强 C端用户、内容创作 Meta Muse Spark 1.1 Meta 2026.07 首次开放Model API；正面争夺企业开发者市场 企业开发、开源生态 Llama 4 Meta 2026(预计) 开源生态标杆；多模态原生；社区微调最丰富 开源基座、定制微调 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/claude/","summary":"\u003ch1 id=\"安装\"\u003e安装\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ewget https://unofficial-builds.nodejs.org/download/release/v20.18.1/node-v20.18.1-linux-x64-glibc-217.tar.xz\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etar -Jxvf node-v20.18.1-linux-x64-glibc-217.tar.xz\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emv node-v20.18.1-linux-x64-glibc-217 node-20\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etouch envn\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport NODEHOME=`pwd`/node-20\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PATH=$NODEHOME/bin:$PATH\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport LD_LIBRARY_PATH=$NODEHOME/lib:$LD_LIBRARY_PATH\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u003c/span\u003e \u0026gt; envn\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003esource\u003c/span\u003e envn\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir npm-global\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enpm config \u003cspan class=\"nb\"\u003eset\u003c/span\u003e prefix \u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e/npm-global\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enpm config \u003cspan class=\"nb\"\u003eset\u003c/span\u003e prefix \u003cspan class=\"nv\"\u003e$NODEHOME\u003c/span\u003e/npm-global\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;export PATH=$NODEHOME/../npm-global/bin:$PATH\u0026#39;\u003c/span\u003e \u0026gt;\u0026gt; envn\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003esource\u003c/span\u003e envn\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enpm pack @anthropic-ai/claude-code\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enpm install -g ./anthropic-ai-claude-code-2.1.162.tgz\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eclaude --version\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ehttps://www.tapd.cn/43100420/markdown_wikis/show/#1143100420001007544\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_BASE_URL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003ehttps://api.deepseek.com/anthropic\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_AUTH_TOKEN\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;sk-e435fe4629934fc892c226fc26d7ac92\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003edeepseek-v4-pro\u003cspan class=\"o\"\u003e[\u003c/span\u003e1m\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_DEFAULT_OPUS_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003edeepseek-v4-pro\u003cspan class=\"o\"\u003e[\u003c/span\u003e1m\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_DEFAULT_SONNET_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003edeepseek-v4-pro\u003cspan class=\"o\"\u003e[\u003c/span\u003e1m\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_DEFAULT_HAIKU_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003edeepseek-v4-flash\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCLAUDE_CODE_SUBAGENT_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003edeepseek-v4-flash\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCLAUDE_CODE_EFFORT_LEVEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003emax\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 内网\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_BASE_URL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003ehttp://172.16.99.137:8081\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_AUTH_TOKEN\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003esk-q49Joop5Yz2BuS1ZPBPWJuCvwnS5elwKy9nP7PaLSi6fWrdy\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003edeepseek-v4-pro\u003cspan class=\"o\"\u003e[\u003c/span\u003e1m\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_DEFAULT_OPUS_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003edeepseek-v4-pro\u003cspan class=\"o\"\u003e[\u003c/span\u003e1m\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_DEFAULT_SONNET_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003edeepseek-v4-pro\u003cspan class=\"o\"\u003e[\u003c/span\u003e1m\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_DEFAULT_HAIKU_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003edeepseek-v4-flash\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCLAUDE_CODE_SUBAGENT_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003edeepseek-v4-flash\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCLAUDE_CODE_EFFORT_LEVEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003emax\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 内网 glm\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_BASE_URL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003ehttp://172.16.99.137:8081\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_AUTH_TOKEN\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003esk-q49Joop5Yz2BuS1ZPBPWJuCvwnS5elwKy9nP7PaLSi6fWrdy\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003eglm-5.2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_DEFAULT_OPUS_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003eglm-5.2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_DEFAULT_SONNET_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003eglm-5.2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_DEFAULT_HAIKU_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003eglm-5\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCLAUDE_CODE_SUBAGENT_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003eglm-5\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCLAUDE_CODE_EFFORT_LEVEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003emax\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 外网： http://172.16.105.104:3000\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_BASE_URL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;https://api.deepseek.com/anthropic\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_AUTH_TOKEN \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;sk-e435fe4629934fc892c226fc26d7ac92\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_MODEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;deepseek-v4-flash\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_DEFAULT_OPUS_MODEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;deepseek-v4-flash\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_DEFAULT_SONNET_MODEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;deepseek-v4-flash\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_DEFAULT_HAIKU_MODEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;deepseek-v4-flash\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:CLAUDE_CODE_SUBAGENT_MODEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;deepseek-v4-flash\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:CLAUDE_CODE_EFFORT_LEVEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;max\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 外网 海量\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_BASE_URL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;http://172.16.105.104:3000\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_AUTH_TOKEN \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;sk-q49Joop5Yz2BuS1ZPBPWJuCvwnS5elwKy9nP7PaLSi6fWrdy\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_MODEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;glm-5.2\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_DEFAULT_OPUS_MODEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;glm-5.2\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_DEFAULT_SONNET_MODEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;glm-5.2\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_DEFAULT_HAIKU_MODEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;glm-5\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:CLAUDE_CODE_SUBAGENT_MODEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;glm-5\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:CLAUDE_CODE_EFFORT_LEVEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;max\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_BASE_URL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003ehttp://172.16.105.104:3000\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_AUTH_TOKEN\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003esk-q49Joop5Yz2BuS1ZPBPWJuCvwnS5elwKy9nP7PaLSi6fWrdy\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003eglm-5.2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_DEFAULT_OPUS_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003eglm-5.2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_DEFAULT_SONNET_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003eglm-5.2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_DEFAULT_HAIKU_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003eglm-5\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCLAUDE_CODE_SUBAGENT_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003eglm-5\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCLAUDE_CODE_EFFORT_LEVEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003emax\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 外网 海量\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_BASE_URL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;http://172.16.105.104:3000\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_AUTH_TOKEN \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;sk-q49Joop5Yz2BuS1ZPBPWJuCvwnS5elwKy9nP7PaLSi6fWrdy\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_MODEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;deepseek-v4-flash\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_DEFAULT_OPUS_MODEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;deepseek-v4-flash\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_DEFAULT_SONNET_MODEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;deepseek-v4-flash\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:ANTHROPIC_DEFAULT_HAIKU_MODEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;deepseek-v4-flash\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:CLAUDE_CODE_SUBAGENT_MODEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;deepseek-v4-flash\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$env\u003c/span\u003e:CLAUDE_CODE_EFFORT_LEVEL \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;max\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_BASE_URL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003ehttp://172.16.105.104:3000\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_AUTH_TOKEN\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003esk-q49Joop5Yz2BuS1ZPBPWJuCvwnS5elwKy9nP7PaLSi6fWrdy\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003edeepseek-v4-pro\u003cspan class=\"o\"\u003e[\u003c/span\u003e1m\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_DEFAULT_OPUS_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003edeepseek-v4-pro\u003cspan class=\"o\"\u003e[\u003c/span\u003e1m\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_DEFAULT_SONNET_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003edeepseek-v4-pro\u003cspan class=\"o\"\u003e[\u003c/span\u003e1m\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eANTHROPIC_DEFAULT_HAIKU_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003edeepseek-v4-flash\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCLAUDE_CODE_SUBAGENT_MODEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003edeepseek-v4-flash\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCLAUDE_CODE_EFFORT_LEVEL\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003emax\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e[\u003c/span\u003eSystem.Environment\u003cspan class=\"o\"\u003e]\u003c/span\u003e::SetEnvironmentVariable\u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;ANTHROPIC_BASE_URL\u0026#34;\u003c/span\u003e, \u003cspan class=\"s2\"\u003e\u0026#34;https://api.deepseek.com/anthropic\u0026#34;\u003c/span\u003e, \u003cspan class=\"s2\"\u003e\u0026#34;User\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e[\u003c/span\u003eSystem.Environment\u003cspan class=\"o\"\u003e]\u003c/span\u003e::SetEnvironmentVariable\u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;ANTHROPIC_AUTH_TOKEN\u0026#34;\u003c/span\u003e, \u003cspan class=\"s2\"\u003e\u0026#34;sk-e435fe4629934fc892c226fc26d7ac92\u0026#34;\u003c/span\u003e, \u003cspan class=\"s2\"\u003e\u0026#34;User\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e[\u003c/span\u003eSystem.Environment\u003cspan class=\"o\"\u003e]\u003c/span\u003e::SetEnvironmentVariable\u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;ANTHROPIC_MODEL\u0026#34;\u003c/span\u003e, \u003cspan class=\"s2\"\u003e\u0026#34;deepseek-v4-pro[1m]\u0026#34;\u003c/span\u003e, \u003cspan class=\"s2\"\u003e\u0026#34;User\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e[\u003c/span\u003eSystem.Environment\u003cspan class=\"o\"\u003e]\u003c/span\u003e::SetEnvironmentVariable\u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;ANTHROPIC_DEFAULT_OPUS_MODEL\u0026#34;\u003c/span\u003e, \u003cspan class=\"s2\"\u003e\u0026#34;deepseek-v4-pro[1m]\u0026#34;\u003c/span\u003e, \u003cspan class=\"s2\"\u003e\u0026#34;User\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e[\u003c/span\u003eSystem.Environment\u003cspan class=\"o\"\u003e]\u003c/span\u003e::SetEnvironmentVariable\u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;ANTHROPIC_DEFAULT_SONNET_MODEL\u0026#34;\u003c/span\u003e, \u003cspan class=\"s2\"\u003e\u0026#34;deepseek-v4-pro[1m]\u0026#34;\u003c/span\u003e, \u003cspan class=\"s2\"\u003e\u0026#34;User\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e[\u003c/span\u003eSystem.Environment\u003cspan class=\"o\"\u003e]\u003c/span\u003e::SetEnvironmentVariable\u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;ANTHROPIC_DEFAULT_HAIKU_MODEL\u0026#34;\u003c/span\u003e, \u003cspan class=\"s2\"\u003e\u0026#34;deepseek-v4-flash\u0026#34;\u003c/span\u003e, \u003cspan class=\"s2\"\u003e\u0026#34;User\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e[\u003c/span\u003eSystem.Environment\u003cspan class=\"o\"\u003e]\u003c/span\u003e::SetEnvironmentVariable\u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;CLAUDE_CODE_SUBAGENT_MODEL\u0026#34;\u003c/span\u003e, \u003cspan class=\"s2\"\u003e\u0026#34;deepseek-v4-flash\u0026#34;\u003c/span\u003e, \u003cspan class=\"s2\"\u003e\u0026#34;User\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e[\u003c/span\u003eSystem.Environment\u003cspan class=\"o\"\u003e]\u003c/span\u003e::SetEnvironmentVariable\u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;CLAUDE_CODE_EFFORT_LEVEL\u0026#34;\u003c/span\u003e, \u003cspan class=\"s2\"\u003e\u0026#34;max\u0026#34;\u003c/span\u003e, \u003cspan class=\"s2\"\u003e\u0026#34;User\u0026#34;\u003c/span\u003e\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 安装nodejs\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eyum install -y nodejs\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir ~/.npm-global\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enpm config \u003cspan class=\"nb\"\u003eset\u003c/span\u003e prefix \u003cspan class=\"s1\"\u003e\u0026#39;~/.npm-global\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;export PATH=~/.npm-global/bin:$PATH\u0026#39;\u003c/span\u003e \u0026gt;\u0026gt; ~/.bashrc\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003esource\u003c/span\u003e ~/.bashrc\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 安装claude\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enpm install -g @anthropic-ai/claude-code\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 验证\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eclaude --version\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e /data/postgresql17\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 5. 启动 Claude Code 并进行首次认证\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 运行后，终端会提供一个链接，在浏览器中完成账号授权即可\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eclaude\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 6. (可选但推荐) 生成项目记忆文件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 在 Claude 交互界面中，输入以下命令，它会分析项目并生成 CLAUDE.md 文件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/init\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# linux 使用代理\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecurl -L https://github.com/MetaCubeX/mihomo/releases/latest/download/mihomo-linux-amd64-compatible.gz \u003cspan class=\"p\"\u003e|\u003c/span\u003e gunzip \u0026gt; /usr/local/bin/mihomo\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod +x /usr/local/bin/mihomo\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir -p /etc/clash\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecurl -o /etc/clash/config.yaml http://43.135.139.219:9999/clash.yaml\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 3. 启动 Clash\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enohup mihomo -f /etc/clash/config.yaml \u0026gt; /var/log/clash.log 2\u0026gt;\u003cspan class=\"p\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e \u003cspan class=\"p\"\u003e\u0026amp;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 4. 设置代理环境变量（Clash 默认 mixed-port 7890）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003ehttp_proxy\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003ehttp://127.0.0.1:7890\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003ehttps_proxy\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003ehttp://127.0.0.1:7890\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 5. 测试\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecurl -I https://www.google.com\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit config --global user.name \u003cspan class=\"s2\"\u003e\u0026#34;shenkun\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit config --global user.email \u003cspan class=\"s2\"\u003e\u0026#34;shenkun@bupt.cn\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003essh-keygen -t rsa -C \u003cspan class=\"s2\"\u003e\u0026#34;shenkun@bupt.cn\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecat ~/.ssh/id_rsa\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eyum install proxychains-ng -y\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;socks5  10.255.255.254  1080\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; /etc/proxychains.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# windows11 安装clash\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ehttps://github.com/clash-verge-rev/clash-verge-rev/releases\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eyum install -y shadowsocks-libev\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecat \u0026gt; /etc/shadowsocks-libev/client.json \u003cspan class=\"s\"\u003e\u0026lt;\u0026lt; \u0026#39;EOF\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e{\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\u0026#34;server\u0026#34;: \u0026#34;43.135.139.219\u0026#34;,\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\u0026#34;server_port\u0026#34;: 443,\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\u0026#34;local_address\u0026#34;: \u0026#34;127.0.0.1\u0026#34;,\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\u0026#34;local_port\u0026#34;: 1080,\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\u0026#34;password\u0026#34;: \u0026#34;gauss@123\u0026#34;,\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\u0026#34;method\u0026#34;: \u0026#34;aes-256-gcm\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e}\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eEOF\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ess-local -c /etc/shadowsocks-libev/client.json -f /var/run/ss-local.pid\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003ehttps_proxy\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003esocks5://127.0.0.1:1080\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# githup\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"使用\"\u003e使用\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 启动\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eclaude\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eclaude --resume \u003cspan class=\"c1\"\u003e# 恢复最近一次对话\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eclaude --continue \u003cspan class=\"c1\"\u003e# 继续上一次对话\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eclaude --model \u0026lt;name\u0026gt; \u003cspan class=\"c1\"\u003e# 指定模型\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eclaude --dangerously-skip-permissions \u003cspan class=\"c1\"\u003e# 跳过所有权限确认\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eclaude update\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 命令\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/clear \u003cspan class=\"c1\"\u003e# 清楚所有对话\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/compact \u003cspan class=\"c1\"\u003e# 压缩上下文，保留摘要\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/rewind \u003cspan class=\"c1\"\u003e# 回滚上一次对话\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/memory \u003cspan class=\"c1\"\u003e# 编辑记忆文件，记住偏好\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/resume \u003cspan class=\"c1\"\u003e# 恢复历史会话\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/context \u003cspan class=\"c1\"\u003e# 显示上下文窗口使用量\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 项目\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/init 初始化项目，生成CLAUDE.md\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/review \u003cspan class=\"c1\"\u003e# 代码审查\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/commit \u003cspan class=\"c1\"\u003e# 提交\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 环境\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/config \u003cspan class=\"c1\"\u003e# 调整主题、模型等\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/model \u003cspan class=\"o\"\u003e[\u003c/span\u003ename\u003cspan class=\"o\"\u003e]\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 切换模型\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/permissions \u003cspan class=\"c1\"\u003e# 工具权限白名单\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/doctor \u003cspan class=\"c1\"\u003e# 检查环境\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/mcp\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/cost \u003cspan class=\"c1\"\u003e# token用量和费用\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/usage\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 扩展\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/skill\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/自定义skill\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 快捷键\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 快捷键 \u003cspan class=\"p\"\u003e|\u003c/span\u003e 功能 \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e :--- \u003cspan class=\"p\"\u003e|\u003c/span\u003e :--- \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"sb\"\u003e`\u003c/span\u003eShift + Tab\u003cspan class=\"sb\"\u003e`\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e 循环切换三种模式：计划模式 → 默认模式 → 自动编辑模式 \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"sb\"\u003e`\u003c/span\u003e!command\u003cspan class=\"sb\"\u003e`\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e 直接在终端执行 bash 命令（不发给 AI） \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"sb\"\u003e`\u003c/span\u003eCtrl + B\u003cspan class=\"sb\"\u003e`\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e 将阻塞的进程放到后台，继续对话 \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"sb\"\u003e`\u003c/span\u003eEsc Esc\u003cspan class=\"sb\"\u003e`\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e 双击 Esc 等同于 \u003cspan class=\"sb\"\u003e`\u003c/span\u003e/rewind\u003cspan class=\"sb\"\u003e`\u003c/span\u003e 回滚 \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"sb\"\u003e`\u003c/span\u003eCtrl + V\u003cspan class=\"sb\"\u003e`\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e 粘贴图片到对话框 \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e \u003cspan class=\"sb\"\u003e`\u003c/span\u003eOption/Ctrl + Enter\u003cspan class=\"sb\"\u003e`\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e 输入框换行（Enter 是直接发送） \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth style=\"text-align: left\"\u003e模型名称\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e厂商\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e发布时间\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e核心亮点（精简）\u003c/th\u003e\n          \u003cth style=\"text-align: left\"\u003e定位/优势场景\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003eGPT-5.6 (Sol/Terra/Luna)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eOpenAI\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e2026.07.09\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e7月9日刚全球开放；三档分层+速度拨盘；Codex与ChatGPT合一\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e全能旗舰、超级智能体\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003eGPT-5.5\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eOpenAI\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e2026.04.24\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e首个从零重训基础模型；100万tokens；MoE+Verifier架构\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e真实工作流、编程调试\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003eDeepSeek-V4 (Pro/Flash)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e深度求索\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e2026.04.24\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e万亿参数MoE开源；百万token原生上下文；成本仅OpenAI 1/100\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e开源性价比之王、Agent\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003eQwen3.7-Max\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e阿里巴巴\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e2026.05.20\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e国产Arena盲测第一；全域思考模式；Agentic Coding全球前三\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e国产旗舰、智能体编程\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003eClaude Opus 4.7/4.8\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eAnthropic\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e2026 Q2\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e代码质量最优；长文本推理首选；WebDev Arena排名第一\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e编程审校、深度推理\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003eGemini 3.5 Pro\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eGoogle\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e2026.06\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eArtificial Analysis智能指数登顶；集成计算机使用(CU)能力\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e复杂推理、多模态科研\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003eGrok 4 / 4.5\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003exAI\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e2026.05-07\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e实时接入X平台；编码与Agent能力持续强化；百亿~千亿参数\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e实时信息、社交分析\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003eKimi-K2.6\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e月之暗面\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e2026 H1\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e长文本办公统治级；JSON输出稳定；指令遵循能力强\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e办公自动化、Agent\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003eGLM-5.1\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e智谱AI\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e2026 Q2\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e国产第一梯队；编程能力进入Top7；综合能力稳居前列\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e通用对话、编程辅助\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e豆包 2.1 Pro\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e字节跳动\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e2026.06\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e中文口语最自然；移动端交互最佳；多模态细节强\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eC端用户、内容创作\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003eMeta Muse Spark 1.1\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eMeta\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e2026.07\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e首次开放Model API；正面争夺企业开发者市场\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e企业开发、开源生态\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003eLlama 4\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003eMeta\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e2026(预计)\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e开源生态标杆；多模态原生；社区微调最丰富\u003c/td\u003e\n          \u003ctd style=\"text-align: left\"\u003e开源基座、定制微调\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e","title":"claude"},{"content":"目录 目录 1 架构 1.1 整体架构 2 流程 2.1 整体流程 3 设计 3.1 驱动加密 3.2 机密计算 一、技术调研 二、方案对比 4 接口 5 实现 1 架构 1.1 整体架构 全密态数据库是一种由数据库提供的安全特性，指数据库在处理数据的过程中，确保数据在传输、计算、存储等全生命周期阶段，于任何不可信的介质或环境中，始终处于加密状态。不可信环境包括：网络、内存、磁盘等。以常见的拓扑模型为例，在使用数据库的过程中，威胁面较广：\n全密态数据库中，对于传输、存储安全，采用驱动加密方案。应用向数据库发送数据时，先在驱动中加密数据，再发送数据密文。应用从数据库接收数据时，先接收数据密文，再在驱动中解密数据。数据在网络、磁盘、服务端内存中，均处于加密状态。基本架构如下图所示：\n全密态数据库中，对于计算安全，采用机密计算方案。驱动加密方案，解决传输、存储安全，但是，数据库端无法在密文上计算。为解决计算问题，业界有两种方案：\n基于密码学算法的密文计算方案：通过密码学算法，让数据库在直接在密文上进行计算，例如保序加密、可搜索加密、同态加密等 基于硬件隔离的机密计算方案：在CPU、内存中，划分逻辑独立的可信执行环境，让数据库在可信执行环境中解密数据密文，进行计算。 在充分对比安全性、功能完备性、性能、实现难度等特点，选择机密计算方案。结合驱动加密方案、机密计算方案，全密态数据库整体架构如下图所示：\n全密态数据库中，对于加密模型，采用多级密钥方案。数据由数据密钥加密，密钥由主密钥加密，主密钥由根密钥加密。在驱动加密模块中，只能获取数据密钥，无法获取主密钥。在更安全的加密方案中，驱动加密模块无法获取数据密钥，由硬件加密机加密。在数据库端，仅存储密钥信息，无法获取密钥。全密态数据库加密模型如下图所示：\n2 流程 2.1 整体流程 使用全密态数据库时，用户需定义主密钥、数据密钥、加密表，在执行存储、查询数据时，全密态数据库自动完成加密、解密、计算等操作。完整的使用流程如图所示：\n3 设计 3.1 驱动加密 3.2 机密计算 一、技术调研 纯软路线\n同态加密 软硬路线\nx86 cpu sgx：硬件 tdx：硬件 固件 me：出厂自带 软件 sgx driver amd cpu sev：Secure Encrypted Virtualization，CPU扩展电路，为每台虚拟机分配内存密钥，运行时加密整段内存。需BIOS开启。 sev-snp/sev-es 固件 psp 软件 kvm sev arm cpu trust-zone：每个核新增总线， 固件 arm trusted fimware 软件 op-tee tee: https://github.com/OP-TEE/build\n二、方案对比 4 接口 5 实现 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/confidential-computing/","summary":"\u003ch1 id=\"目录\"\u003e目录\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E7%9B%AE%E5%BD%95\"\u003e目录\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-%E6%9E%B6%E6%9E%84\"\u003e1 架构\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-1-%E6%95%B4%E4%BD%93%E6%9E%B6%E6%9E%84\"\u003e1.1 整体架构\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-%E6%B5%81%E7%A8%8B\"\u003e2 流程\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#2-1-%E6%95%B4%E4%BD%93%E6%B5%81%E7%A8%8B\"\u003e2.1 整体流程\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-%E8%AE%BE%E8%AE%A1\"\u003e3 设计\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#3-1-%E9%A9%B1%E5%8A%A8%E5%8A%A0%E5%AF%86\"\u003e3.1 驱动加密\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-2-%E6%9C%BA%E5%AF%86%E8%AE%A1%E7%AE%97\"\u003e3.2 机密计算\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%80%E3%80%81%E6%8A%80%E6%9C%AF%E8%B0%83%E7%A0%94\"\u003e一、技术调研\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BA%8C%E3%80%81%E6%96%B9%E6%A1%88%E5%AF%B9%E6%AF%94\"\u003e二、方案对比\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-%E6%8E%A5%E5%8F%A3\"\u003e4 接口\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#5-%E5%AE%9E%E7%8E%B0\"\u003e5 实现\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"1-架构\"\u003e1 架构\u003c/h1\u003e\n\u003ch2 id=\"11-整体架构\"\u003e1.1 整体架构\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003e全密态数据库\u003c/strong\u003e是一种由数据库提供的安全特性，指数据库在处理数据的过程中，确保数据在传输、计算、存储等全生命周期阶段，于任何不可信的介质或环境中，始终处于加密状态。不可信环境包括：网络、内存、磁盘等。以常见的拓扑模型为例，在使用数据库的过程中，威胁面较广：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"risk\" loading=\"lazy\" src=\"/images/Security/confidential-computing/risk.png\"\u003e\u003c/p\u003e\n\u003cp\u003e全密态数据库中，对于传输、存储安全，采用驱动加密方案。应用向数据库发送数据时，先在驱动中加密数据，再发送数据密文。应用从数据库接收数据时，先接收数据密文，再在驱动中解密数据。数据在网络、磁盘、服务端内存中，均处于加密状态。基本架构如下图所示：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"driver\" loading=\"lazy\" src=\"/images/Security/confidential-computing/driver.png\"\u003e\u003c/p\u003e\n\u003cp\u003e全密态数据库中，对于计算安全，采用机密计算方案。驱动加密方案，解决传输、存储安全，但是，数据库端无法在密文上计算。为解决计算问题，业界有两种方案：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e基于密码学算法的密文计算方案：通过密码学算法，让数据库在直接在密文上进行计算，例如保序加密、可搜索加密、同态加密等\u003c/li\u003e\n\u003cli\u003e基于硬件隔离的机密计算方案：在CPU、内存中，划分逻辑独立的可信执行环境，让数据库在可信执行环境中解密数据密文，进行计算。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e在充分对比安全性、功能完备性、性能、实现难度等特点，选择机密计算方案。结合驱动加密方案、机密计算方案，全密态数据库整体架构如下图所示：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"all\" loading=\"lazy\" src=\"/images/Security/confidential-computing/all.png\"\u003e\u003c/p\u003e\n\u003cp\u003e全密态数据库中，对于加密模型，采用多级密钥方案。数据由数据密钥加密，密钥由主密钥加密，主密钥由根密钥加密。在驱动加密模块中，只能获取数据密钥，无法获取主密钥。在更安全的加密方案中，驱动加密模块无法获取数据密钥，由硬件加密机加密。在数据库端，仅存储密钥信息，无法获取密钥。全密态数据库加密模型如下图所示：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"crypt\" loading=\"lazy\" src=\"/images/Security/confidential-computing/crypt.png\"\u003e\u003c/p\u003e\n\u003ch1 id=\"2-流程\"\u003e2 流程\u003c/h1\u003e\n\u003ch2 id=\"21-整体流程\"\u003e2.1 整体流程\u003c/h2\u003e\n\u003cp\u003e使用全密态数据库时，用户需定义主密钥、数据密钥、加密表，在执行存储、查询数据时，全密态数据库自动完成加密、解密、计算等操作。完整的使用流程如图所示：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"flow\" loading=\"lazy\" src=\"/images/Security/confidential-computing/flow.png\"\u003e\u003c/p\u003e\n\u003ch1 id=\"3-设计\"\u003e3 设计\u003c/h1\u003e\n\u003ch2 id=\"31-驱动加密\"\u003e3.1 驱动加密\u003c/h2\u003e\n\u003ch2 id=\"32-机密计算\"\u003e3.2 机密计算\u003c/h2\u003e\n\u003ch3 id=\"一技术调研\"\u003e一、技术调研\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e纯软路线\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e同态加密\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e软硬路线\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ex86\n\u003cul\u003e\n\u003cli\u003ecpu\n\u003cul\u003e\n\u003cli\u003esgx：硬件\u003c/li\u003e\n\u003cli\u003etdx：硬件\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e固件\n\u003cul\u003e\n\u003cli\u003eme：出厂自带\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e软件\n\u003cul\u003e\n\u003cli\u003esgx driver\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003eamd\n\u003cul\u003e\n\u003cli\u003ecpu\n\u003cul\u003e\n\u003cli\u003esev：Secure Encrypted Virtualization，CPU扩展电路，为每台虚拟机分配内存密钥，运行时加密整段内存。需BIOS开启。\u003c/li\u003e\n\u003cli\u003esev-snp/sev-es\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e固件\n\u003cul\u003e\n\u003cli\u003epsp\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e软件\n\u003cul\u003e\n\u003cli\u003ekvm sev\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003earm\n\u003cul\u003e\n\u003cli\u003ecpu\n\u003cul\u003e\n\u003cli\u003etrust-zone：每个核新增总线，\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e固件\n\u003cul\u003e\n\u003cli\u003earm trusted fimware\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e软件\n\u003cul\u003e\n\u003cli\u003eop-tee\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003etee: \u003ca href=\"https://github.com/OP-TEE/build\"\u003ehttps://github.com/OP-TEE/build\u003c/a\u003e\u003c/p\u003e","title":"高质量专项 全密态机密计算"},{"content":" 查看python安装路径\npython -c \u0026#34;import sys, os; print(os.path.dirname(sys.executable))\u0026#34; python下载pgk\npython -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/python/","summary":"\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e查看python安装路径\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epython -c \u003cspan class=\"s2\"\u003e\u0026#34;import sys, os; print(os.path.dirname(sys.executable))\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003epython下载pgk\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epython -m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple 包名\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ol\u003e","title":"工具 python"},{"content":"1 数据传输 1.1 传输场景 父子进程 陌生进程 1.2 传输接口 1.3 传输示例 2 并发控制 2.1 并发场景 整型 多写 一写多读 多写一读 多写多读 数据 多写 多读 一写多读 多写一读 多写多读 2.2 并发接口 (glibc) 一、自选锁 #include \u0026lt;pthread.h\u0026gt; pthread_spinlock_t spin; pthread_spin_init(\u0026amp;spin, PTHREAD_PROCESS_PRIVATE); pthread_spin_lock(\u0026amp;spin); pthread_spin_unlock(\u0026amp;spin); 二、互斥锁 #include \u0026lt;pthread.h\u0026gt; pthread_mutex_t lock; pthread_mutexattr_t attr; thread_mutexattr_init(\u0026amp;attr); pthread_mutexattr_settype(\u0026amp;attr, PTHREAD_MUTEX_NORMAL); pthread_mutex_init(\u0026amp;lock, \u0026amp;attr); pthread_mutex_lock(\u0026amp;lock); pthread_mutex_unlock(\u0026amp;lock); 三、读写锁 #include \u0026lt;pthread.h\u0026gt; pthread_mutex_t rdlock; pthread_mutexattr_t attr; pthread_rwlockattr_init(\u0026amp;attr); pthread_rwlockattr_setpshared(\u0026amp;attr, PTHREAD_PROCESS_SHARED); pthread_rwlock_init(\u0026amp;rdlock, \u0026amp;attr); pthread_rwlock_rdlock(\u0026amp;rdlock); pthread_rwlock_wrlock(\u0026amp;rdlock); pthread_rwlock_unlock(\u0026amp;rdlock); 四、信号量 #include \u0026lt;semaphore.h\u0026gt; sem_t sem; sem_init(\u0026amp;sem, 0, 8); sem_wait(\u0026amp;sem); sem_post(\u0026amp;sem); 五、原子写 #include \u0026lt;pthread.h\u0026gt;/* C 11 */ volatile unsigned num = 0; __atomic_store_n(\u0026amp;num, 8, __ATOMIC_SEQ_CST); unsigned cur = __atomic_load_n(\u0026amp;num, __ATOMIC_SEQ_CST); 2.3 并发代码 整型数据\n场景\n多写 一写多读 多写一读 多写多读 实现\n/* 自旋锁 */ void mul_write(int *num) { spin_lock() *num += 1; spin_unlock() } /* 原子变量 */ 数据\n多写\n/* 自旋锁 */ void mul_write(CommBuf *buf, Data *data) { spin_lock() memcpy(buf-\u0026gt;buf, data, data-\u0026gt;len) spin_unlock() } /* 排他锁 */ void mul_write(ommBuf *buf, Data *data) { spin_lock() memcpy(buf, data, ..) spin_unlock() } /* 信号量 */ /* 预申请：原子变量 */ 多读\n一写多读\n/* 自旋锁 */ /* 排他锁 */ /* 信号量 */ void mul_write(CommBuf *buf, Data *data) { spin_lock(buf-\u0026gt;spin) memcpy(buf-\u0026gt;buf, data, ..) spin_unlock(buf-\u0026gt;spin) sem_post(buf-\u0026gt;sem) } void read(CommBuf *buf, Data *data) { sem_wait(buf-\u0026gt;sem) // 计数器为0，阻塞 spin_lock(buf-\u0026gt;spin) memcpy(data, buf-\u0026gt;buf, ..) spin_unlock(buf-\u0026gt;spin) } 多写一读\n/* 自旋锁 */ /* 排他锁 */ /* 信号量 */ /* 预申请：原子变量 + 信号量 */ 多写多读\n/* 排他锁 */ /* 信号量 */ /* 预申请：原子变量 + 信号量 */ ","permalink":"https://my-blog.j8465383071.workers.dev/posts/os/os-3-process-and-thread/","summary":"\u003ch1 id=\"1-数据传输\"\u003e1 数据传输\u003c/h1\u003e\n\u003ch2 id=\"11-传输场景\"\u003e1.1 传输场景\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e父子进程\u003c/li\u003e\n\u003cli\u003e陌生进程\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"12-传输接口\"\u003e1.2 传输接口\u003c/h2\u003e\n\u003ch2 id=\"13-传输示例\"\u003e1.3 传输示例\u003c/h2\u003e\n\u003ch1 id=\"2-并发控制\"\u003e2 并发控制\u003c/h1\u003e\n\u003ch2 id=\"21-并发场景\"\u003e2.1 并发场景\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e整型\n\u003cul\u003e\n\u003cli\u003e多写\u003c/li\u003e\n\u003cli\u003e一写多读\u003c/li\u003e\n\u003cli\u003e多写一读\u003c/li\u003e\n\u003cli\u003e多写多读\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e数据\n\u003cul\u003e\n\u003cli\u003e多写\u003c/li\u003e\n\u003cli\u003e多读\u003c/li\u003e\n\u003cli\u003e一写多读\u003c/li\u003e\n\u003cli\u003e多写一读\u003c/li\u003e\n\u003cli\u003e多写多读\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"22-并发接口-glibc\"\u003e2.2 并发接口 (glibc)\u003c/h2\u003e\n\u003ch3 id=\"一自选锁\"\u003e一、自选锁\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;pthread.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003epthread_spinlock_t\u003c/span\u003e \u003cspan class=\"n\"\u003espin\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003epthread_spin_init\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003espin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ePTHREAD_PROCESS_PRIVATE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003epthread_spin_lock\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003espin\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003epthread_spin_unlock\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003espin\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"二互斥锁\"\u003e二、互斥锁\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;pthread.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003epthread_mutex_t\u003c/span\u003e \u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003epthread_mutexattr_t\u003c/span\u003e \u003cspan class=\"n\"\u003eattr\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003ethread_mutexattr_init\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eattr\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003epthread_mutexattr_settype\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eattr\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ePTHREAD_MUTEX_NORMAL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003epthread_mutex_init\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eattr\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003epthread_mutex_lock\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003epthread_mutex_unlock\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003elock\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"三读写锁\"\u003e三、读写锁\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;pthread.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003epthread_mutex_t\u003c/span\u003e \u003cspan class=\"n\"\u003erdlock\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003epthread_mutexattr_t\u003c/span\u003e \u003cspan class=\"n\"\u003eattr\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003epthread_rwlockattr_init\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eattr\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003epthread_rwlockattr_setpshared\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eattr\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ePTHREAD_PROCESS_SHARED\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003epthread_rwlock_init\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003erdlock\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003eattr\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003epthread_rwlock_rdlock\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003erdlock\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003epthread_rwlock_wrlock\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003erdlock\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003epthread_rwlock_unlock\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003erdlock\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"四信号量\"\u003e四、信号量\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;semaphore.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003esem_t\u003c/span\u003e \u003cspan class=\"n\"\u003esem\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003esem_init\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003esem\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003esem_wait\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003esem\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003esem_post\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003esem\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"五原子写\"\u003e五、原子写\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;pthread.h\u0026gt;/* C 11 */\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003evolatile\u003c/span\u003e \u003cspan class=\"kt\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"n\"\u003enum\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nf\"\u003e__atomic_store_n\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003enum\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e8\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003e__ATOMIC_SEQ_CST\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eunsigned\u003c/span\u003e \u003cspan class=\"n\"\u003ecur\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003e__atomic_load_n\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003enum\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003e__ATOMIC_SEQ_CST\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"23-并发代码\"\u003e2.3 并发代码\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e整型数据\u003c/p\u003e","title":"操作系统 3 多进程与多线程"},{"content":" 查看某个进程占用的内存\nps -p 17286 --no-headers -o pid,comm,rss,%mem | awk \u0026#39;{printf \u0026#34;%-8s %-20s %8.2f MB %5s%%\\n\u0026#34;, $1, $2, $3/1024, $4}\u0026#39; gdb调试进程或coredump文件时，变量取值出现’optimized out’时，关闭编译优化\n# 以编译PG为例： configure --enable-debug --disable-optimizations CFLAGS=\u0026#34;-g -O0 -fno-inline -fno-omit-frame-pointer\u0026#34; gdb启动调试阶段，自动执行命令\ntouch ~/.gdbinit echo \u0026#34;handle SIGUSR2 nostop noprint\u0026#34; \u0026gt;\u0026gt; ~/.gdbinit 判断编译选项\nreadelf --debug-dump=info `which bin_name` | grep -E \u0026#39;DW_AT_producer.*O[0-9]\u0026#39; ","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/gdb/","summary":"\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e查看某个进程占用的内存\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eps -p \u003cspan class=\"m\"\u003e17286\u003c/span\u003e --no-headers -o pid,comm,rss,%mem \u003cspan class=\"p\"\u003e|\u003c/span\u003e awk \u003cspan class=\"s1\"\u003e\u0026#39;{printf \u0026#34;%-8s %-20s %8.2f MB  %5s%%\\n\u0026#34;, $1, $2, $3/1024, $4}\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003egdb调试进程或coredump文件时，变量取值出现’optimized out’时，关闭编译优化\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 以编译PG为例：\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003econfigure --enable-debug --disable-optimizations \u003cspan class=\"nv\"\u003eCFLAGS\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;-g -O0 -fno-inline -fno-omit-frame-pointer\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003egdb启动调试阶段，自动执行命令\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etouch ~/.gdbinit\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;handle SIGUSR2 nostop noprint\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; ~/.gdbinit\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e判断编译选项\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ereadelf --debug-dump\u003cspan class=\"o\"\u003e=\u003c/span\u003einfo \u003cspan class=\"sb\"\u003e`\u003c/span\u003ewhich bin_name\u003cspan class=\"sb\"\u003e`\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e grep -E \u003cspan class=\"s1\"\u003e\u0026#39;DW_AT_producer.*O[0-9]\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ol\u003e","title":"工具 gdb"},{"content":"git log --author=shenkun --oneline x86\ngit status -uno | awk \u0026#39;{if (NR\u0026gt;1) print $3}\u0026#39; | grep src | xargs -I {} git add {} arm\ngit status -uno | grep modified | awk \u0026#39;{if (NR\u0026gt;1) print $2}\u0026#39; | xargs -I {} git add {} git tag -l git ls-remote --tags origin git fetch --tags ","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/git/","summary":"\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit log --author\u003cspan class=\"o\"\u003e=\u003c/span\u003eshenkun --oneline\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003ex86\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit status -uno \u003cspan class=\"p\"\u003e|\u003c/span\u003e awk \u003cspan class=\"s1\"\u003e\u0026#39;{if (NR\u0026gt;1) print $3}\u0026#39;\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e grep src \u003cspan class=\"p\"\u003e|\u003c/span\u003e xargs -I \u003cspan class=\"o\"\u003e{}\u003c/span\u003e git add \u003cspan class=\"o\"\u003e{}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003earm\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit status -uno \u003cspan class=\"p\"\u003e|\u003c/span\u003e grep modified \u003cspan class=\"p\"\u003e|\u003c/span\u003e awk \u003cspan class=\"s1\"\u003e\u0026#39;{if (NR\u0026gt;1) print $2}\u0026#39;\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e xargs -I \u003cspan class=\"o\"\u003e{}\u003c/span\u003e git add \u003cspan class=\"o\"\u003e{}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit tag -l\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit ls-remote --tags origin\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit fetch --tags\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"工具 git"},{"content":"tcpdump -i any -w ./vsql.pcap \u0026#39;tcp port 5432\u0026#39; ","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/tcpdump/","summary":"\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etcpdump -i any -w ./vsql.pcap \u003cspan class=\"s1\"\u003e\u0026#39;tcp port 5432\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"工具 tcpdump"},{"content":"1 基于SSL证书实现身份认证 在应用与数据库传输数据时，为避免攻击者对数据进行窃听、篡改、伪造、重放等攻击，Vastbae支持采用SSL协议保障数据机密性与完整性。在SSL协议协商密钥的过程中，应用与数据库需通过证书验证对方身份，同时，该证书也可作为登入数据库的身份凭证。\n此处介绍生成证书，并基于证书配置SSL协议，同时基于证书实现身份认证，操作流程可分为以下3个阶段：\n一、生成私钥与证书 二、数据库端配置证书与私钥 三、应用端配置证书与私钥 一、生成私钥与证书 此处介绍基于openssl工具，生成自签名证书的流程\n创建存放私钥与证书的文件夹\nmkdir cadir cd cadir mkdir ./demoCA ./demoCA/newcerts ./demoCA/private echo \u0026#39;01\u0026#39;\u0026gt;./demoCA/serial touch ./demoCA/index.txt 配置openssl工具\n从Vastbase安装包中，获取openssl工具以及openss配置文件。假设Vastbae安装包存放在$GAUSSHOME目录。\ncp $GAUSSHOME/bin/openssl ./ export PATH=`pwd`:$PATH which openssl # 确保openssl来源于Vastbase安装包，避免因版本不同造成证书不可用 openssl version cp $GAUSSHOME/share/sslcert/gsql/openssl.cnf ./ export OPENSSL_CONF=`pwd`/openssl.cnf 创建CA私钥、CA证书\nopenssl ecparam -genkey -name SM2 -out demoCA/private/cakey.pem openssl req -new -config openssl.cnf -key demoCA/private/cakey.pem -subj /C=CN/ST=BJ/L=HaiDian/O=VAST/OU=SEC/CN=CA -out cacert.req openssl ca -selfsign -config openssl.cnf -batch -keyfile demoCA/private/cakey.pem -in cacert.req -out demoCA/cacert.pem 创建数据库私钥、数据库证书\nopenssl ecparam -genkey -name SM2 -out server.key openssl req -new -config openssl.cnf -key server.key -subj /C=CN/ST=BJ/L=HaiDian/O=VAST/OU=SEC/CN=server -out server.req openssl ca -config openssl.cnf -days 3650 -batch -in server.req -out server.crt 创建应用端私钥、应用端证书\n注意，在以下第2条命令中，-subj的参数中，CN的取值应与数据库用户名相等。此处假设用户名为u1，则应配置CN=u1\nopenssl ecparam -genkey -name SM2 -out client.key openssl req -new -config openssl.cnf -key client.key -subj /C=CN/ST=BJ/L=HaiDian/O=VAST/OU=SEC/CN=u1 -out client.req openssl ca -config openssl.cnf -days 3650 -batch -in client.req -out client.crt 设置私钥与证书文件权限\nchmod 600 client* server* ca* demoCA/ca* 二、数据库端配置证书与私钥 创建新用户\nCREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; 配置SSL证书\nSSL协议支持使用多种加密与哈希算法保护传输数据，此处，通过配置ssl_ciphers参数可强制采用国密算法。\n此处，假设数据库的数据目录为$VBDATA。\nvb_guc set -D $VBDATA -c \u0026#34;ssl=on\u0026#34; vb_guc set -D $VBDATA -c \u0026#34;require_ssl=on\u0026#34; vb_guc set -D $VBDATA -c \u0026#34;ssl_ciphers=\u0026#39;ECDHE-ECDSA-SM4-CBC-SM3\u0026#39;\u0026#34; vb_guc set -D $VBDATA -c \u0026#34;ssl_cert_file=\u0026#39;`pwd`/server.crt\u0026#39;\u0026#34; vb_guc set -D $VBDATA -c \u0026#34;ssl_key_file=\u0026#39;`pwd`/server.key\u0026#39;\u0026#34; vb_guc set -D $VBDATA -c \u0026#34;ssl_ca_file=\u0026#39;`pwd`/demoCA/cacert.pem\u0026#39;\u0026#34; 开启远程登录\nvb_guc set -D $VBDATA -c \u0026#34;listen_addresses=\u0026#39;*\u0026#39;\u0026#34; 开启登录防火墙与配置基于证书的身份认证\n在pg_hba.conf中，添加一行配置，确保该配置在所有host配置的第1行\nvi $VBDATA/pg_hba.conf # 添加一下1行 hostssl all u1 0.0.0.0/0 cert 三、应用端配置证书与私钥 配置私钥与证书\n应用端可通过环境变量或连接参数配置私钥与证书\nexport PGSSLMODE=verify-ca export PGSSLCERT=`pwd`/client.crt export PGSSLKEY=`pwd`/client.key export PGSSLROOTCERT=`pwd`/demoCA/cacert.pem 登录数据库\n采用基于证书的身份认证后，并启用SSL协议，客户端无需再使用基于密码的身份认证\nvsql -h localhost -p 5432 -U u1 -r # 1. 验证openssl版本（确保openssl来vastbase安装包，且是tassl版本） which openssl openssl version # 2. 搭建CA环境 mkdir cadir cd cadir mkdir ./demoCA ./demoCA/newcerts ./demoCA/private echo \u0026#39;01\u0026#39;\u0026gt;./demoCA/serial touch ./demoCA/index.txt # 3. 创建CA私钥、CA证书 openssl ecparam -genkey -name SM2 -out demoCA/private/cakey.pem openssl req -new -config openssl.cnf -key demoCA/private/cakey.pem -subj /C=CN/ST=BJ/L=HaiDian/O=VAST/OU=SEC/CN=CA -out cacert.req openssl ca -config openssl.cnf -in cacert.req -keyfile demoCA/private/cakey.pem -selfsign -out demoCA/cacert.pem -batch # 4. 创建服务端私钥、服务端证书 openssl ecparam -genkey -name SM2 -out server.key openssl req -new -config openssl.cnf -key server.key -subj /C=CN/ST=BJ/L=HaiDian/O=VAST/OU=SEC/CN=server -out server.req openssl ca -config openssl.cnf -in server.req -out server.crt -days 3650 -batch # -md sm3 # 5. 创建客户端私钥、客户端证书 openssl ecparam -genkey -name SM2 -out client.key # (如果使用cert认证，-subj中，CN必须与用户名相等，比如我的用户名时u1) openssl req -new -config openssl.cnf -key client.key -subj /C=CN/ST=BJ/L=HaiDian/O=VAST/OU=SEC/CN=u1 -out client.req openssl ca -config openssl.cnf -in client.req -out client.crt -days 3650 -batch # 6. 设置权限 chmod 600 client* server* ca* demoCA/ca* # 7. 客户端配置ssl export PGSSLCERT=`pwd`/client.crt export PGSSLKEY=`pwd`/client.key export PGSSLMODE=verify-ca export PGSSLROOTCERT=`pwd`/demoCA/cacert.pem # 8. 服务端配置ssl连接 gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl=on\u0026#34; gs_guc set -D $GAUSSHOME/data -c \u0026#34;require_ssl=on\u0026#34; gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl_cert_file=\u0026#39;`pwd`/server.crt\u0026#39;\u0026#34; gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl_key_file=\u0026#39;`pwd`/server.key\u0026#39;\u0026#34; gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl_ca_file=\u0026#39;`pwd`/demoCA/cacert.pem\u0026#39;\u0026#34; gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl_crl_file=\u0026#39;\u0026#39;\u0026#34; # 9. 服务端配置远程连接 gs_guc set -D $GAUSSHOME/data -c \u0026#34;listen_addresses = \u0026#39;*\u0026#39;\u0026#34; vi $GAUSSHOME/data/pg_hba.conf host all u1 0.0.0.0/0 sha256 # 如果是cert认证，pg_hba.conf配置修改为： hostssl all all 0.0.0.0/0 cert 安全前提：（本例子中，正向计算为乘法，负向计算为除法，显然除法计算不难，此处只是为了方便解释如何计算密钥）\n攻击者通过网络流量，获取：4，120，80\n安全前提，攻击者无法逆向计算：120 / 4 = 30 或者 80 / 4 = 20\nRSA：正向计算简单（大质数相乘）、负向计算非常难（大整数分解）\n正向计算：9999991 * 9999983 = 99999740000153 负向计算：将99999740000153分解为2个质数 client - 生成随机数 [client_random] - 生成随机私钥 [client_priv] - 计算公钥 [client_pub] - 发送 [client_random, client_pub] --\u0026gt; - 接收 [client_random, client_pub] - 生成随机数 [server_random] - 生成随机私钥 [server_priv] - 计算公钥 [server_pub] - 发送 [server_random, server_pub] - 生成密钥 [client_random, client_priv, server_random, server_pub] - 生成密钥 [server_random, server_priv, client_random, client_pub] 原理：[client_priv, server_pub] = [server_priv, client_pub] client - 生成随机数 [client_random] - 生成随机私钥 [client_priv] 3 - 基于client_priv，计算公钥 [client_pub] 10 - 3 = 7 - 发送 [client_random, client_pub] --\u0026gt; - 接收 [client_random, client_pub] - 生成随机数 [server_random] - 生成随机私钥 [server_priv] 1 - 基于server_priv，计算公钥 [server_pub] 10 - 1 = 9 - 发送 [server_random, server_pub] - 生成密钥 [client_random, client_priv, server_random, server_pub] - 生成密钥 [server_random, server_priv, client_random, client_pub] 3， 7\n9 1\n3 + (10 - 1) = 12\n9 + (10 - 7) = 12\nClient Server ================================================================================== 0️⃣ 启动连接 本机产生 32 字节随机预随机 → 准备发 ClientHello ------------------------------------------\u0026gt; 1️⃣ ClientHello 报文内容 - 协议版本：客户端最高支持的 TLS 版本号（如 1.2） - ClientRandom：4 字节时间戳 + 28 字节真随机共 32 B - 会话 ID：空（新会话）或旧会话票 - 密码套件列表：必须包含 ECDHE 族，如 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - 压缩方法列表：通常只有 null - 扩展： – supported_groups：本机支持的椭圆曲线（secp256r1、secp384r1 …） – ec_point_formats：支持未压缩/压缩点 – server_name：访问的域名（SNI） – application_layer_protocol_negotiation：想谈 ALPN（h2、http/1.1 …） – session_ticket：如果客户端有旧票 ------------------------------------------\u0026gt; 2️⃣ Server 收到 ClientHello 后，**一次性动作** 2a) 当场随机生成 32 字节 ServerRandom（4 字节时间戳 + 28 字节真随机） 2b) 当场随机生成 ECDHE 私钥 eS ∈ [1, n-1]（n 为曲线阶） 2c) 计算对应临时公钥 PubS = eS·G 2d) 选定最终协议版本、CipherSuite、曲线 2e) 组装以下四条报文一次性发回 \u0026lt;------------------------------------------ ┌─ ServerHello 报文 │ - 协议版本：最终协商的 TLS 版本 │ - ServerRandom：32 B 随机数 │ - CipherSuite：最终选定的算法套件 │ - CompressionMethod：null │ - SessionID：服务器决定的新会话 ID │ - 扩展：选定的曲线、点格式、ALPN 结果等 ├─ Certificate 报文 │ - 服务器证书链（叶子证书 + 可选中间证书） │ - 叶子证书含 RSA/ECDSA 公钥，KeyUsage 含数字签名 ├─ ServerKeyExchange 报文 │ - 曲线参数：曲线名 secp256r1 │ - PubS：服务器临时 ECDHE 公钥（未压缩或压缩点） │ - Signature：对“曲线参数 || PubS || ClientRandom || ServerRandom” │ 用服务器私钥做的数字签名（算法与证书匹配） ├─ CertificateRequest 报文（双向认证必发） │ - certificate_types：要求 RSA 或 ECDSA 证书 │ - signature_algorithms：可接受的签名算法列表 │ - certificate_authorities：服务器信任的 CA 可打印名列表 └─ ServerHelloDone 报文（空结构，仅表示“我发完了”） 【★Client 校验服务器身份】 3️⃣ Client 收到后 3a) **当场随机生成 ECDHE 私钥 eC ∈ [1, n-1]** 3b) 计算对应临时公钥 PubC = eC·G 3c) **逐张检查服务器证书链** - 有效期、KeyUsage、吊销状态（CRL/OCSP）、域名匹配 3d) **用服务器证书公钥验证 ServerKeyExchange 中的签名** - 验证失败直接发 Alert 断开 3e) **计算共享密钥** Pre-Master Secret = 椭圆曲线点乘 eC·PubS 的 x 坐标 3f) 组装以下报文一次性发出 ------------------------------------------\u0026gt; ┌─ Certificate 报文（双向认证时发） │ - 客户端证书链（叶子证书 + 可选中间证书） │ - 叶子证书含 RSA/ECDSA 公钥，KeyUsage 含数字签名 ├─ ClientKeyExchange 报文 │ - PubC：客户端临时 ECDHE 公钥 ├─ CertificateVerify 报文（若发了客户端证书，必发） │ - Signature：对“到此为止所有握手消息哈希” │ 用客户端私钥做的数字签名（算法与证书匹配） ├─ ChangeCipherSpec 报文（单字节 0x01） │ - 含义：以后我用协商密钥加密 └─ Finished 报文 - 用刚刚算出的主密钥对“全部握手消息”做 HMAC，验证完整性 【★Server 校验客户端身份】 4️⃣ Server 收到后 4a) **逐张检查客户端证书链** - 有效期、KeyUsage、吊销状态、ACL 匹配 4b) **用客户端证书公钥验证 CertificateVerify 中的签名** - 验证失败直接发 Alert 断开 4c) **计算共享密钥** Pre-Master Secret = 椭圆曲线点乘 eS·PubC 的 x 坐标 （与 Client 值必然相同） 4d) **PRF 派生主密钥** Master Secret = PRF(Pre-Master, \u0026#34;master secret\u0026#34;, ClientRandom || ServerRandom) 4e) **PRF 再次派生 6 把会话密钥/IV** - client_write_key、server_write_key - client_write_MAC_key、server_write_MAC_key - client_write_IV、server_write_IV 4f) 组装以下报文一次性发回 \u0026lt;------------------------------------------ ┌─ ChangeCipherSpec 报文（单字节 0x01） └─ Finished 报文 - 用协商密钥对“全部握手消息”做 HMAC，验证完整性 5️⃣ 双方各自校验对端 Finished 的 HMAC 通过 → 握手成功 失败 → Alert(fatal) 立即断开 6️⃣ 应用数据阶段 - 所有后续记录层消息使用 AEAD（如 AES-128-GCM）加密 - 每条记录含序列号、类型、长度、密文、认证标签 - 任何 MAC 校验错误 → Alert(fatal) 立即中断 Client Server ================================================================================== 0️⃣ 启动连接 本地随机生成 32 B 预随机 ------------------------------------------\u0026gt; 1️⃣ ClientHello - TLS 版本、CipherSuites（本次必须含 TLS_RSA_WITH_*） - ClientRandom (32 B) - 可选 SNI / ALPN / 会话票 ------------------------------------------\u0026gt; 2️⃣ Server 收到 - 选 TLS 版本、CipherSuite（TLS_RSA_*） - 当场随机生成 ServerRandom - 取自己 RSA 证书链 CertS（含 RSA 公钥 PubS） - 决定要求客户端证书 → 置 CertificateRequest \u0026lt;------------------------------------------ ServerHello Certificate (CertS) ← 仅含 RSA 公钥，无临时 ECDHE 参数 CertificateRequest* ← 双向认证时发送 ServerHelloDone 【★Client 校验 Server 证书】 3️⃣ Client 收到后 3a) 解析 CertS 链 - 逐级检查签名、有效期、KeyUsage = keyEncipherment - 查 CRL / OCSP / 本地缓存 - 把叶子证书与 SNI / URL 域名比对 3b) 任一步失败 → Alert(fatal) 中断 3c) 当场随机生成 48 B 的 Pre-Master Secret 3d) 用 PubS 对其进行 RSAES-PKCS1-v1_5 或 RSAES-OAEP 加密， 得到 EncryptedPreMasterSecret 4️⃣ Client 发送 - 自己的证书链 CertC（含 RSA 公钥） - EncryptedPreMasterSecret - CertificateVerify - 签名 = Sign(握手消息哈希) 用 CertC 对应私钥 ------------------------------------------\u0026gt; ClientKeyExchange - EncryptedPreMasterSecret Certificate (CertC) CertificateVerify ChangeCipherSpec Finished 【★Server 校验 Client 证书】 5️⃣ Server 收到后 5a) 解析 CertC 链 - 逐级检查签名、有效期、KeyUsage = digitalSignature - 查 CRL / OCSP / 本地 ACL 5b) 用 CertC 的公钥验证 CertificateVerify 5c) 任一步失败 → Alert(fatal) 中断 5d) 用本地 RSA 私钥解密 EncryptedPreMasterSecret 得到与 Client 完全相同的 48 B Pre-Master 5e) PRF(Pre-Master, ClientRandom, ServerRandom) → Master Secret (48 B) → 6 个对称密钥/IV \u0026lt;------------------------------------------ ChangeCipherSpec Finished 6️⃣ 双方独立派生密钥 PRF 展开 → client_write_key / server_write_key 等 后续记录层全部 AEAD 加密 7️⃣ 应用数据阶段 Client 写：AEAD-加密 Server 写：AEAD-加密 Finished 校验失败 → Alert(fatal) 立即中断 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/vastbase-ssl/","summary":"\u003ch1 id=\"1-基于ssl证书实现身份认证\"\u003e1 基于SSL证书实现身份认证\u003c/h1\u003e\n\u003cp\u003e在应用与数据库传输数据时，为避免攻击者对数据进行窃听、篡改、伪造、重放等攻击，Vastbae支持采用SSL协议保障数据机密性与完整性。在SSL协议协商密钥的过程中，应用与数据库需通过证书验证对方身份，同时，该证书也可作为登入数据库的身份凭证。\u003cbr\u003e\n此处介绍生成证书，并基于证书配置SSL协议，同时基于证书实现身份认证，操作流程可分为以下3个阶段：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e一、生成私钥与证书\u003c/li\u003e\n\u003cli\u003e二、数据库端配置证书与私钥\u003c/li\u003e\n\u003cli\u003e三、应用端配置证书与私钥\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"一生成私钥与证书\"\u003e一、生成私钥与证书\u003c/h2\u003e\n\u003cp\u003e此处介绍基于openssl工具，生成自签名证书的流程\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e创建存放私钥与证书的文件夹\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir cadir\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e cadir\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir ./demoCA ./demoCA/newcerts ./demoCA/private\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;01\u0026#39;\u003c/span\u003e\u0026gt;./demoCA/serial\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etouch ./demoCA/index.txt\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e配置openssl工具\u003cbr\u003e\n从Vastbase安装包中，获取openssl工具以及openss配置文件。假设Vastbae安装包存放在$GAUSSHOME目录。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/bin/openssl ./\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003ePATH\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e:\u003cspan class=\"nv\"\u003e$PATH\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ewhich openssl \u003cspan class=\"c1\"\u003e# 确保openssl来源于Vastbase安装包，避免因版本不同造成证书不可用\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl version\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/share/sslcert/gsql/openssl.cnf ./\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eOPENSSL_CONF\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e/openssl.cnf\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e创建CA私钥、CA证书\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -genkey -name SM2 -out demoCA/private/cakey.pem\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -new -config openssl.cnf -key demoCA/private/cakey.pem -subj /C\u003cspan class=\"o\"\u003e=\u003c/span\u003eCN/ST\u003cspan class=\"o\"\u003e=\u003c/span\u003eBJ/L\u003cspan class=\"o\"\u003e=\u003c/span\u003eHaiDian/O\u003cspan class=\"o\"\u003e=\u003c/span\u003eVAST/OU\u003cspan class=\"o\"\u003e=\u003c/span\u003eSEC/CN\u003cspan class=\"o\"\u003e=\u003c/span\u003eCA -out cacert.req\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ca -selfsign -config openssl.cnf -batch -keyfile demoCA/private/cakey.pem -in cacert.req -out demoCA/cacert.pem\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e创建数据库私钥、数据库证书\u003c/p\u003e","title":"Vastbase SSL安全传输"},{"content":"./configure --prefix=$PG_HOME --enable_debug --with-openssl --enable-cassert make -sj 6 \u0026amp;\u0026amp; make install alias pmake=\u0026#39;make -sj 6 \u0026amp;\u0026amp; make install -sj\u0026#39; alias pinit=\u0026#39;rm -rf $PG_HOME/data \u0026amp;\u0026amp; initdb -D $PG_HOME/data\u0026#39; alias pstart=\u0026#39;pg_ctl start -D $PG_HOME/data -l logfile\u0026#39; alias pstop=\u0026#39;pg_ctl stop -D $PG_HOME/data -l logfile\u0026#39; ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/e100/","summary":"\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e./configure --prefix\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e --enable_debug --with-openssl --enable-cassert\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emake -sj \u003cspan class=\"m\"\u003e6\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e make install\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ealias\u003c/span\u003e \u003cspan class=\"nv\"\u003epmake\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;make -sj 6 \u0026amp;\u0026amp; make install -sj\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ealias\u003c/span\u003e \u003cspan class=\"nv\"\u003epinit\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;rm -rf $PG_HOME/data \u0026amp;\u0026amp; initdb -D $PG_HOME/data\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ealias\u003c/span\u003e \u003cspan class=\"nv\"\u003epstart\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pg_ctl start -D $PG_HOME/data -l logfile\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ealias\u003c/span\u003e \u003cspan class=\"nv\"\u003epstop\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pg_ctl stop -D $PG_HOME/data -l logfile\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"e100"},{"content":"1 使用方式 vsql -d vastbase -r CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; CREATE USER u2 SYSADMIN PASSWORD \u0026#39;u2.password\u0026#39;; CREATE USER u3 SUPERUSER PASSWORD \u0026#39;u3.password\u0026#39;; SELECT rolname,rolsuper,rolsystemadmin FROM pg_authid ORDER BY rolname; vsql -d vastbase -c \u0026#34;SELECT rolname,rolsuper,rolsystemadmin FROM pg_authid ORDER BY rolname;\u0026#34; # 导出 vb_dumpall --roles-only -f ./u.sql # 清理 vsql -d vastbase -c \u0026#34; DROP USER IF EXISTS u1,u2,u3; \u0026#34; # 恢复 vsql -d vastbase -f ./u.sql vsql -d vastbase -c \u0026#34;SELECT rolname,rolsuper,rolsystemadmin FROM pg_authid ORDER BY rolname;\u0026#34; ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/dump/","summary":"\u003ch1 id=\"1-使用方式\"\u003e1 使用方式\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003evsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003evastbase\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSYSADMIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSUPERUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u3.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erolname\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003erolsuper\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003erolsystemadmin\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_authid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eORDER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erolname\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d vastbase -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT rolname,rolsuper,rolsystemadmin FROM pg_authid ORDER BY rolname;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 导出\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_dumpall --roles-only -f ./u.sql\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 清理\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d vastbase -c \u003cspan class=\"s2\"\u003e\u0026#34; DROP USER IF EXISTS u1,u2,u3; \u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 恢复\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d vastbase -f ./u.sql\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d vastbase -c \u003cspan class=\"s2\"\u003e\u0026#34;SELECT rolname,rolsuper,rolsystemadmin FROM pg_authid ORDER BY rolname;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"pg_dump"},{"content":"1 libpq编程 1.1 配置数据库 安装数据库\n# 假设安装目录为 $PG_HOME 启动数据库\n# 假设数据目录为 $PG_HOME/data 配置数据库\necho \u0026#39;host all u1 0.0.0.0/0 md5\u0026#39; \u0026gt;\u0026gt; $PG_HOME/data/pg_hba.conf echo \u0026#34;listen_addresses=\u0026#39;0.0.0.0\u0026#39;\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/postgresql.conf pg_ctl reload -D $PG_HOME/data 创建用户\npsql -d postgres -c \u0026#34;create user u1 password \u0026#39;u1.password\u0026#39;;\u0026#34; # 验证一下 psql -h 127.0.0.1 -p 5432 -d postgres -U u1 -W \u0026#39;u1.password\u0026#39; -c \u0026#39;\\d\u0026#39; 1.2 编写libpq demo 生成源文件\ntouch pq.c # 复制 1.3 章节的源码 到 pq.c中 # 配置环境变量 export LD_LIBRARY_PATH=$PG_HOME/lib:$LD_LIBRARH_PATH 编译\ngcc pq.c -o pq -I$PG_HOME/include -L$PG_HOME/lib -lpq 执行\n./pq 1.3 libpq demo源码 #include \u0026lt;stdio.h\u0026gt; #include \u0026lt;stdlib.h\u0026gt; #include \u0026#34;libpq-fe.h\u0026#34; PGresult *exec_sql(PGconn *conn, const char *sql) { PGresult *res = PQexec(conn, sql); if (PQresultStatus(res) == PGRES_COMMAND_OK || PQresultStatus(res) == PGRES_TUPLES_OK) { return res; } printf(\u0026#34;sql : %s \\nerror: %s\\n\u0026#34;, sql, PQerrorMessage(conn)); PQfinish(conn); exit(0); } int main() { PGconn *conn; PGresult *res; conn = PQconnectdb(\u0026#34;host=127.0.0.1 port=5432 dbname=postgres user=u1 password=u1.password\u0026#34;); if (PQstatus(conn) != CONNECTION_OK) { printf(\u0026#34;conn error, %s\\n\u0026#34;, PQerrorMessage(conn)); exit(0); } res = exec_sql(conn, \u0026#34;DROP TABLE IF EXISTS t1;\u0026#34;); res = exec_sql(conn, \u0026#34;CREATE TABLE t1(c1 INT);\u0026#34;); res = exec_sql(conn, \u0026#34;INSERT INTO t1 VALUES (5);\u0026#34;); res = exec_sql(conn, \u0026#34;SELECT * FROM t1;\u0026#34;); int rows = PQntuples(res); int i; for (i = 0; i \u0026lt; rows; i++) { printf(\u0026#34;[%d]: %s\\n\u0026#34;, i, PQgetvalue(res, i, 0)); } PQfinish(conn); return 0; } ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/libpq/","summary":"\u003ch1 id=\"1-libpq编程\"\u003e1 libpq编程\u003c/h1\u003e\n\u003ch2 id=\"11-配置数据库\"\u003e1.1 配置数据库\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e安装数据库\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 假设安装目录为\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e启动数据库\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 假设数据目录为\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e配置数据库\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;host all u1 0.0.0.0/0 md5\u0026#39;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/pg_hba.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;listen_addresses=\u0026#39;0.0.0.0\u0026#39;\u0026#34;\u003c/span\u003e \u0026gt;\u0026gt; \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data/postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epg_ctl reload -D \u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/data\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e创建用户\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epsql -d postgres -c \u003cspan class=\"s2\"\u003e\u0026#34;create user u1 password \u0026#39;u1.password\u0026#39;;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 验证一下\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epsql -h 127.0.0.1 -p \u003cspan class=\"m\"\u003e5432\u003c/span\u003e -d postgres -U u1 -W \u003cspan class=\"s1\"\u003e\u0026#39;u1.password\u0026#39;\u003c/span\u003e -c \u003cspan class=\"s1\"\u003e\u0026#39;\\d\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"12-编写libpq-demo\"\u003e1.2 编写libpq demo\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e生成源文件\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etouch pq.c\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 复制 1.3 章节的源码 到 pq.c中\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 配置环境变量\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eLD_LIBRARY_PATH\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/lib:\u003cspan class=\"nv\"\u003e$LD_LIBRARH_PATH\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e编译\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egcc pq.c -o pq -I\u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/include -L\u003cspan class=\"nv\"\u003e$PG_HOME\u003c/span\u003e/lib -lpq\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e执行\u003c/p\u003e","title":"libpq"},{"content":"1 adt_scope_ddl /* ============================= Operate create alter drop truncate prepare dealocate abort begin release savepoint analyze checkpoint commit commit prepared end rollback rollback prepare prepare prepare transcation rollback to savepoint savepoint start transaction call execute close explain cluster comment copy discard do declare move fetch grant revoke import listen notify unlisten load lock reassign refresh reindex reset set set constraints set role set session authorization set transcation show values Object: system user role group database table space schema table temp table forgien table index view materialized view sequence function procedure trigger aggregate larger object domain type cast conversion collation language rule forgien data wrapper server user mapping publication subscription privileges policy statistics routine text search configuration text search dictionary text search parser text search template operator operator class operator family access method extension -- ============================= */ -- fdw \\c atlasdb CREATE EXTENSION postgres_fdw; CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; CREATE SERVER s1 FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host \u0026#39;172.16.100.134\u0026#39;, port \u0026#39;5432\u0026#39;, dbname \u0026#39;fdb1\u0026#39;); GRANT ALL ON FOREIGN SERVER s1 TO u1; set role u1; CREATE FOREIGN TABLE t1 (c1 INT) SERVER s1 OPTIONS (schema_name \u0026#39;public\u0026#39;, table_name \u0026#39;ft1\u0026#39;); CREATE USER MAPPING FOR u1 SERVER s1 OPTIONS (user \u0026#39;fu1\u0026#39;, password \u0026#39;fu1.password\u0026#39;); -- common CREATE TABLE tbl(c1 INT, c2 TEXT); INSERT INTO tbl VALUES(generate_series(1, 100), \u0026#39;bbbbbbbbb\u0026#39;); -- cursor | declare,fetch,move,close | (must in transaction block) BEGIN; DECLARE cu1 CURSOR FOR SELECT * FROM tbl; -- consider it as a cache for select result FETCH 3 FROM cu1; FETCH 3 FROM cu1; MOVE FORWARD 2 FROM cu1; CLOSE cu1; COMMIT; -- channel | listen,unlisten,notify -- session 1 LISTEN ch1; -- session 2 --\u0026gt; session 1, session 1 receive and cache message NOTIFY ch1, \u0026#39;hello\u0026#39;; SELECT pg_notify(\u0026#39;ch1\u0026#39;, \u0026#39;hello\u0026#39; || \u0026#39;a\u0026#39;); UNLISTEN ch1; -- table | create,alter(rename,move),drop,lock,insert,update,select,delete CREATE TABLE tb1(c1 INT); ALTER TABLE tb1 ADD COLUMN c3(INT); ALTER TABLE tb1 RENAME COLUMN c3 TO c2; BEGIN; LOCK TABLE tb1 IN ACCESS EXCLUSIVE MODE; COMMIT; DROP TABLE tb1; -- materialized view CREATE MATERIALIZED VIEW mv1 AS SELECT * FROM tbl; -- dictionary \u0026amp; configuration | CREATE TEXT SEARCH DICTIONARY tsd1 ( TEMPLATE = snowball, language = english ); ALTER TEXT SEARCH DICTIONARY tsd1 (stopwords = english); CREATE TEXT SEARCH CONFIGURATION tsc1 (copy = english); ALTER TEXT SEARCH CONFIGURATION tsc1 ALTER MAPPING FOR asciiword, asciihword, hword_asciipart WITH tsd1, simple; SELECT to_tsvector(\u0026#39;tsc1\u0026#39;, \u0026#39;abc bb cc bb\u0026#39;); DROP TEXT SEARCH CONFIGURATION tsc1; DROP TEXT SEARCH DICTIONARY tsd1; -- domain | create,alter,drop CREATE DOMAIN do1 AS TEXT CONSTRAINT c1 CHECK ( VALUE ~ \u0026#39;^[0-9]+$\u0026#39; ) DEFAULT \u0026#39;3\u0026#39;; -- consider a group of \u0026#39;check / not null / default\u0026#39; for column ALTER DOMAIN do1 ADD CONSTRAINT c2 CHECK (LEFT(VALUE, 1) \u0026lt; \u0026#39;5\u0026#39;); CREATE TABLE t1(c1 do1); INSERT INTO t1 VALUES (\u0026#39;12\u0026#39;); INSERT INTO t1 VALUES (\u0026#39;89\u0026#39;); INSERT INTO t1 VALUES (default); DROP TABLE t1; DROP DOMAIN do1; -- conversion | create | (need define c code) -- CREATE FUNCTION f1(integer, cstring, integer, cstring) RETURNS integer AS \u0026#39;latin1_utf8\u0026#39;, \u0026#39;latin1_to_utf8\u0026#39; LANGUAGE C STRICT; -- CREATE CONVERSION co1 FOR \u0026#39;LATIN1\u0026#39; TO \u0026#39;UTF8\u0026#39; FROM f1; -- SELECT CONVERT(\u0026#39;\\xe4\\xf6\\xfc\u0026#39;::bytea, \u0026#39;latin1_utf8_cnv\u0026#39;); -- DROP CONVERSION co1; -- DROP FUNCTION f1; -- user CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; CREATE USER u2 PASSWORD \u0026#39;u2.password\u0026#39;; CREATE USER u3 PASSWORD \u0026#39;u2.password\u0026#39;; ALTER USER u1 PASSWORD \u0026#39;u1.newpass\u0026#39;; DROP USER u1; DROP USER IF EXISTS u1,u2,u3,u4; -- type CREATE TYPE int_2 AS (a INT, b INT); -- synonym (only oracle) CREATE TABLE t1 (c1 INT); CREATE SYNONYM s1 FOR t1; CREATE PUBLIC SYNONYM ps1 FOR t1; SELECT * FROM s1; SELECT * FROM ps1; DROP SYNONYM s1; DROP SYNONYM ps1; -- aggregate CREATE FUNCTION f_add_a_int(state bigint[], val int) RETURNS bigint[] LANGUAGE sql AS $$ SELECT ARRAY[state[1] + val, state[2] + 1] $$; CREATE FUNCTION f_avg_final(state bigint[]) RETURNS numeric LANGUAGE sql AS $$ SELECT state[1]::numeric / state[2] $$; CREATE AGGREGATE a_int_avg(int) ( SFUNC = f_add_a_int, STYPE = bigint[], FINALFUNC = f_avg_final, INITCOND = \u0026#39;{0,0}\u0026#39; ); SELECT a_int_avg(v) FROM generate_series(1,6) v; DROP AGGREGATE a_int_avg(int); DROP FUNCTION f_add_a_int; DROP FUNCTION f_avg_final; 2 adt_scope_dcl 3 adt_scope_dml 4 adt_scope_dql 5 adt_scope_tcl 6 adt_scope_func 7 adt_scope_mng 8 adt_scope_misc ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/9-testcase-e100-audit/","summary":"\u003ch1 id=\"1-adt_scope_ddl\"\u003e1 adt_scope_ddl\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/*\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e=============================\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003eOperate\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    create\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    alter\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    drop\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    truncate\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    prepare\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    dealocate\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    abort\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    begin\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    release savepoint\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    analyze\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    checkpoint\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    commit\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    commit prepared\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    end\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    rollback\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    rollback prepare\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    prepare\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    prepare transcation\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    rollback to savepoint\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    savepoint\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    start transaction\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    call\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    execute\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    close\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    explain\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    cluster\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    comment\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    copy\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    discard\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    do\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    declare\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    move\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    fetch\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    grant\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    revoke\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    import\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    listen\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    notify\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    unlisten\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    load\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    lock\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    reassign\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    refresh\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    reindex\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    reset\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    set\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    set constraints\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    set role\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    set session authorization\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    set transcation\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    show\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    values\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003eObject:\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    system\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    user\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    role\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    group\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    database\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    table space\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    schema\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    table\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e        temp table\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e        forgien table\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    index\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    view\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e        materialized view\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    sequence\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    function\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    procedure\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    trigger\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    aggregate\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    larger object\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    domain\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    type\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    cast\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    conversion\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    collation\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    language\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    rule\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    forgien data wrapper\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    server\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    user mapping\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    publication\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    subscription\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    privileges\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    policy\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    statistics\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    routine\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    text search configuration\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    text search dictionary\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    text search parser\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    text search template\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    operator\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    operator class\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    operator family\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    access method\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e    extension\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e-- =============================\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e*/\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- fdw\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eatlasdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eEXTENSION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres_fdw\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSERVER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOREIGN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATA\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eWRAPPER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres_fdw\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eOPTIONS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ehost\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;172.16.100.134\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eport\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;5432\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;fdb1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eGRANT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eALL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOREIGN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSERVER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003erole\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOREIGN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSERVER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eOPTIONS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003eschema_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;public\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etable_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;ft1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eMAPPING\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSERVER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eOPTIONS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003euser\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;fu1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;fu1.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- common\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etbl\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etbl\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003egenerate_series\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e100\u003c/span\u003e\u003cspan class=\"p\"\u003e),\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;bbbbbbbbb\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- cursor | declare,fetch,move,close |  (must in transaction block)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDECLARE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCURSOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etbl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- consider it as a cache for select result\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eFETCH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eFETCH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eMOVE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFORWARD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCLOSE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCOMMIT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- channel | listen,unlisten,notify\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- session 1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eLISTEN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ech1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- session 2 --\u0026gt; session 1, session 1 receive and cache message\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eNOTIFY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ech1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;hello\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_notify\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;ch1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;hello\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e||\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;a\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eUNLISTEN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ech1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- table | create,alter(rename,move),drop,lock,insert,update,select,delete\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etb1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etb1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eADD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCOLUMN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec3\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etb1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eRENAME\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCOLUMN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eBEGIN\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eLOCK\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etb1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eACCESS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXCLUSIVE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eMODE\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCOMMIT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etb1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- materialized view\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eMATERIALIZED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVIEW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emv1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etbl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- dictionary \u0026amp; configuration |\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSEARCH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDICTIONARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etsd1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eTEMPLATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esnowball\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003elanguage\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eenglish\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSEARCH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDICTIONARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etsd1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003estopwords\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eenglish\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSEARCH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eCONFIGURATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etsc1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ecopy\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eenglish\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSEARCH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eCONFIGURATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etsc1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eMAPPING\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003easciiword\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003easciihword\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ehword_asciipart\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etsd1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003esimple\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eto_tsvector\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;tsc1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;abc bb cc bb\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSEARCH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eCONFIGURATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etsc1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSEARCH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDICTIONARY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etsd1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- domain | create,alter,drop\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDOMAIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edo1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCONSTRAINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCHECK\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eVALUE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e~\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;^[0-9]+$\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDEFAULT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;3\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- consider a group of \u0026#39;check / not null / default\u0026#39; for column\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDOMAIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edo1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eADD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCONSTRAINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCHECK\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003eLEFT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eVALUE\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;5\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edo1\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;12\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;89\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003edefault\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDOMAIN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edo1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- conversion | create | (need define c code)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- CREATE FUNCTION f1(integer, cstring, integer, cstring) RETURNS integer AS \u0026#39;latin1_utf8\u0026#39;, \u0026#39;latin1_to_utf8\u0026#39; LANGUAGE C STRICT;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- CREATE CONVERSION co1 FOR \u0026#39;LATIN1\u0026#39; TO \u0026#39;UTF8\u0026#39; FROM f1;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- SELECT CONVERT(\u0026#39;\\xe4\\xf6\\xfc\u0026#39;::bytea, \u0026#39;latin1_utf8_cnv\u0026#39;);\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- DROP CONVERSION co1;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- DROP FUNCTION f1;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- user\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu3\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u2.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.newpass\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eIF\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eEXISTS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eu2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eu3\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003eu4\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- type\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTYPE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eint_2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- synonym (only oracle)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSYNONYM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ePUBLIC\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSYNONYM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eps1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eps1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSYNONYM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSYNONYM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eps1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- aggregate\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFUNCTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ef_add_a_int\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003estate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003ebigint\u003c/span\u003e\u003cspan class=\"p\"\u003e[],\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eval\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eRETURNS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003ebigint\u003c/span\u003e\u003cspan class=\"p\"\u003e[]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLANGUAGE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003esql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e$$\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eARRAY\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"k\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eval\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$$\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFUNCTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ef_avg_final\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003estate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003ebigint\u003c/span\u003e\u003cspan class=\"p\"\u003e[])\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eRETURNS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003enumeric\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eLANGUAGE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003esql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAS\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e$$\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e]::\u003c/span\u003e\u003cspan class=\"nb\"\u003enumeric\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003estate\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$$\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAGGREGATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea_int_avg\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nb\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"n\"\u003eSFUNC\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ef_add_a_int\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"k\"\u003eSTYPE\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003ebigint\u003c/span\u003e\u003cspan class=\"p\"\u003e[],\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"n\"\u003eFINALFUNC\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ef_avg_final\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"n\"\u003eINITCOND\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;{0,0}\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea_int_avg\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ev\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egenerate_series\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"mi\"\u003e6\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ev\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eAGGREGATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ea_int_avg\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nb\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFUNCTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ef_add_a_int\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFUNCTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ef_avg_final\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"2-adt_scope_dcl\"\u003e2 adt_scope_dcl\u003c/h1\u003e\n\u003ch1 id=\"3-adt_scope_dml\"\u003e3 adt_scope_dml\u003c/h1\u003e\n\u003ch1 id=\"4-adt_scope_dql\"\u003e4 adt_scope_dql\u003c/h1\u003e\n\u003ch1 id=\"5-adt_scope_tcl\"\u003e5 adt_scope_tcl\u003c/h1\u003e\n\u003ch1 id=\"6-adt_scope_func\"\u003e6 adt_scope_func\u003c/h1\u003e\n\u003ch1 id=\"7-adt_scope_mng\"\u003e7 adt_scope_mng\u003c/h1\u003e\n\u003ch1 id=\"8-adt_scope_misc\"\u003e8 adt_scope_misc\u003c/h1\u003e","title":"海量 9 用例 E100审计"},{"content":"1 使用JDBC的流程 准备java环境 准备jdbc驱动 编写java代码 执行java代码 2 使用JDBC 2.1 准备java环境 安装java工具包\nsudo yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel 验证java安装成功\njava -version # openjdk version \u0026#34;1.8.0_382\u0026#34; : 8表示java 8 执行java demo\n# 编写代码 echo \u0026#39; public class Demo { public static void main(String[] args) { System.out.println(\u0026#34;Hello World\u0026#34;); } } \u0026#39; \u0026gt;\u0026gt; Demo.java # 编译代码 javac Demo.java # 执行 java Demo 2.2 准备jdbc驱动 touch jdbc cd jdbc mkdir jars cd jars wget https://jdbc.postgresql.org/download/postgresql-42.7.7.jar 目录架构： |-- jdbc |-- jars |-- postgresql-42.7.7.jar https://polydistortion.net/bc/index.html\n2.3 准备数据库 CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; 2.3 编写java代码 import java.sql.*; public class Pg { public static void main(String[] args) { try { Class.forName(\u0026#34;org.postgresql.Driver\u0026#34;); Connection conn = DriverManager.getConnection( \u0026#34;jdbc:postgresql://127.0.0.1:5432/postgres\u0026#34;, \u0026#34;u1\u0026#34;, \u0026#34;u1.password\u0026#34;); Statement stmt = conn.createStatement(); int ru = stmt.executeUpdate(\u0026#34;CREATE TABLE t1(c1 INT, c2 TEXT)\u0026#34;); ru = stmt.executeUpdate(\u0026#34;INSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;)\u0026#34;); ResultSet rq = stmt.executeQuery(\u0026#34;SELECT * FROM t1\u0026#34;); stmt.close(); conn.close(); } catch (Exception e) { e.printStackTrace(); } } } 2.4 执行java代码 # 1 编译 javac -cp ./jars/postgresql-42.7.7.jar Pg.java # 2 运行 java -cp ./:./jars/postgresql-42.7.7.jar Pg ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/jdbc/","summary":"\u003ch1 id=\"1-使用jdbc的流程\"\u003e1 使用JDBC的流程\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e准备java环境\u003c/li\u003e\n\u003cli\u003e准备jdbc驱动\u003c/li\u003e\n\u003cli\u003e编写java代码\u003c/li\u003e\n\u003cli\u003e执行java代码\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"2-使用jdbc\"\u003e2 使用JDBC\u003c/h1\u003e\n\u003ch2 id=\"21-准备java环境\"\u003e2.1 准备java环境\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e安装java工具包\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esudo yum install -y java-1.8.0-openjdk java-1.8.0-openjdk-devel\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e验证java安装成功\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ejava -version\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# openjdk version \u0026#34;1.8.0_382\u0026#34; : 8表示java 8\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e执行java demo\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 编写代码\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003epublic class Demo {\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e    public static void main(String[] args) {\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e        System.out.println(\u0026#34;Hello World\u0026#34;);\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e    }\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e}\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u003c/span\u003e \u0026gt;\u0026gt; Demo.java\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 编译代码\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ejavac Demo.java\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 执行\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ejava Demo\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"22-准备jdbc驱动\"\u003e2.2 准备jdbc驱动\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etouch jdbc\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e jdbc\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir jars\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e jars\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ewget https://jdbc.postgresql.org/download/postgresql-42.7.7.jar\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e目录架构：\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e-- jdbc\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e|\u003c/span\u003e-- jars\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"p\"\u003e|\u003c/span\u003e-- postgresql-42.7.7.jar\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003ca href=\"https://polydistortion.net/bc/index.html\"\u003ehttps://polydistortion.net/bc/index.html\u003c/a\u003e\u003c/p\u003e","title":"jdbc"},{"content":"1 E100审计功能 1.1 功能简述 【审计功能】\n审计是重要的安全特性，核心功能是收集数据库内的事件，例如：登录用户、创建对象、查询数据等，根据事件生成与审计日志，存储审计日志，向用户提供日志查询接口。使用方式请看需求文档。\n【审计架构】\n审计整体架构如下图所示：（“线程“替换为“进程”，原图不小心弄丢了，不好修改了，将就看）\n【审计流程】\n1.2 实现方案 一、启动审计进程 1. 启动postmaster进程 # PostmasterMain 2. 加载GUC参数 # SelectConfigFiles 2.1 \u0026#39;---加载审计GUC---\u0026#39; 3. 创建共享内存和信号量 # reset_shared -\u0026gt; CreateSharedMemoryAndSemaphores 3.1 计算共享内存总大小 \u0026#39;计算审计共享内存大小：根据GUC配置\u0026#39; 3.2 创建共享内存 # PGSharedMemoryCreate 3.3 创建LwLock # CreateLWLocks 3.4 初始化wal-buffer共享内存 # XLOGShmemInit 3.5 初始化share-buffer共享内存 # InitBufferPool 3.6 \u0026#39;如果开启审计：初始化审计共享内存：划分共享内存，包括audit-buffer\u0026#39; 4. 启动sys-log进程 # SysLogger_Start 5. \u0026#39;如果开启审计：初始化审计模块\u0026#39; 5.1 \u0026#39;日志目录：检验与创建审计日志目录\u0026#39; 5.2 \u0026#39;日志文件：每次重启，使用新的日志文件，方便用户单个删除日志文件\u0026#39; 5.3 \u0026#39;内存上下文：创建审计全局内存上下文\u0026#39; 5.4 \u0026#39;审计缓存区：初始化audit-buffer\u0026#39; 5.5 \u0026#39;审计文件：初始化审计文件（并发write, read, delete日志）\u0026#39; 5.6 \u0026#39;回调函数：在执行DDL、计划、函数等关键函数中，注册生成审计事件、日志的回调函数\u0026#39; # 后面详细介绍 6. \u0026#39;如果开启审计：启动审计进程\u0026#39; 6.1 \u0026#39;信号：注册信号处理函数：sighup, sigquit, sigusr1\u0026#39; 6.2 \u0026#39;显示：设置ps命令显示的进程信息\u0026#39; 6.3 主循环 6.4 \u0026#39;等待事件：关键是timeout\u0026#39; 6.5 \u0026#39;存储日志：读取audit-buffer中待落盘的日志，并存储\u0026#39; # 后面详细介绍 6.6 \u0026#39;调整速率：按照每次落盘数据的长度，动态调整timeout\u0026#39; 连续多次为0，timeout依次变为1ms, 100ms, 1s 单次落盘长度大于16m，timeout=0 7. \u0026#39;主循环\u0026#39; # ServerLoop 7.1 接收客户端连接 # select 7.2 创建postgres进程 # BackendStartup -\u0026gt; BackendRun -\u0026gt; PostgresMain 7.3 检查与重启sys-log进程 # SysLogger_Start 7.4 \u0026#39;检查与重启审计进程\u0026#39; 7.5 检查与重启checkpointer进程 # StartCheckpointer 7.6 检查与重启wal-writer进程 # StartWalWriter 二、收集审计事件 目前，只有以下2类进程，会生成审计事件：\npostmaster：启动集群、停止集群 postgres：登录用户、登出用户、执行SQL postmaster进程 对于postmaster进程，事件类型为：启动、停止集群。收集事件的流程如下：\n1. 启动postmaster进程 # PostmasterMain 2. 加载GUC参数 # InitializeGucOptions 3. 检查数据库目录 # CheckDataDir audit_dir_init 3. 创建共享内存和信号量 # reset_shared 3.x \u0026#39;如果开启审计：初始化审计共享内存：划分共享内存，包括audit-buffer\u0026#39; 4. 启动sys-log进程 # SysLogger_Start 5. \u0026#39;如果开启审计：初始化审计模块\u0026#39; 5.x \u0026#39;如果开启审计：基于PG已有的hook框架，注册审计回调函数（身份认证、执行DDL、执行DML等）\u0026#39; 6. \u0026#39;如果开启审计：启动审计进程\u0026#39; 6.1 \u0026#39;生成审计事件：启动系统\u0026#39; 7. \u0026#39;主循环\u0026#39; # ServerLoop postgres进程 对于postgres进程，事件类型为：登录用户、执行DDL、执行DML、执行函数、执行其他语句、登出用户。收集的事件的流程如下：\n1. 启动postgres进程 # PostgresMain 2. 加载GUC参数 # SelectConfigFiles 3. 初始化共享内存和信号量 # BaseInit-\u0026gt;InitCommunication 4. 初始化postgres进程 # InitPostgres 4.1 初始化缓存 # InitCatalogCache 4.2 \u0026#39;注册进程结束回调函数：用户登出账号\u0026#39; 4.3 注册注册进程结束回调函数：清理事务、清理锁 # ShutdownPostgres 4.4 进行身份认证 # PerformAuthentication-\u0026gt;ClientAuthentication 4.4.1 校验密码 4.4.2 \u0026#39;执行回调函数：身份认证\u0026#39; 4.4.2.1 \u0026#39;执行审计回调函数：身份认证\u0026#39; 6. 主循环 7. 接收客户端数据 # ReadCommand 8. 重载SIGHUP级GUC参数 # ProcessConfigFile 9. 执行SQL # exec_simple_query 10. \u0026#39;记录当前原始SQL语句\u0026#39; 11. 语法解析 # pg_parse_query 12. 语义分析和查询重写 # pg_analyze_and_rewrite 13. 计划生成 # pg_plan_queries 13.1 预处理函数 # pg_plan_query-\u0026gt;planner-\u0026gt;..-\u0026gt;preprocess_expression 13.2 替换函数 # ExecInitFunc 13.3 \u0026#39;执行审计回调函数：执行函数\u0026#39; # RunFunctionExecuteHook 13.3.1 \u0026#39;执行审计回调函数：执行函数\u0026#39; 14. 执行 # PobtrtalRun-\u0026gt;PortalRunMulti 15. 执行DDL/DCL/等 # PortalRunUtility-\u0026gt;ProcessUtility 15.1 执行回调函数：处理DDL/DCL/等非DML # ProcessUtility_hook 15.1.1 \u0026#39;执行审计回调函数：处理DDL/DCL/等非DML\u0026#39; switch (nodeTag(parsetree)) { case T_CreatedbStmt: case T_DropStmt: case T_ExecuteStmt: case T_DoStmt: ... \u0026#39;工作量：识别所有DDL中的主体、操作、客体等信息\u0026#39; } 15.2 执行标准函数：处理DDL/DCL/等非DML # standard_ProcessUtility 16. 执行DML等 # ProcessQuery 17. 初始化计划 # ExecutorStart-\u0026gt;InitPlan 17.1 检查对象访问权限 # ExecCheckRTPerms 17.2 执行回调函数：检查对象访问权限 17.2.1 \u0026#39;执行审计回调函数：检查对象访问权限，入参为{操作、对象}的列表\u0026#39; （基于访问控制框架） 17.3 初始化算子 # ExecInitNode 17.3.1 初始化算子中的函数 # ExecInitFunc 17.3.2 执行回调函数：执行函数 # InvokeFunctionExecuteHook 17.3.2.1 \u0026#39;执行审计回调函数：执行函数\u0026#39; 18. 执行计划 # ExecutorRun-\u0026gt;ExecutePlan 18.1 执行算子 18.2 执行qual/project中的函数 # FunctionCallInvoke 18.3 执行回调函数：执行函数 # InvokeFunctionExecuteHook 18.3.1 \u0026#39;执行审计回调函数：执行函数\u0026#39; 18.4 调用heapam等接口 18.4.1 访问share-buffer 18.4.2 生成xlog 18.4.3 访问wal-buffer 19. 清理计划 # ExecutorEnd 20. 提交事务 # finish_xact_command-\u0026gt;CommitTransactionCommand-\u0026gt;CommitTransaction 21. 等待xlog落盘 # XLogFlush 22. \u0026#39;以后版本计划：审计同步落盘：等待审计日志落盘\u0026#39; 三、发送审计日志 审计缓冲区的模型如下：\n工作进程，发送日志的流程如下：\n1. 工作进程：发送审计日志，长度为x 2. 加锁：audit-buffer读锁 2. 加锁：预留空间自旋锁 3. 申请的预留位置 = \u0026#39;预留空间指针\u0026#39; 3. \u0026#39;预留空间指针\u0026#39; += x 2. 解锁：预留空间自旋锁 3. 写入审计日志到audit-buffer 4. \u0026#39;已写入指针\u0026#39; += x 3. 解锁：audit-buffer读锁 审计进程： 1. 申请audit-buffer写锁，需等待工作进程 2. 获取audit-buffer写锁时，一定满足\u0026#39;预留空间指针 == 已写入指针\u0026#39; (极低概率异常：\u0026#39;预留空间指针 != 已写入指针\u0026#39;，触发异常处理：检查日志，如果发现异常的，则丢弃异常之后的整段日志) 并发场景，工作流程如下：\n（假设：3个工作进程，并发发送日志，日志长度分为为a,b,c）\n时刻 工作进程1 工作进程2 工作进程3 工作线程4 审计进程 1 发送日志 - - - - 2 - 发送日志 - - - 3 - 发送日志 - - 4 获取读锁 - - - - 5 - 获取读锁 - - - 6 - - 获取读锁 - - 7 预留空间指针 + a - - - - 8 - 预留空间指针 + b - - - 9 - - 预留空间指针 + c - - 10 - - - - 申请写锁 11 已发送指针 + a - - - - 12 - 已发送指针 + b - - - 13 - - 已发送指针 + c - - 14 释放读锁 - - - - 15 - - - 申请读锁 - 16 - 释放读锁 - - - 17 - - 释放读锁 - - 18 - - - - 获取写锁 19 - - - - 获取待落盘长度 a + b + c 20 - - - - 落盘 a + b + c 21 - - - - 已落盘指针 + a + b + c 22 - - - - 释放写锁 23 - - - 获取读锁 - 五、组织审计日志 AuditFile：1个AuditFile，由多个AuditPage组成。大小固定为64M AuditPage：1个AuditPage，大小固定为4k，存储多条AuditLog。引入AuditPage的作用如下： 内容校验：CRC校验的粒度 并发控制：并发写日志、读日志、删日志时，判断是否需加锁保护 完整性保护：发生断电等异常时，避免只写入半条日志等特殊情况（1条日志跨越2个物理block） 快速查找：根据页面头部的时间信息，快速找打符合条件的日志 –\u0026gt;以后版本：哈希、加密、区块链的粒度 –\u0026gt;以后版本：方便从后往前读日志 AuditLog：1条审计日志。 六、读取审计日志 （这块并发管理写的不是很好，需再优化）\n以下3种场景，读日志存在并发冲突：\n审计进程：写日志，单进程 读到(正在写的文件，正在写的Page)，等待写锁 工作进程：读日志，多进程 并发读 工作进程：删日志，单进程 如果存在任意一个删进程，等待删锁 1. 工作进程执行pg_audit_log(begin_time, end_time) 2. 获取指定的最早和最晚时间 3. 如果为指定最晚时间，则最晚时间为当前时间 4. \u0026#39;初始化TupleStore\u0026#39; # 由PG提供，具有自动物化的功能 5. 扫描文件：查找日志目录所有文件，按文件名过滤不符合时间的文件 6. 排序文件：按文件名中的时间排序日志文件 7. 循环： 8. 读取日志： 8.1 打开文件：按顺序从头打开、读取文件 8.2 \u0026#39;并发控制：如果读取审计进程正在写的文件和AuditPage，则获取文件读锁\u0026#39; \u0026#39;提示：审计进程写日志时，获取文件写锁，不读日志时，无人竞争写锁\u0026#39; 8.3 读取AuditPage：1次读取1个AuditPage 8.4 获取AuditLog：1次获取1个AuditLog 9. \u0026#39;缓存日志：将日志缓存在TupleStore中，必要时自动物化\u0026#39; 10. \u0026#39;保护机制：如果日志条数 \u0026gt; 10000，则中止，并提示用户：\u0026#39; 日志数量过多，缩小begin_time和end_time的区间 七、删除审计日志 以下3种场景，删日志存在并发冲突：\n审计进程：写日志，单进程 删到（正在写的文件），等待写锁 工作进程：读日志，多进程 竞争删锁 工作进程：删日志，单进程 如果存在任意一个删进程，报错，只允许1个删进程 1. 工作进程执行pg_delete_audit_log(begin_time, end_time) 2. 同一时刻，只能有1个进程删除日志，否则报错 3. 如果为指定最晚时间，则最晚时间为当前时间 4. 扫描文件：查找日志目录所有文件，按文件名过滤不符合时间的文件 5. 排序文件：按文件名中的时间排序日志文件 6. 循环： 7. \u0026#39;并发控制：如果涉及审计进程在写的文件，则获取文件写锁，删除文件中符合条件的日志，更新审计进程write偏移\u0026#39; 8. 快速删除：根据文件名，获取文件中最早日志。读取文件最后1个Page，获取文件中最晚日志。可判断是否直接删除整个文件 9. 其他删除逻辑较简单，此处不再介绍 八、审计测试工具 release版本，audit_tool支持功能如下：\n解析日志文件 打印日志文件（复用内置函数pg_audit_log()的代码） debug版本，audit_tool额外支持\n随机生成日志文件与日志 删除审计日志（复用内置函数pg_audit_delete_log()的代码） 多进程并发生成、存储审计日志（复用audit-buffer、audit-writer进程的代码） 1.3 接口说明 用户接口\n新增4个函数\n-- 查看可选审计范围 pg_audit_scope() -- 查看审计日志 pg_audig_log() pg_audig_log(timestamptz begtime, timestamptz endtime) -- 删除审计日志 pg_audit_delete_log(timestamptz begtime, timestamptz endtime) 新增1个视图\nCREATE VIEW pg_audit_log AS SELECT * FROM pg_audig_log(); 新增1个工具\naudit_tool -h # 输出如下： audit_tool is a utility to process audit log. usage: audit_tool decode [options] audit_tool print [options] [options] could be: -h,-?, --help show this help, then exit -v, --version show the version of this tool, then exit -d, --direcotry=LOG_DIR directory of audit logs -f, --file=LOG_FILE audit log file -o, --output=DIR_OR_FILE used with the --direcotry or --file parameter -b, --begin-time=BEGIN_TIME the earliest audit log, format example: \u0026#39;2020/01/01 12:00:00\u0026#39; -e, --end-time=END_TIME the latest audit log 1. command to decode directory: audit_tool decode -d LOG_DIR [-o OUTPUT_DIR] [-b BEGIN_TIME] [-e END_TIME] 2. command to decode file: audit_tool decode -f LOG_FILE [-o OUTPUT_FILE] [-b BEGIN_TIME] [-e END_TIME] 代码接口\n此处仅列举审计模块对外接口：\n/* 资源管理 */ Size audit_shm_size(); /* 计算共享内存总大小 */ void audit_init_shmem(); /* 划分共享内存 */ void audit_init(); /* 初始化所有审计资源 */ /* 进程管理 */ int audit_writer_start(); /* 启动审计进程 */ void audit_writer_exit(); /* 退出审计进程 */ /* 事件管理：无法通过PG内置hook框架获取的事件 */ void audit_hook_logout_user(int code, Datum arg); /* 审计登出用户 */ void audit_hook_start_system(); /* 审计启动集群 */ void audit_hook_exit_system(int code, Datum arg); /* 审计停止集群 */ /* 事件管理：获取原始SQL语句（在执行器之前，可能生成事件） */ void audit_event_init(const char *sql); /* 记录原始SQL语句 */ /* 内置函数 */ Datum pg_audit_scope(PG_FUNCTION_ARGS); /* 查询可选审计范围 */ Datum pg_audit_log(PG_FUNCTION_ARGS); /* 查询审计日志 */ Datum pg_delete_audit_log(PG_FUNCTION_ARGS); /* 删除审计日志 */ 代码文件\n审计的关键代码都集中在审计文件夹下，以下文件包含审计90%以上的代码。\n| -- e100 |-- src |-- beckend |-- audit |-- audit.c # 所有审计的对外接口 |-- adt_config.c |-- adt_time.c |-- adt_query.c # 识别每种DML、DDL，收集事件 |-- adt_event.c |-- adt_log.c |-- adt_page.c |-- adt_file.c |-- adt_buffer.c |-- adt_writer.c |-- bin |-- adt_tool |-- adt_tool.c |-- 软链接：adt_config.c adt_event.c adt_log.c等 1.4 内存管理 共享内存 临时内存 收集事件 生成日志：临时申请内存（一般1k以内） 发送日志：销毁临时内存 1.5 安全 在执行以下3个函数时，检查是否具有审计权限：\n查询日志：pg_audit_log() 查询日志：pg_audit_log(begin_time, end_time) 删除日志：pg_audit_delete_log(begin_time, end_time)\n检查方式： 是否是superuser：访问pg_authid系统表，判断rolsuper列 是否是pg_monitor：访问pg_auth_members系统表，查找{roloid， member}符合{pg_monitor, 当前用户} 1.6 性能 实现方案中，发送审计日志章节，已介绍性能瓶颈。\n1.7 专利 无\n1.8 升级管理 新增5个GUC参数\n新增4个内置函数\n新增1个视图\n（新增1个功能audit_tool，无任何依赖）\n1.9 其他说明 无\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/9-design-e100-audit/","summary":"\u003ch1 id=\"1-e100审计功能\"\u003e1 E100审计功能\u003c/h1\u003e\n\u003ch2 id=\"11-功能简述\"\u003e1.1 功能简述\u003c/h2\u003e\n\u003cp\u003e【审计功能】\u003cbr\u003e\n审计是重要的安全特性，核心功能是收集数据库内的事件，例如：登录用户、创建对象、查询数据等，根据事件生成与审计日志，存储审计日志，向用户提供日志查询接口。使用方式请看需求文档。\u003c/p\u003e\n\u003cp\u003e【审计架构】\u003cbr\u003e\n审计整体架构如下图所示：（\u003cstrong\u003e“线程“替换为“进程”\u003c/strong\u003e，原图不小心弄丢了，不好修改了，将就看）\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"adt-1\" loading=\"lazy\" src=\"/images/ProjectDocs/9-design-e100-audit/adt-1.png\"\u003e\u003c/p\u003e\n\u003cp\u003e【审计流程】\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"adt-2\" loading=\"lazy\" src=\"/images/ProjectDocs/9-design-e100-audit/adt-2.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"12-实现方案\"\u003e1.2 实现方案\u003c/h2\u003e\n\u003ch3 id=\"一启动审计进程\"\u003e一、启动审计进程\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e1. 启动postmaster进程    \u003cspan class=\"c1\"\u003e# PostmasterMain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    2. 加载GUC参数      \u003cspan class=\"c1\"\u003e# SelectConfigFiles\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        2.1 \u003cspan class=\"s1\"\u003e\u0026#39;---加载审计GUC---\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    3. 创建共享内存和信号量     \u003cspan class=\"c1\"\u003e# reset_shared -\u0026gt; CreateSharedMemoryAndSemaphores\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        3.1 计算共享内存总大小\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"s1\"\u003e\u0026#39;计算审计共享内存大小：根据GUC配置\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        3.2 创建共享内存  \u003cspan class=\"c1\"\u003e# PGSharedMemoryCreate\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        3.3 创建LwLock   \u003cspan class=\"c1\"\u003e# CreateLWLocks\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        3.4 初始化wal-buffer共享内存 \u003cspan class=\"c1\"\u003e# XLOGShmemInit\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        3.5 初始化share-buffer共享内存 \u003cspan class=\"c1\"\u003e# InitBufferPool\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        3.6 \u003cspan class=\"s1\"\u003e\u0026#39;如果开启审计：初始化审计共享内存：划分共享内存，包括audit-buffer\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    4. 启动sys-log进程 \u003cspan class=\"c1\"\u003e# SysLogger_Start\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    5. \u003cspan class=\"s1\"\u003e\u0026#39;如果开启审计：初始化审计模块\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        5.1 \u003cspan class=\"s1\"\u003e\u0026#39;日志目录：检验与创建审计日志目录\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        5.2 \u003cspan class=\"s1\"\u003e\u0026#39;日志文件：每次重启，使用新的日志文件，方便用户单个删除日志文件\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        5.3 \u003cspan class=\"s1\"\u003e\u0026#39;内存上下文：创建审计全局内存上下文\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        5.4 \u003cspan class=\"s1\"\u003e\u0026#39;审计缓存区：初始化audit-buffer\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        5.5 \u003cspan class=\"s1\"\u003e\u0026#39;审计文件：初始化审计文件（并发write, read, delete日志）\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        5.6 \u003cspan class=\"s1\"\u003e\u0026#39;回调函数：在执行DDL、计划、函数等关键函数中，注册生成审计事件、日志的回调函数\u0026#39;\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 后面详细介绍\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    6. \u003cspan class=\"s1\"\u003e\u0026#39;如果开启审计：启动审计进程\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        6.1 \u003cspan class=\"s1\"\u003e\u0026#39;信号：注册信号处理函数：sighup, sigquit, sigusr1\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        6.2 \u003cspan class=\"s1\"\u003e\u0026#39;显示：设置ps命令显示的进程信息\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        6.3 主循环\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            6.4 \u003cspan class=\"s1\"\u003e\u0026#39;等待事件：关键是timeout\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            6.5 \u003cspan class=\"s1\"\u003e\u0026#39;存储日志：读取audit-buffer中待落盘的日志，并存储\u0026#39;\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 后面详细介绍\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            6.6 \u003cspan class=\"s1\"\u003e\u0026#39;调整速率：按照每次落盘数据的长度，动态调整timeout\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                连续多次为0，timeout依次变为1ms, 100ms, 1s\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                单次落盘长度大于16m，timeout\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"m\"\u003e0\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    7. \u003cspan class=\"s1\"\u003e\u0026#39;主循环\u0026#39;\u003c/span\u003e \u003cspan class=\"c1\"\u003e# ServerLoop\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        7.1 接收客户端连接       \u003cspan class=\"c1\"\u003e# select\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        7.2 创建postgres进程    \u003cspan class=\"c1\"\u003e# BackendStartup -\u0026gt; BackendRun -\u0026gt; PostgresMain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        7.3 检查与重启sys-log进程 \u003cspan class=\"c1\"\u003e# SysLogger_Start\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        7.4 \u003cspan class=\"s1\"\u003e\u0026#39;检查与重启审计进程\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        7.5 检查与重启checkpointer进程 \u003cspan class=\"c1\"\u003e# StartCheckpointer\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        7.6 检查与重启wal-writer进程   \u003cspan class=\"c1\"\u003e# StartWalWriter\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"二收集审计事件\"\u003e二、收集审计事件\u003c/h3\u003e\n\u003cp\u003e目前，只有以下2类进程，会生成审计事件：\u003c/p\u003e","title":"海量 9 设计 E100审计"},{"content":"1 简介 1.1 目的 审计是重要的安全特性，功能是收集数据库内的事件，例如创建对象、查询数据等，根据事件生成与存储审计日志，并向用户提供查询审计日志的接口。\n在303.7版本，E100首次引入审计特性，本文介绍E100审计特性的对外接口、功能约束、使用方式等信息。\n1.2 适用范围 E100，303.7及之后的版本\n1.3 术语定义、首字母缩写词和缩略语 无\n1.3 参考资料 G100审计特性：https://docs.vastdata.com.cn/zh_CN/VastbaseG100/V3.0.8/1/2f4fb0e4adcc49f8b19dd4710f2a6549 Oracle审计特性：https://docs.oracle.com/en/database/oracle/oracle-database/23/dbseg/part_6.html 开源组件pgaudit：https://www.modb.pro/db/105894 G100审计重构方案：https://doc.weixin.qq.com/doc/w3_AdwAfAa7AFkCNFLkO0AXJSUK7CICd?scode=AHUAfwdSAA8DKRU1G1AdwAfAa7AFk\u0026amp;version=4.1.38.6011\u0026amp;platform=win pg 14完整语法：https://www.postgresql.org/docs/14/sql-commands.html 2 E100审计特性 2.1 功能简述 【审计特性】\n审计特性，主要功能是记录数据库内的各种事件，并向用户提供查询事件的接口。事件包括：\n启动、恢复、切换、停止集群 登录、注销账号 创建、修改、删除数据库对象，包括：DATABASE、SCHEMA、TABLE等 插入、更新、删除、查询关系表 … 【审计事件】\n数据库内发生的事件，都可描述为\u0026lt;主体\u0026gt;\u0026lt;操作\u0026gt;\u0026lt;客体\u0026gt;\n主体：一般是数据库用户 客体：集群、账号、数据对象等 操作：针对不同客体，操作类型不一样。比如，对于TABLE，操作类型有：CREATE, INSERT, SELECT等。 【审计日志】\n发生事件时，审计特性会收集事件中的信息，将事件封装审计日志，审计日志中的关键内容包括：\n主体信息：用户名 操作信息：操作类型、操作时间、操作的SQL语句等 客体信息：客体类型、客体名称、客体属于哪个database、客体属于哪个schema 【审计流程】\n使用审计特性时，主要包括以下几个流程：\n配置审计功能：用户提前配置审计范围，即配置哪些事件需被审计。 生成审计日志：用户操作数据库时，产生审计事件，例如创建表、删除表等。内核收集事件信息，生成审计日志。 存储审计日志：内核存储审计日志至磁盘。 查询审计日志：用户查询审计日志，内核从磁盘读取审计日志。 删除审计日志 一个简单示例如下图所示：\n-- 1. 配置审计功能：确定哪些事件需审计 -- 2. 生成审计日志：用户执行SQL，产生事件\u0026lt;用户\u0026gt;\u0026lt;创建\u0026gt;\u0026lt;表\u0026gt;，根据事件生成日志 CREATE TABLE t1 (c1 INT, c2 TEXT); -- 3. 存储审计日志：内核自动存储日志 -- 4. 查询审计日志 SELECT * FROM pg_audit_log(); -- 预期输出（横向输出） -[ RECORD 1 ]--------------------------------- scope | subject | u1 -- 主体信息：用户名 optype | create -- 操作信息：create操作 optime | 2025-07-18 18:15:17.400009+08 -- 操作时间 opresult | object | table -- 客体信息：客体类型 objdb | postgres -- 客体信息：客体属于哪个database objnsp | public -- 客体信息：客体属于哪个schema objname | t1 -- 客体信息：客体名称 opxid | optid | pid | sql | create table t1(c1 int); -- 触发操作的SQL extra | 【友商对比】\n对比oracle、opengauss/g100、pgaudit\noracle\n配置审计功能：通过SQL语法配置，可按照权限、操作、对象、角色进行配置\nCREATE AUDIT POLICY ap1 PRIVILEGES privilege [ , privilege ..] -- privilege 子句，内置权限有200多种，示例：CREATE TABLE, ALTER USER ACTIONS action [ , action ..] -- aciton 子句，示例：SELECT,ALTER,DROP 。操作+对象组合，共有1900+ ON object [ , object ..] -- object 子句 ROLES role [ , role ..] -- role 子句 查询审计日志：通过视图查询，视图共80+列。此处列举常用输出：\nSELECT * FROM UNIFIED_AUDIT_TRAIL; -- 时间戳 -- 事件id -- 主体相关：用户名、客户端程序、操作系统用户、客户端主机、客户端IP、认证方式、认证数据等 -- 操作相关：事务ID、操作类型、原始SQL、返回码等 -- 客体相关：对象名、对象SCHEMA、对象类型、对象版本等 存储审计日志：存储于SYSAUX表空间，按表的格式存储。\n删除审计日志：通过函数删除，先设置归档时间，再根据归档时间删除日志\n-- 主动删除 DBMS_AUDIT_MGMT.SET_LAST_ARCHIVE_TIMESTAMP( .. last_archive_time =\u0026gt; TO_TIMESTAMP(\u0026#39;2024-06-01 00:00:00\u0026#39;, \u0026#39;YYYY-MM-DD HH24:MI:SS\u0026#39;) ) DBMS_AUDIT_MGMT.CLEAN_AUDIT_TRAIL( .. use_last_arch_timestamp =\u0026gt; TRUE ) -- 自动删除：创建自动清理任务，定时清理 opengauss/g100\n配置审计功能：传统审计通过GUC配置，统一审计通过SQL配置\n传统审计：\n-- 主体 audit_user 对白名单内的用户进行审计 full_audit_users 对白名单内的用户的所有操作进行审计 no_audit_client 对黑名单内的IP的用户不审计 -- 操作 audit_copy_exec 是否审计 COPY audit_dml_state 是否审计 INSERT、UPDATE、DELETE audit_dml_state_select 是否审计 SELECT audit_set_parameter 是否审计 SET audit_user_violation 是否越权操作 audit_operation_result 只记录操作：成功、失败、成功和失败 的日志 audit_transcation 是否审计TANSCATITON：提交、回滚 audit_login_logout 审计CLUSTER：{登录、注销} x {成功、失败} audit_user_locked 是否审计USER：锁定、解锁 audit_grant_revoke 是否审计USER：赋权、收权 audit_network_error 是否审计网络连接错误 audit_query_cancel 是否审计用户取消SELECT操作 audit_insufficient_space 是否记录SPACE：达到限额 audit_tool_error 是否审计 vb_dump、vb_dumpall、vb_restore 的异常 -- 客体 audit_system_object 审计OBJECT的范围：DATABASE、SCHEMA、TABLE、…等DDL操作 audit_database_process 是否审计CLUSTER：启动、停止、切换和恢复 audit_function_exec 是否审计FUNCTION：执行 audit_systerm_function_exec 是否审计FUNCTION：执行（内核写了一个白名单，共61个，例如pg_stat_activity，pg_switch_xlog等） audit_sequence_enabled 是否审计语句序列 audit_crypt_func 是否审计FUNCION （密码运算函数） audit_security_policy 是否审计POLICY 统一审计：首先，创建资源标签。然后，根据资源标签进行审计。可按照操作、对象、用户、IP等配置。\n-- 创建资源标签（对象组）：对象类型包括：TABLE,COLUMN,SCHEMA,VIEW,FUNCTION CREATE RESOURCE LABEL label_name ADD label_item_list [, ...]; -- 设置审计策略： CREATE AUDIT POLICY policy_name PRIVILEGES { DDL | ALL } -- DDL操作类型 ON LABEL resource_label_name [, ... ] -- 对象 ACCESS { DML | ALL } -- DML操作类型 ON LABEL resource_label_name [, ... ] -- 对象 FILTER ON FILTER_TYPE filter_value [, ... ] -- 过滤类型：用户、IP等 -- DDL: ALTER | ANALYZE | COMMENT | CREATE | DROP | GRANT | REVOKE | SET | SHOW -- DML: COPY | DEALLOCATE | DELETE_P | EXECUTE | REINDEX | INSERT | PREPARE | SELECT | TRUNCATE | UPDATE -- FILTER_TYPE: APP | ROLES | IP | TIME_PERIOD 查询审计日志：通过函数在线查询\nSELECT * FROM pg_query_audit(begintime, endtime); -- time -- 主体信息：用户id，用户名，客户端信息，节点，线程id，本地端口，远端端口 -- 操作信息：操作类型、操作结果、权限、SQL语句 -- 客体信息：database，客体名，详细信息 -- 其他：审计日志sm3 hash，hash校验结果 存储审计日志：存储在指定目录下，按二进制格式存储\nshow audit_directory; 删除审计日志：通过时间、空间限制，自动删除，或者通过函数主动删除。\n-- 自动删除：按时间或总空间保留日志，旧日志被覆盖 audit_resource_policy audit_file_remain_time; audit_space_limit; -- 主动删除：通过函数删除 SELECT pg_delete_audit(begintime, endtime); pgaudit\n配置审计功能：通过GUC参数配置。只能按照操作进行配置。\nALTER SYSTEM SET pgaudit.log TO \u0026#39;all, read, write, function, role, ddl, misc\u0026#39; -- read：SELECT等 -- write: INSERT、DELETE、UPDATE、TRUNCATE、COPY等 -- misc: FETCH, CHECKPOINT等 查看审计日志：只能在pg_log中查询日志，一行日志示例：\nAUDIT: SESSION,1,1,DDL,CREATE TABLE,TABLE,public.t1,create table t1( id int, name text); 存储审计日志：复用运行日志的存储功能，在pg_log中存储\n删除审计日志：不提供\n2.2 功能说明 2.2.1 使用流程 E100审计的关键设计如下：\n配置审计特性：参考pgaudit，通过GUC参数配置，按操作类型配置审计范围 存储审计日志：参考vastbase g100，生成日志后，将其存储在用户配置的目录下，文件格式为二进制格式 查看审计日志：参考vastbase g100，通过在线函数查询，或者通过工具离线将日志文件转换为普通log文件 删除审计日志：自动覆盖旧文件，或主动通过函数删除 场景一、配置审计特性 熟悉审计配置参数\n编号 参数名 默认值 取值范围 级别 功能 1 enable_audit off on, off postmaster 控制是否开启审计功能 2 aduit_directory 空 任意绝对路径 postmaster 审计日志存储目录。如果取值为空，则默认存储于”数据目录/vb_audit_log”下 3 audit_directory_size 128M [64M, -] postmaster 审计日志目录最大空间，如果文件目录达到限制时，最旧的日志文件将被新文件覆盖 4 audit_scope ddl,dcl all,ddl,dcl,dml,dql,tcl,func,mng,misc sighup 审计范围。可设置多个范围，示例：”ddl,dcl,dml” 5 audit_buffer_size 16M [1M, 1G] postmaster 内存中，审计日志缓冲区大小 开启审计特性\ngs_guc set -D $DATA_DIR -c \u0026#34;enable_audit=on\u0026#34; 设置审计范围\n-- 首先，查看可设置的审计范围： SELECT * FROM pg_audit_scope(); -- 预期输出： scope_type | operates -----------+---------------------------------------------------------------------- ddl | create,alter,drop,truncate,prepare,deallocate dcl | grant,revoke,create user,alter user,drop user dml | insert,update,delete,copy,merge,lock dql | select tcl | begin,start,commit,end,rollback,savepoint func | do,execute mng | set,show,vacuum,analyze,checkpoint,reindex,cluster,refresh,explian,load misc | fetch,move -- 然后，设置审计范围 ALTER SYSTEM SET audit_scope TO \u0026#39;ddl,dcl,dml\u0026#39; -- 其他：只要开启审计，启动、停止集群，登录、登出用户，都会被审计，不受参数控制。（oracle也有很多必须审计的事件） pg 14完整语法：https://www.postgresql.org/docs/14/sql-commands.html 场景二、生成审计日志 事件由SQL语句触发，执行SQL时，内核会自动生成审计日志。\n执行DDL\nCREATE TABLE t1 (c1 INT, c2 TEXT); 查看审计日志\nSELECT * FROM pg_audit_log(); -- 预期输出（设置\\x） -[ RECORD 1 ]--------------------------------- scope | ddl subject | u1 -- 主体信息：用户名 optype | create -- 操作信息：操作类型 optime | 2025-07-18 18:15:17.400009+08 -- 操作信息：操作时间 opresult | -- 操作结果：取值为 空 或 fail；目前，失败场景只支持：检查用户表权限失败、登录失败 object | table -- 客体信息：客体类型 objdb | postgres -- 客体信息：客体database objnsp | public -- 客体信息：客体schema objname | t1 -- 客体信息：客体名 opxid | -- 操作信息：本事务最近一次xid操作 optid | -- 操作信息：写操作时产生的事务id pid | 31648 -- 主体信息：操作的进程id sql | create table t1(c1 int); -- 原始SQL语句 extra | -- 其他信息：暂时保留，可能存储报错信息 执行DCL\n如果CREATE USER/ALTER USER语法中，包含密码，SQL语句中的密码会被替换为*号（需要根据password关键字识别）。\nCREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; GRANT ALL ON SCHEMA public TO u1; SELECT optype,object,objdb,objnsp,objname,sql FROM pg_audit_log(now() - interval\u0026#39;10s\u0026#39;, null); optype | object | objdb | objnsp | objname | sql --------+--------+----------+--------+---------+---------------------------------------- create | user | | | u1 | CREATE USER u1 PASSWORD \u0026#39;***********\u0026#39;; grant | schema | postgres | | public | GRANT ALL ON SCHEMA public TO u1; 执行DML\n约束：不支持审计系统表、系统视图\nINSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;); SELECT optype,object,objdb,objnsp,objname,sql FROM pg_audit_log(now() - interval\u0026#39;10s\u0026#39;, null); optype | object | objdb | objnsp | objname | sql --------+--------+----------+--------+---------+---------------------------------------- insert | table | postgres | public | t1 | INSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;); 执行FUNC\n约束：不支持审计系统函数（简单的操作符，=，\u0026lt;,\u0026gt;,等，实际都是函数）\nCREATE OR REPLACE FUNCTION my_concat(text1 text, text2 text) RETURNS text AS $$ SELECT text1 || text2; $$ LANGUAGE sql IMMUTABLE; SELECT my_concat(\u0026#39;abc\u0026#39;, \u0026#39;efg\u0026#39;); SELECT optype,object,objdb,objnsp,objname,sql FROM pg_audit_log(now() - interval\u0026#39;10s\u0026#39;, null); optype | object | objdb | objnsp | objname | sql ---------+----------+----------+--------+-----------+---------------------------------------- execute | function | postgres | public | my_concat | SELECT my_concat(\u0026#39;abc\u0026#39;, \u0026#39;efg\u0026#39;); 执行MNG\nVACUUM; SELECT optype,object,objdb,objnsp,objname,sql FROM pg_audit_log(now() - interval\u0026#39;10s\u0026#39;, null); optype | object | objdb | objnsp | objname | sql ---------+----------+----------+--------+-----------+---------------------------------------- vacuum | | postgres | | | VACUUM; 执行DDL与DML\nCREATE TABLE t2 AS SELECT * FROM t1; SELECT optype,object,objdb,objnsp,objname,pid,sql FROM pg_audit_log(now() - interval\u0026#39;10s\u0026#39;, null); optype | object | objdb | objnsp | objname | pid | sql --------+--------+----------+--------+---------+------+---------------------------------- create | table | postgres | public | t2 | 1399 | CREATE TABLE t2 AS SELECT * FROM t1; select | table | postgres | public | t1 | 1399 | (repeat) 执行DML与FUNC\nINSERT INTO t2 VALUES (1, my_concat(\u0026#39;abc\u0026#39;, \u0026#39;efg\u0026#39;)); SELECT optype,object,objdb,objnsp,objname,sql FROM pg_audit_log(now() - interval\u0026#39;10s\u0026#39;, null); optype | object | objdb | objnsp | objname | pid | sql ---------+-----------+----------+--------+-----------+------+---------------------------------- execute | function | postgres | public | my_concat | 1399 | CREATE TABLE t2 AS SELECT * FROM t1; select | table | postgres | public | t1 | 1399 | (repeat) 执行DDL、DML、FUNC\n约束：不支持审计在DDL语句中的函数（实现麻烦，pgaudit也有该问题，需要再研究下，不一定来得及）\nCREATE TABLE t3 AS SELECT c1,my_concat(c2, \u0026#39;_t3\u0026#39;) FROM t1; SELECT optype,object,objdb,objnsp,objname,sql FROM pg_audit_log(now() - interval\u0026#39;10s\u0026#39;, null); optype | object | objdb | objnsp | objname | pid | sql --------+--------+----------+--------+---------+------+---------------------------------- create | table | postgres | public | t3 | 1399 | CREATE TABLE t3 AS SELECT c1,my_concat(c2, \u0026#39;_t3\u0026#39;) FROM t1; select | table | postgres | public | t1 | 1399 | (repeat) 必须审计的内容\n启动、停止集群 登录、登出用户 其他操作\n操作类型与客体类型较多，此处不一一列举。\n操作类型：\nCREATE, ALTER, DROP, TRUNCATE GRANT, REVOKE, CREATE USER, ALTER USER, DROP USER INSERT, UPDATE, DELETE, COPY, MERGE, LOCK SELECT BEGIN, START, COMMIT, END, ROLLBACK, SAVEPOINT DO, EXECUTE SET, SHOW, VACUUM, ANALYZE, CHECKPOINT, REINDEX, CLUSTER, REFRESH, EXPLAIN, LOAD FETCH, MOVE 客体类型包括：\nDATABASE, SCHEMA, TABLE SPACE, TABLE, INDEX, VIEW, MATERIALIZED VIEW, SEQUENCE ROLE, USER, GROUP FUNCTION, PROCEDURE, TRIGGER RULE, TYPE, DOMAIN, EXTENSION, FOREIGN DATA WRAPPER, SERVER, USER MAPPING, FOREIGN TABLE, PUBLICATION, COLLATION, CONVERSION AGGREGATE, CAST, POLICY, STATISTICS, ACCESS METHOD, LANGUAGE, OPERATOR, ... 风险：部分DDL太复杂，客体名可能解析不完全，不过会保留原始SQL语句，不影响业务。\n场景三、查询审计日志 设置查询权限\n以下2种角色，可查询日志：\nsuperuser：包括初始用户。\npg_monitor: pg_monitor是内置角色，查询具有该角色的用户。\n-- 查看哪些用户时superuser SELECT rolsuper FROM pg_authid -- 将pg_monitor角色赋予普通用户 GRANT pg_monitor TO $user; -- 查看哪些用户具有pg_monitor角色 SELECT pg_get_userbyid(roleid) FROM pg_auth_members WHERE member = (SELECT oid FROM pg_authid WHERE rolname = \u0026#39;pg_monitor\u0026#39;) 在线查询pg_audit_query()\n查询所有日志\nSELECT * FROM pg_audit_query(); -- 预期输出（设置\\x） -[ RECORD 1 ]--------------------------------- scope | ddl subject | u1 -- 主体信息：用户名 optype | create -- 操作信息：操作类型 optime | 2025-07-18 18:15:17.400009+08 -- 操作信息：操作时间 opresult | -- 操作结果：取值为 空 或 fail；目前，失败场景只支持：检查用户表权限失败 object | table -- 客体信息：客体类型 objdb | postgres -- 客体信息：客体database objnsp | public -- 客体信息：客体schema objname | t1 -- 客体信息：客体名 opxid | -- 操作信息：本事务最近一次xid操作 optid | -- 操作信息：写操作时产生的事务id pid | 31648 -- 主体信息：操作的进程id sql | create table t1(c1 int); -- 原始SQL语句 extra | -- 其他信息：暂时保留，可能存储报错信息 在线查询pg_audit_query(timestamptz begtime, timestamptz endtime)\n按时间查询日志\nSELECT * FROM pg_audit_query(\u0026#39;2020-01-01 08:00:00\u0026#39;, NOW()); SELECT * FROM pg_audit_query(null, \u0026#39;2025-01-01 08:00:00\u0026#39;); 离线查询audit_tool\n-- 查看审计目录 show audit_direcotory; 离线解析日志\n# 1 查看日志文件 ll $audit_direcotory adt_2025_0718_1815_05_054161.blog adt_2025_0718_1903_21_389583.blog adt_2025_0718_1908_48_355815.blog adt_2025_0718_2030_01_938610.blog # 命名： adt_年_月日_时分_秒_微秒.blog # 格式： 二进制（主要是：时间、操作类型、客体类型等不是字符串） # 2 解析单个日志文件 audit_tool decode -f /data/pg_audit/adt_2025_0718_1815_05_054161.log -o adt_2025_0718_1815_05_054161.log # 解码后的单条日志： # 2025/07/18 18:15:17 400009 ddl shenkun create table postgres.public.t1 0,0 create table t1(c1 int);,- # 3 解析日志文件夹 audit_tool decode -d /data/pg_audit/ -o ./decoded_log/ 场景四、删除审计日志 自动删除日志文件\n-- 当审计目录下，总文件大小达到阈值时，最旧的文件将被覆盖 show audit_direcotry_size; 主动删除日志\nSELECT pg_delete_audit_log(\u0026#39;2020-01-01 08:00:00\u0026#39;, \u0026#39;2021-01-01 08:00:00\u0026#39;); -- 预期：再次查询该之间范围内的日志，查询结果为空 离线删除日志文件\nrm -f /data/pg_audit/adt_2025_0718_1815_05_054161.log 场景五、异常场景 配置异常\n如果配置异常，会导致数据库无法启动\n编号 参数名 默认值 取值范围 级别 功能 1 enable_audit off on, off postmaster 控制是否开启审计功能 2 aduit_directory 空 任意绝对路径 postmaster 审计日志存储目录。如果取值为空，则默认存储于”数据目录/vb_audit_log”下 3 audit_directory_size 128M [64M, -] postmaster 审计日志目录最大空间，如果文件目录达到限制时，最旧的日志文件将被新文件覆盖 4 audit_scope ddl,dcl all,ddl,dcl,dml,dql,tcl,func,mng,misc sighup 审计范围。可设置多个范围，示例：”ddl,dcl,dml” 5 audit_buffer_size 16M [1M, 1G] postmaster 内存中，审计日志缓冲区大小 运行异常\n异常场景 描述 预期结果 进程异常 kill 审计进程 自动重启进程，不影响业务，日志不丢失 文件异常 audit_direcotry运行时异常 审计功能异常，无法记录审计日志，不影响业务 文件异常 audit log已写完文件丢失 查询日志时，缺少部分日志，影响不大 文件异常 audit log正在写文件丢失 自动重新创建文件，不影响业务 2.2.2 配置参数和文件 新增5个GUC参数\n编号 参数名 默认值 取值范围 级别 功能 1 enable_audit off on, off postmaster 控制是否开启审计功能 2 aduit_directory 空 任意绝对路径 postmaster 审计日志存储目录。如果取值为空，则默认存储于”数据目录/vb_audit_log”下 3 audit_directory_size 128M [64M, -] postmaster 审计日志目录最大空间，如果文件目录达到限制时，最旧的日志文件将被新文件覆盖 4 audit_scope ddl,dcl all,ddl,dcl,dml,dql,tcl,func,mng,misc sighup 审计范围。可设置多个范围，示例：”ddl,dcl,dml” 5 audit_buffer_size 16M [1M, 1G] postmaster 内存中，审计日志缓冲区大小 2.2.3 数据相关性 日志文件夹：由audit_directory参数配置，默认在数据目录/vb_audit_log\n2.3 接口信息 新增4个函数\n-- 查看可选审计范围 pg_audit_scope() -- 查看审计日志 pg_audig_log() pg_audig_log(timestamptz begtime, timestamptz endtime) -- 删除审计日志 pg_delete_audit_log(timestamptz begtime, timestamptz endtime) 新增1个工具\naudit_tool -h # 输出如下： audit_tool is a utility to process audit log. usage: audit_tool decode [options] audit_tool print [options] [options] could be: -h,-?, --help show this help, then exit -v, --version show the version of this tool, then exit -d, --direcotry=LOG_DIR directory of audit logs -f, --file=LOG_FILE audit log file -o, --output=DIR_OR_FILE used with the --direcotry or --file parameter -b, --begin-time=BEGIN_TIME the earliest audit log, format example: \u0026#39;2020/01/01 12:00:00\u0026#39; -e, --end-time=END_TIME the latest audit log 1. command to decode directory: audit_tool decode -d LOG_DIR [-o OUTPUT_DIR] [-b BEGIN_TIME] [-e END_TIME] 2. command to decode file: audit_tool decode -f LOG_FILE [-o OUTPUT_FILE] [-b BEGIN_TIME] [-e END_TIME] 2.4 正反向行为 2.4.1 生效说明 查看是否开启审计功能\nshow enable_audit; 查看审计范围\nshow audit_scope; 查询审计日志\nSELECT * FROM pg_audit_log(); 2.4.2 提示信息 查询审计日志\n无权限时，提示需grant pg_monitor to current user 2.4.3 约束和依赖 审计范围：不支持审计系统表、系统视图、系统函数 审计目录：audit_direcotry取值需为绝对路径(默认值vb_audit_log除外) 日志存储：不支持同步落盘审计日志，即发生断电等异常时，可能丢失部分未及时落盘的日志(优先保证性能) 审计日志：1条SQL语句，最多生成100条审计日志 2.5 安全性 2.5.1 权限控制 查询日志：具有superuser或pg_monitor角色时，才可调用查询日志的函数 2.5.2 审计 无\n2.6 影响范围 2.6.1 对已有UDT,UDF, ECPG的影响 无\n2.6.2 对系统函数的影响 新增4个系统函数，已介绍\n2.6.3 对系统CATALOG的影响 无\n2.6.4 对xlog日志格式、数据格式的影响 无\n2.6.5 与其他功能交互时的行为表现 无\n2.6.6 版本兼容性 无\n2.7 指标相关 2.7.1 关键资源指标 CPU：开启审计后，执行审计范围内的SQL，都有可能生成审计日志 内存：占用共享内存，由audit_buffer_size配置 进程：新增1个进程，负责将审计日志落盘 网络：无 外存：占用外存，由audit_direcotry_size配置 2.7.2 系统性指标 无\n2.7.3 性能指标 性能指标：\naudit_scope取值为ddl,dcl时，与不开审计相比，tpcc性能劣化在5%以内 audit_scope取值为all，即审计含SELECT等所有操作，，与不开审计相比，tpcc性能劣化在30%以内 2.8 测试建议 DDL：需要构造多种类型的DDL\nDML：需要构造复杂的SQL\n2.8 其他说明 无\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/9-requirement-e100-audit/","summary":"\u003ch1 id=\"1-简介\"\u003e1 简介\u003c/h1\u003e\n\u003ch2 id=\"11-目的\"\u003e1.1 目的\u003c/h2\u003e\n\u003cp\u003e审计是重要的安全特性，功能是收集数据库内的事件，例如创建对象、查询数据等，根据事件生成与存储审计日志，并向用户提供查询审计日志的接口。\u003c/p\u003e\n\u003cp\u003e在303.7版本，E100首次引入审计特性，本文介绍E100审计特性的对外接口、功能约束、使用方式等信息。\u003c/p\u003e\n\u003ch2 id=\"12-适用范围\"\u003e1.2 适用范围\u003c/h2\u003e\n\u003cp\u003eE100，303.7及之后的版本\u003c/p\u003e\n\u003ch2 id=\"13-术语定义首字母缩写词和缩略语\"\u003e1.3 术语定义、首字母缩写词和缩略语\u003c/h2\u003e\n\u003cp\u003e无\u003c/p\u003e\n\u003ch2 id=\"13-参考资料\"\u003e1.3 参考资料\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eG100审计特性：\u003ca href=\"https://docs.vastdata.com.cn/zh_CN/VastbaseG100/V3.0.8/1/2f4fb0e4adcc49f8b19dd4710f2a6549\"\u003ehttps://docs.vastdata.com.cn/zh_CN/VastbaseG100/V3.0.8/1/2f4fb0e4adcc49f8b19dd4710f2a6549\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eOracle审计特性：\u003ca href=\"https://docs.oracle.com/en/database/oracle/oracle-database/23/dbseg/part_6.html\"\u003ehttps://docs.oracle.com/en/database/oracle/oracle-database/23/dbseg/part_6.html\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e开源组件pgaudit：\u003ca href=\"https://www.modb.pro/db/105894\"\u003ehttps://www.modb.pro/db/105894\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eG100审计重构方案：\u003ca href=\"https://doc.weixin.qq.com/doc/w3_AdwAfAa7AFkCNFLkO0AXJSUK7CICd?scode=AHUAfwdSAA8DKRU1G1AdwAfAa7AFk\u0026amp;version=4.1.38.6011\u0026amp;platform=win\"\u003ehttps://doc.weixin.qq.com/doc/w3_AdwAfAa7AFkCNFLkO0AXJSUK7CICd?scode=AHUAfwdSAA8DKRU1G1AdwAfAa7AFk\u0026amp;version=4.1.38.6011\u0026amp;platform=win\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003epg 14完整语法：\u003ca href=\"https://www.postgresql.org/docs/14/sql-commands.html\"\u003ehttps://www.postgresql.org/docs/14/sql-commands.html\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-e100审计特性\"\u003e2 E100审计特性\u003c/h1\u003e\n\u003ch2 id=\"21-功能简述\"\u003e2.1 功能简述\u003c/h2\u003e\n\u003cp\u003e【审计特性】\u003cbr\u003e\n审计特性，主要功能是记录数据库内的各种事件，并向用户提供查询事件的接口。事件包括：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e启动、恢复、切换、停止集群\u003c/li\u003e\n\u003cli\u003e登录、注销账号\u003c/li\u003e\n\u003cli\u003e创建、修改、删除数据库对象，包括：DATABASE、SCHEMA、TABLE等\u003c/li\u003e\n\u003cli\u003e插入、更新、删除、查询关系表\u003c/li\u003e\n\u003cli\u003e…\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e【审计事件】\u003cbr\u003e\n数据库内发生的事件，都可描述为\u0026lt;主体\u0026gt;\u0026lt;操作\u0026gt;\u0026lt;客体\u0026gt;\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e主体：一般是数据库用户\u003c/li\u003e\n\u003cli\u003e客体：集群、账号、数据对象等\u003c/li\u003e\n\u003cli\u003e操作：针对不同客体，操作类型不一样。比如，对于TABLE，操作类型有：CREATE, INSERT, SELECT等。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e【审计日志】\u003cbr\u003e\n发生事件时，审计特性会收集事件中的信息，将事件封装审计日志，审计日志中的关键内容包括：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e主体信息：用户名\u003c/li\u003e\n\u003cli\u003e操作信息：操作类型、操作时间、操作的SQL语句等\u003c/li\u003e\n\u003cli\u003e客体信息：客体类型、客体名称、客体属于哪个database、客体属于哪个schema\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e【审计流程】\u003cbr\u003e\n使用审计特性时，主要包括以下几个流程：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e配置审计功能：用户提前配置审计范围，即配置哪些事件需被审计。\u003c/li\u003e\n\u003cli\u003e生成审计日志：用户操作数据库时，产生审计事件，例如创建表、删除表等。内核收集事件信息，生成审计日志。\u003c/li\u003e\n\u003cli\u003e存储审计日志：内核存储审计日志至磁盘。\u003c/li\u003e\n\u003cli\u003e查询审计日志：用户查询审计日志，内核从磁盘读取审计日志。\u003c/li\u003e\n\u003cli\u003e删除审计日志\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e一个简单示例如下图所示：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 1. 配置审计功能：确定哪些事件需审计\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 2. 生成审计日志：用户执行SQL，产生事件\u0026lt;用户\u0026gt;\u0026lt;创建\u0026gt;\u0026lt;表\u0026gt;，根据事件生成日志\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3. 存储审计日志：内核自动存储日志\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 4. 查询审计日志\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_audit_log\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 预期输出（横向输出）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eRECORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"c1\"\u003e---------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003escope\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003esubject\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 主体信息：用户名\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eoptype\u003c/span\u003e\u003cspan class=\"w\"\u003e   \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecreate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 操作信息：create操作\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eoptime\u003c/span\u003e\u003cspan class=\"w\"\u003e   \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2025\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e07\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e18\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e18\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"mi\"\u003e15\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"mi\"\u003e17\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e400009\u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"mi\"\u003e08\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 操作时间\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eopresult\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003eobject\u003c/span\u003e\u003cspan class=\"w\"\u003e   \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etable\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 客体信息：客体类型\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eobjdb\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 客体信息：客体属于哪个database\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eobjnsp\u003c/span\u003e\u003cspan class=\"w\"\u003e   \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003epublic\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 客体信息：客体属于哪个schema\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eobjname\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 客体信息：客体名称\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eopxid\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eoptid\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003epid\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003esql\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecreate\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etable\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 触发操作的SQL\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eextra\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e【友商对比】\u003cbr\u003e\n对比oracle、opengauss/g100、pgaudit\u003c/p\u003e","title":"海量 9 需求 E100审计"},{"content":"1 简介 1.1 分享的主题 分享一些编写需求、设计文档经验\n1.2 分享的背景 背景：我写的需求文档，（相对）还算详细，所以有此次分享\n308.1，profile功能的需求文档：https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007196 根因：前公司流程繁重，被迫养成这种习惯。\n分享的内容：可分享的干货不多，我觉得，在写文档的过程中，大部分人想的很详细，只是没有编写到文档中，毕竟每个人都有自己的编写风格。所以，本文的重点，是介绍前公司流程与要求，并以我做过的需求为例，为大家提供一点参考。\n分享人经历：交过10+个不算小的需求，完整写过10+次需求与设计文档，格式与海量的接近。\n分享的局限：交付的需求，主要是安全方向，也涉及SQL、存储等多个模块，所以，本文主要以安全需求的角度写，其他模块的需求不一定适用。\n1.3 前公司的流程 与海量相比，前公司的交付流程，几乎一样：\n客户：提出需求 产品、项目、测试、架构等：审核需求 开发：撰写需求/设计文档 各角色：评审需求/设计文档 开发：编写代码 … 其中，在4.评审需求/设计文档环节，前公司区别较大：\n一、评审人员多\n编号 角色 评审人 目的 1 开发 安全组、SQL组、存储组、运维组、.. 避免影响其他模块，协助发现风险 2 测试 测试人、测试组长 学习新需求，识别测试重点 3 架构 架构设计 避免影响其他模块，确保后向兼容 4 资料 资料优化、资料审核 学习新需求 5 用例 用例审核 确保各种check可看护功能 6 其他 流程提升 - 二、评审通过难\n组内评审 线上评审：上述所有角色会上评审，不过，一般很多人会议冲突，关键靠线下评审 线下评审（关键流程）：各类角色共10+必选评审人，通过在线需求文档、设计文档了解需求，提出疑问，提出意见。开发分析解决后，找提出人确认意见，才算闭环。最后，所有必选评审人评审通过，才算完成流程。 在这种流程中，需求与设计文档，要满足很多要求：\n普适：考虑到其他组开发、测试、资料等角色，不熟悉本领域的基础知识，所以，需要详细介绍相关原理，很多原理需要从头介绍\n完整：要充分例举所有可能涉及风险，否则，评审人会认为未考虑到\n举例：做了1个需求，可以为表设置加密属性，需要考虑：系统表、用户表（atore表、ustore表、分区表、临时表、toast表、unlogged表、segment表、hashbuckent表、物化视图…）\n2 需求文档写作思路 2.1 分析过程 首先，客户提出需求，很多需求不够清晰。\n示例：\nprofile原始需求： 目前对于数据库用户的管理方式不够便捷，无法像Oracle为用户赋予一组安全策略。一些属性如密码有效期、密码过期天数、密码尝试次数等也只能全局设定，无法指定用户配置。 然后，以我的个人习惯，分析需求的流程如下：\n分析需求属于哪个模块\n举例：profile需求，分析关键词：密码、登录等，可确定需求属于身份认证模块 熟悉需求涉及的模块\n举例：我熟悉身份认证的习惯 熟悉身份认证原理（产品文档、AI、网上博客等）\n熟悉vastbase身份认证原理（产品文档、AI、网上博客）\n为什么需要这个模块 如何配置：GUC参数等 如何触发：连接参数、SQL语句等 如何存储元数据：系统表、文件 非核心功能有哪些：修改密码、删除密码、… 按自己理解，划分vastbase身份认证子模块/流程：\n配置参数 创建用户：设置密码 登录用户：提供密码 校验用户：检查密码，检查登录次数等 修改密码 xxx 识别需求属于哪个子模块（熟悉客户核心需要的东西）\n示例：profile需求，分析关键词：配置策略、全局设定、指定用户设置，可确定涉及的子模块：\n配置参数：可配置密码有效期等参数，以前是集群级GUC参数，客户想要用户级配置参数 识别可能涉及的子模块：（熟悉本需求的修改范围，修改工作量，需要详细学习的子模块）\n示例：本需求涉及很多配置参数，因此，很多流程都会被影响\n配置参数 创建用户 登录用户 校验用户：读取配置参数，校验密码有效期、密码过期天数、密码尝试次数 修改密码：读取配置参数，校验密码复用次数 xxx 熟悉友商现状\n示例：一般情况，客户提的需求，都能在友商产品中找到，我会先从oralce, sql server, postgresql, mysql等产品文档中，学习相关内容：\n熟悉oralcle身份认证模块：oracle profile做的比较好，客户的需求，其实就是想要oracle profile 熟悉oracle身份认证子模块 配置参数（有差异） 创建用户 .. oracle资料：https://docs.oracle.com/en/database/oracle/oracle-database/23/ mysql资料：https://mysql.net.cn/doc/refman/8.0/en/preface.html 设计需求接口（客户怎么使用本需求）\n示例：profile需求，参考友商，通过SQL语法，可以达到配置用户级参数的目的\nCREATE PROFILE {参数组名} LIMIT {参数名} {参数值}； ALTER USER {用户名} {参数组名}; 梳理代码流程（评估需求接口可行性）\n示例：身份认证流程如下:\n场景一、创建用户、密码\nexec_simple_query(\u0026#39;CREATE USER ..\u0026#39;) ... CreateRole AddAuthHistory transform \u0026#39;password_reuse_time\u0026#39; systable_beginscan(\u0026#39;pg_auth_history\u0026#39;) if password \u0026gt; \u0026#39;password_reuse_time\u0026#39; or \u0026#39;password_reuse_max\u0026#39;: # 校验密码复用条件 ok exec_simple_query(\u0026#39;ALTER USER ..\u0026#39;) AlterRole AddAuthHistory 场景一：登录用户、校验用户\n# 此处以未开启线程池为例 PostgresMain # 第一阶段：接受用户的密码，并进行一系列检查 InitBackendWorker InitSession CheckAuthentication PerformAuthentication port-\u0026gt;protocol_config-\u0026gt;fn_authenticate ClientAuthentication # 1. 从pg_hba.conf中，读取password校验方式 hba_getauthmethod sendAuthRequest # 2. 接收客户端的password，检查password是否正确 recv_and_check_password_packet crypt_verify # 3. 从系统表pg_user_status中，获取rolstatus字段，判断用户是否被锁 GetAccountLockedStatus SearchSysCache1(\u0026#39;pg_user_status\u0026#39;) # 4. 无论密码正确与否，更新与锁定账号相关的参数 if role is lock or unlock: TryUnlockAccount GetPasswordTimeOfTuple transform \u0026#39;password_lock_time\u0026#39; UpdateUnlockAccountTuples # 5. 如果密码失败次数较多，锁定账户 if passwrong: if master: TryLockAccount if \u0026gt; \u0026#39;failed_login_attempts\u0026#39; tableam_tops_modify_tuple(\u0026#39;pg_user_status\u0026#39;) elif standby: UpdateFailCountToHashTable if \u0026gt; \u0026#39;failed_login_attempts\u0026#39; lock # 6. 如果密码正确，检查密码有效期（仅vastbase有此函数） checkPasswordEffect getLeftEffectSpan transform \u0026#39;password_effect_time\u0026#39; if leftday \u0026lt; 0: \u0026#39;ERROR: password expired\u0026#39; # 第二阶段：循环接收用户的其他数据，比如SQL语句 for (;;) ReadCommand # 此处，每接收一条客户端的消息，都会检查一次 session_timeout # 如果开启profile，此处需要缓存该用户的profile idle_time参数，否则，每次都从profile系统表中读取，对性能影响较大 # 理论上，如果无用户更新profile idle_time参数，一个连接缓存一次即可，即一个连接仅需读取一次系统表 if \u0026gt; \u0026#39;session_timeout\u0026#39;: \u0026#39;ERROR: timeout\u0026#39; exec_simple_query(\u0026#39;SQL\u0026#39;) 2.2 编写需求文档 以海量的模板为例，需求文档内包含的内容如下：\n1 简介 1.1 目的\n（简单介绍需求是什么） 1.2 使用范围 1.3 术语 1.4 参考资料\n（oracle、mysql、postgreql、…相关产品中关于相关需求的介绍） 2 需求名称 2.1 功能简介\n（需求来源：客户原始诉求）\n（需求关联：需求属于哪个模块）（示例：profile需求，属于身份认证模块，用于配置身份认证参数）\n（需求背景：相关模块基本原理、使用流程。模块中，与需求有关的功能的现状）（示例：身份认证的基本原理、使用流程。其中，介绍在旧版本中，如何配置身份认证参数）\n（友商分析：友商相关模块的基本介绍，关于本需求的介绍）（示例：oracle, mysql等如何配置身份认证参数）\n（需求实现：简单介绍实现需求需做哪些事情）\n（需求约束：需求可以做到什么程度） 2.2 功能说明 2.2.1 使用流程（需求文档最重要的部分） （主成功场景：介绍核心功能。从用户的角度，介绍如何使用需求，如何查看需求相关元数据，如何判断需求是否生效。主要通过对外接口介绍：guc参数、连接参数、环境变量、sql语句、系统表、系统函数、系统视图、文件等）\n（配置数据库）\n（连接数据库）\n（执行相关操作，关键操作包含预期输出，比如，CREATE成功，预期系统表内新增一行记录等）\n（…） （扩展场景：1.相关功能: 从内核的角度，介绍该功能可能会对其他模块的影响。2.约束场景：哪些场景无法使用。3.复杂场景：主备场景、物理备份恢复场景等）（示例：相关功能中，假设需求与表相关，可能涉及系统表、用户表，astore表、ustore表、分区表、toast表、临时表、…） （异常场景：1.异常输入：用户随机使用，无操作等。2.特殊操作：攻击者DOS攻击等） 2.2.2 配置参数和文件 2.2.3 数据先关性 2.3 接口信息 2.4 正反向行为 2.4.1 说明 2.4.1 生效说明 2.4.2 提示信息 2.4.3 约束和依赖 2.5 安全性 2.5.1 权限控制 2.5.2 审计 2.6 影响范围 2.6.1 对已有UDT,UDF, ECPG的影响 2.6.2 对系统函数的影响 2.6.3 对系统CATALOG的影响 2.6.4 对xlog日志格式、数据格式的影响 2.6.5 与其他功能交互时的行为表现 2.6.6 版本兼容性 2.7 指标相关 2.7.1 关键资源指标 2.7.2 系统性指标 2.7.3 性能指标 2.8 测试建议 3 设计文档写作思路 3.1 设计流程 与海量相比，前公司设计文档的主要区别是：1个模块维护1份设计文档，新增需求时，在原有文档中补充内容。\n假设，需求名称是：全密态数据库支持国密算法，设计文档的内容包括：\n明确模块最核心的功能\n示例：全密态数据库核心功能 设计整体架构\n示例：全密态数据库整体架构 设计工作流程\n示例：全密态数据库：等值查询流程\n解释：\n定义主密钥： 历史需求列表：\n示例：全密态数据库 版本 变更 功能点 503.1 首次合入，支持密态等值查询 支持语法：INSERT, SELECT, UPDATE, .. 数据类型：int, text, xxx; 算法类型：aes_128_cbc, …； 密钥管理类型：hwc_kms, …； .. 503.2 支持函数与存储过程 支持语法：新增函数与存储过程，… 503.3 支持国密加密算法 算法类型：新增国密算法sm4_cbc，… 新需求实现思路\n新需求流程图\n3.2 编写设计文档 1 需求名称 1.1 功能简述\n（模块简介、需求简介）\n（模块架构图）\n（模块流程图）\n（需求列表）（示例：- 1.0.0 引入身份认证模块，支持xxx功能； - 2.2.15 身份认证新增xxx功能 - 3.0.8 身份认证新增xxx功能）\n（历史需求架构图）\n（历史需求流程图） 1.2 实现方案\n（需求实现思路）\n（需求流程图）\n（需求流程介绍）\n（文件等详细设计格式） 1.3 接口说明\n（SQL完整格式）\n（系统表元数据） 1.4 内存管理 1.5 安全 1.6 性能 1.7 专利 1.8 升级管理 1.9 其他说明 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/writing-requirement-and-design-docs/","summary":"\u003ch1 id=\"1-简介\"\u003e1 简介\u003c/h1\u003e\n\u003ch2 id=\"11-分享的主题\"\u003e1.1 分享的主题\u003c/h2\u003e\n\u003cp\u003e分享一些编写需求、设计文档经验\u003c/p\u003e\n\u003ch2 id=\"12-分享的背景\"\u003e1.2 分享的背景\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e背景：我写的需求文档，（相对）还算详细，所以有此次分享\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e308.1，profile功能的需求文档：\u003ca href=\"https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007196\"\u003ehttps://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007196\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e根因：前公司流程繁重，被迫养成这种习惯。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e分享的内容：可分享的干货不多，我觉得，在写文档的过程中，大部分人想的很详细，只是没有编写到文档中，毕竟每个人都有自己的编写风格。所以，本文的重点，是介绍前公司流程与要求，并以我做过的需求为例，为大家提供一点参考。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e分享人经历：交过10+个不算小的需求，完整写过10+次需求与设计文档，格式与海量的接近。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e分享的局限：交付的需求，主要是安全方向，也涉及SQL、存储等多个模块，所以，本文主要以安全需求的角度写，其他模块的需求不一定适用。\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg alt=\"scope\" loading=\"lazy\" src=\"/images/ProjectDocs/writing-requirement-and-design-docs/scope.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"13-前公司的流程\"\u003e1.3 前公司的流程\u003c/h2\u003e\n\u003cp\u003e与海量相比，前公司的交付流程，几乎一样：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e客户：提出需求\u003c/li\u003e\n\u003cli\u003e产品、项目、测试、架构等：审核需求\u003c/li\u003e\n\u003cli\u003e开发：撰写需求/设计文档\u003c/li\u003e\n\u003cli\u003e各角色：评审需求/设计文档\u003c/li\u003e\n\u003cli\u003e开发：编写代码\u003c/li\u003e\n\u003cli\u003e…\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e其中，在\u003ccode\u003e4.评审需求/设计文档\u003c/code\u003e环节，前公司区别较大：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e一、评审人员多\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e编号\u003c/th\u003e\n          \u003cth\u003e角色\u003c/th\u003e\n          \u003cth\u003e评审人\u003c/th\u003e\n          \u003cth\u003e目的\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e1\u003c/td\u003e\n          \u003ctd\u003e开发\u003c/td\u003e\n          \u003ctd\u003e安全组、SQL组、存储组、运维组、..\u003c/td\u003e\n          \u003ctd\u003e避免影响其他模块，协助发现风险\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e2\u003c/td\u003e\n          \u003ctd\u003e测试\u003c/td\u003e\n          \u003ctd\u003e测试人、测试组长\u003c/td\u003e\n          \u003ctd\u003e学习新需求，识别测试重点\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e3\u003c/td\u003e\n          \u003ctd\u003e架构\u003c/td\u003e\n          \u003ctd\u003e架构设计\u003c/td\u003e\n          \u003ctd\u003e避免影响其他模块，确保后向兼容\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e4\u003c/td\u003e\n          \u003ctd\u003e资料\u003c/td\u003e\n          \u003ctd\u003e资料优化、资料审核\u003c/td\u003e\n          \u003ctd\u003e学习新需求\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e5\u003c/td\u003e\n          \u003ctd\u003e用例\u003c/td\u003e\n          \u003ctd\u003e用例审核\u003c/td\u003e\n          \u003ctd\u003e确保各种check可看护功能\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e6\u003c/td\u003e\n          \u003ctd\u003e其他\u003c/td\u003e\n          \u003ctd\u003e流程提升\u003c/td\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e二、评审通过难\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e组内评审\u003c/li\u003e\n\u003cli\u003e线上评审：上述所有角色会上评审，不过，一般很多人会议冲突，关键靠线下评审\u003c/li\u003e\n\u003cli\u003e线下评审（关键流程）：各类角色共10+必选评审人，通过在线需求文档、设计文档了解需求，提出疑问，提出意见。开发分析解决后，找提出人确认意见，才算闭环。最后，所有必选评审人评审通过，才算完成流程。\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e在这种流程中，需求与设计文档，要满足很多要求：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e普适：考虑到其他组开发、测试、资料等角色，不熟悉本领域的基础知识，所以，需要详细介绍相关原理，很多原理需要从头介绍\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e完整：要充分例举所有可能涉及风险，否则，评审人会认为未考虑到\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e举例：做了1个需求，可以为表设置加密属性，需要考虑：系统表、用户表（atore表、ustore表、分区表、临时表、toast表、unlogged表、segment表、hashbuckent表、物化视图…）\u003c/p\u003e\u003c/blockquote\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"2-需求文档写作思路\"\u003e2 需求文档写作思路\u003c/h1\u003e\n\u003ch2 id=\"21-分析过程\"\u003e2.1 分析过程\u003c/h2\u003e\n\u003cp\u003e首先，客户提出需求，很多需求不够清晰。\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e示例：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eprofile原始需求：\n\u003cul\u003e\n\u003cli\u003e目前对于数据库用户的管理方式不够便捷，无法像Oracle为用户赋予一组安全策略。一些属性如密码有效期、密码过期天数、密码尝试次数等也只能全局设定，无法指定用户配置。\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\u003c/blockquote\u003e\n\u003cp\u003e然后，以我的个人习惯，分析需求的流程如下：\u003c/p\u003e","title":"分享编写需求/设计文档的个人经验"},{"content":" 配置审计功能\n通过GUC配置审计功能，新增GUC如下： 编号 参数名 默认值 取值范围 功能 1 enable_audit off on, off 控制是否开启审计功能 2 aduit_directory 空 任意绝对路径 审计日志存储目录，确保数据库用户有权访问。如果取值为空，则默认存储于”数据目录/vb_audit”下 3 audit_directory_size 64M [64M, -] 审计日志目录最大空间，如果文件目录达到限制时，最旧的日志文件将被新文件覆盖 4 audit_scope ddl all, ddl, insert, update, select, delete, function 审计范围。可设置多个范围，示例：”ddl, update, delete” 5 audit_buffer_size 16M [1M, 1G] 内存中，审计日志缓冲区大小 6 audit_detail basic,event,sql basic,event, sql 控制审计日志详细程度 7 audit_unclassfied on 启动审计功能\n设置审计参数后，重启数据库，内核关键变化如下： 申请共享内存：工作线程生成日志后，将日志写入共享内存，该内存为审计日志缓冲区，缓冲区大小由GUC参数audit_buffer_size控制 新增进程：新增1个线程，负责将审计缓存区中的日志，存储至文件 生成审计日志\n执行SQL语句时，如果SQL语句在审计范围内，内核一般会生成1条审计日志，如果SQL语句较复杂，语句中多个子操作会生成多条审计日志。 审计日志中，记录的内容如下：\n日志字段 示例 解释 主体类型 user 目前，主体类型只支持用户类型 主体名称 u1 执行操作的用户，即执行SQL前，与数据库建立连接的用户 操作类型 create 针对不同类型的对象，操作不同，例如，针对表有create, insert, select, ..等操作 操作时间 2025-05-01 12:00:01 678956 格式：年-月-日 时-分-秒 微秒 操作XID 20000 事务ID 操作LSN 0/170F5F0 该日志对应的SQL语句，最新生成的XLOG的写入位置 对象类型 table 数据库对象类型，包括database, schema, table, view, … 对象名称 t1 数据库对象名称 对象数据库 db1 对象属于哪个database 对象命名空间 sch1 对象属于哪个schema SQL语句 CREATE TABLE t1(c1 INT, c2 TEXT) 执行操作的原始SQL语句 存储审计日志\n在审计目录下，审计文件设计如下： 命名：格式为：adt_年_月日_时分_秒_微秒.alog，文件名中包含文件创建时间\n示例：\nadt_2025_0617_1909_12_425390.blog adt_2025_0617_1909_23_105450.blog adt_2025_0617_1909_23_352771.blog 格式：为节约空间，采用二进制格式存储日志。可通过内置的函数查询日志，或者通过离线工具audit_tool将二进制文件转换为普通字符文件。\n大小：单位日志文件最大为64M\n查询审计日志 可通过内置函数查询日志\nSELECT pg_audit_log(\u0026#34;开始时间\u0026#34;， \u0026#34;结束时间\u0026#34;); -- 示例： SELECT pg_audit_log(\u0026#39;2025-05-01 08:00:00\u0026#39;, NOW()); -- 输出（各字段对应的内容见上文） subjtype | subjname | optype | optime | opxid | oplsn | objtype | objname | ojbdb | ojbnsp | sql ---------+----------+--------+----------------------------+-------+-----------+---------+---------+-------+--------+------------------------- user | u1 | create | 2025-05-01 12:00:01 678956 | 20000 | 0/170F5F0 | table | t1 | db1 | shc1 | CREATE TABLE t1(c1 INT, c2 TEXT) user | u2 | insert | 2025-05-01 12:01:27 643511 | 2101 | 0/171A900 | table | t1 | db1 | sch1 | INSERT INTO t1 VALUES (1, \u0026#39;aa\u0026#39;), (2, \u0026#39;bb\u0026#39;); 可通过离线工具解析日志\naudit_tool decode -f /审计目录/审计文件 -o /任意目录/文件名 # 示例 audit_tool decode -f /data/aduit_log/adt_2025_0617_1909_12_425390.blog -o ./2025_0617_1909_12_425390.log 审计性能规格 性能：在业务场景下，或TPCC场景下： 审计范围为ddl，与不开审计相比，性能劣化在5%以内 审计范围为all，即审计含SELECT等所有操作，性能劣化在30%以内 审计注意事项 如果审计范围过大，短时间内生成的日志会非常多 -- 1 ddl CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; CREATE TABLE t1(c1 INT, c2 TEXT); CREATE TABLE t2 (c1 INT, c2 TEXT); CREATE INDEX i1 ON t1(c2); -- 2 dml INSERT INTO t1 VALUES (1, \u0026#39;aaa\u0026#39;), (2, \u0026#39;bbb\u0026#39;), (3, \u0026#39;ccc\u0026#39;); INSERT INTO t2 VALUES (1, \u0026#39;aaa\u0026#39;), (5, \u0026#39;bbb\u0026#39;); UPDATE t1 SET c2 = \u0026#39;ddd\u0026#39; WHERE c1 \u0026lt; 3; DELETE FROM t1 WHERE c1 = 2; -- 3 select SELECT * FROM t1; -- 4 function CREATE OR REPLACE FUNCTION my_concat(text1 text, text2 text) RETURNS text AS $$ SELECT text1 || text2; $$ LANGUAGE sql IMMUTABLE; SELECT c2 || \u0026#39;_oper\u0026#39; FROM t1; SELECT my_concat(\u0026#39;abc\u0026#39;, \u0026#39;efg\u0026#39;); SELECT my_concat(c2, \u0026#39;_func\u0026#39;) FROM t1; INSERT INTO t1 VALUES (5, my_concat(\u0026#39;aaa\u0026#39;, \u0026#39;_func\u0026#39;)), (6, my_concat(\u0026#39;aaa\u0026#39;, \u0026#39;_func\u0026#39;)); -- 5 dml \u0026amp; dml INSERT INTO t1 SELECT * FROM t2; SELECT * FROM t1 JOIN t2 ON t1.c1 = t2.c1; CREATE VIEW v1 AS SELECT t1.c1 FROM t1 JOIN t2 ON t1.c1 = t2.c1; SELECT * FROM v1; -- ddl \u0026amp; dml CREATE TABLE t3 AS SELECT * FROM t2; -- dml \u0026amp; function CREATE FUNCTION ft1() RETURNS TRIGGER AS $$ BEGIN SELECT count(*) FROM t1; RETURN NEW; END; $$ LANGUAGE plpgsql; -- ddl \u0026amp; dml \u0026amp; function -- clean DROP TABLE t1,t2,t3; SELECT * FROM pg_audit_log(\u0026#39;2025/07/01 12:00:00\u0026#39;, \u0026#39;2025/08/01 12:00:00\u0026#39;); SELECT * FROM pg_audit_log(\u0026#39;2025/07/01 12:00:00\u0026#39;, NOW()); SELECT * FROM pg_audit_log(NULL, NULL); SELECT * FROM pg_audit_log(); # result of \u0026#39;pg_audit_log\u0026#39; # proallargtypes =\u0026gt; \u0026#39;{timestamptz,text,text,text,text,text,text,int8,int8,text,text}\u0026#39;, # proargmodes =\u0026gt; \u0026#39;{o,o,o,o,o,o,o,o,o,o,o}\u0026#39;, # proargnames =\u0026gt; \u0026#39;{optime,subject,optype,object,objdb,objnsp,objname,opxid,optid,sql,extra}\u0026#39;, 设计思路：参考pgaudit 改进：function、改进 # pg 14 / E100 PostgresMain exec_simple_query() # 1. 执行SQL pg_parse_query() # 2. 解析语法、分析语义、重写查询、生成计划 pg_analyze_and_rewrite() pg_plan_queries() pg_plan_query() planner() planner_hook() # ----\u0026gt; standard_planner() ... preprocess_expression() # 函数预求值 ... ExecInitExpr() .. ExecInitFunc InvokeFunctionExecuteHook() RunFunctionExecuteHook() object_access_hook() PortalStart() PobtrtalRun() # 3. 执行计划 PortalRunMulti() if \u0026#39;DDL\u0026#39;: PortalRunUtility() # 执行DDL ProcessUtility() ProcessUtility_hook() standard_ProcessUtility() elif \u0026#39;DML\u0026#39;: ProcessQuery() # 执行DML ExecutorStart() ExecutorStart_hook() # ----\u0026gt; standard_ExecutorStart() InitPlan() ExecCheckRTPerms() ExecCheckRTEPerms() ExecutorCheckPerms_hook() ExecInitNode() ExecInitFunc() InvokeFunctionExecuteHook() RunFunctionExecuteHook() object_access_hook() ExecutorRun() ExecutorRun_hook() standard_ExecutorRun() ExecutePlan() ExecProcNode ... FunctionCallInvoke() ExecutorFinish() ExecutorFinish_hook() standard_ExecutorFinish() ExecutorEnd() # 4. 清理计划 ExecutorEnd_hook() standard_ExecutorEnd() PortalDrop() finish_xact_command() # 5. 提交事务 CommitTranscationCommand() XLogFlush(XactLastRecEnd) # 等待本事务最后1条xlog落盘 audit_flush() # 如果设置了同步落盘日志：等待本事务最后1条adtlog落盘 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/9-api-e100-audit/","summary":"\u003col\u003e\n\u003cli\u003e配置审计功能\u003cbr\u003e\n通过GUC配置审计功能，新增GUC如下：\u003c/li\u003e\n\u003c/ol\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e编号\u003c/th\u003e\n          \u003cth\u003e参数名\u003c/th\u003e\n          \u003cth\u003e默认值\u003c/th\u003e\n          \u003cth\u003e取值范围\u003c/th\u003e\n          \u003cth\u003e功能\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e1\u003c/td\u003e\n          \u003ctd\u003eenable_audit\u003c/td\u003e\n          \u003ctd\u003eoff\u003c/td\u003e\n          \u003ctd\u003eon, off\u003c/td\u003e\n          \u003ctd\u003e控制是否开启审计功能\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e2\u003c/td\u003e\n          \u003ctd\u003eaduit_directory\u003c/td\u003e\n          \u003ctd\u003e空\u003c/td\u003e\n          \u003ctd\u003e任意绝对路径\u003c/td\u003e\n          \u003ctd\u003e审计日志存储目录，确保数据库用户有权访问。如果取值为空，则默认存储于”数据目录/vb_audit”下\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e3\u003c/td\u003e\n          \u003ctd\u003eaudit_directory_size\u003c/td\u003e\n          \u003ctd\u003e64M\u003c/td\u003e\n          \u003ctd\u003e[64M, -]\u003c/td\u003e\n          \u003ctd\u003e审计日志目录最大空间，如果文件目录达到限制时，最旧的日志文件将被新文件覆盖\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e4\u003c/td\u003e\n          \u003ctd\u003eaudit_scope\u003c/td\u003e\n          \u003ctd\u003eddl\u003c/td\u003e\n          \u003ctd\u003eall, ddl, insert, update, select, delete, function\u003c/td\u003e\n          \u003ctd\u003e审计范围。可设置多个范围，示例：”ddl, update, delete”\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e5\u003c/td\u003e\n          \u003ctd\u003eaudit_buffer_size\u003c/td\u003e\n          \u003ctd\u003e16M\u003c/td\u003e\n          \u003ctd\u003e[1M, 1G]\u003c/td\u003e\n          \u003ctd\u003e内存中，审计日志缓冲区大小\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e6\u003c/td\u003e\n          \u003ctd\u003eaudit_detail\u003c/td\u003e\n          \u003ctd\u003ebasic,event,sql\u003c/td\u003e\n          \u003ctd\u003ebasic,event, sql\u003c/td\u003e\n          \u003ctd\u003e控制审计日志详细程度\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e7\u003c/td\u003e\n          \u003ctd\u003eaudit_unclassfied\u003c/td\u003e\n          \u003ctd\u003eon\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n          \u003ctd\u003e\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003col start=\"2\"\u003e\n\u003cli\u003e启动审计功能\u003cbr\u003e\n设置审计参数后，重启数据库，内核关键变化如下：\u003c/li\u003e\n\u003c/ol\u003e\n\u003cul\u003e\n\u003cli\u003e申请共享内存：工作线程生成日志后，将日志写入共享内存，该内存为审计日志缓冲区，缓冲区大小由GUC参数audit_buffer_size控制\u003c/li\u003e\n\u003cli\u003e新增进程：新增1个线程，负责将审计缓存区中的日志，存储至文件\u003c/li\u003e\n\u003c/ul\u003e\n\u003col start=\"3\"\u003e\n\u003cli\u003e生成审计日志\u003cbr\u003e\n执行SQL语句时，如果SQL语句在审计范围内，内核一般会生成1条审计日志，如果SQL语句较复杂，语句中多个子操作会生成多条审计日志。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e审计日志中，记录的内容如下：\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e日志字段\u003c/th\u003e\n          \u003cth\u003e示例\u003c/th\u003e\n          \u003cth\u003e解释\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e主体类型\u003c/td\u003e\n          \u003ctd\u003euser\u003c/td\u003e\n          \u003ctd\u003e目前，主体类型只支持用户类型\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e主体名称\u003c/td\u003e\n          \u003ctd\u003eu1\u003c/td\u003e\n          \u003ctd\u003e执行操作的用户，即执行SQL前，与数据库建立连接的用户\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e操作类型\u003c/td\u003e\n          \u003ctd\u003ecreate\u003c/td\u003e\n          \u003ctd\u003e针对不同类型的对象，操作不同，例如，针对表有create, insert, select, ..等操作\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e操作时间\u003c/td\u003e\n          \u003ctd\u003e2025-05-01 12:00:01 678956\u003c/td\u003e\n          \u003ctd\u003e格式：年-月-日 时-分-秒 微秒\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e操作XID\u003c/td\u003e\n          \u003ctd\u003e20000\u003c/td\u003e\n          \u003ctd\u003e事务ID\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e操作LSN\u003c/td\u003e\n          \u003ctd\u003e0/170F5F0\u003c/td\u003e\n          \u003ctd\u003e该日志对应的SQL语句，最新生成的XLOG的写入位置\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e对象类型\u003c/td\u003e\n          \u003ctd\u003etable\u003c/td\u003e\n          \u003ctd\u003e数据库对象类型，包括database, schema, table, view, …\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e对象名称\u003c/td\u003e\n          \u003ctd\u003et1\u003c/td\u003e\n          \u003ctd\u003e数据库对象名称\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e对象数据库\u003c/td\u003e\n          \u003ctd\u003edb1\u003c/td\u003e\n          \u003ctd\u003e对象属于哪个database\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e对象命名空间\u003c/td\u003e\n          \u003ctd\u003esch1\u003c/td\u003e\n          \u003ctd\u003e对象属于哪个schema\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003eSQL语句\u003c/td\u003e\n          \u003ctd\u003eCREATE TABLE t1(c1 INT, c2 TEXT)\u003c/td\u003e\n          \u003ctd\u003e执行操作的原始SQL语句\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003col start=\"4\"\u003e\n\u003cli\u003e存储审计日志\u003cbr\u003e\n在审计目录下，审计文件设计如下：\u003c/li\u003e\n\u003c/ol\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e命名：格式为：adt_年_月日_时分_秒_微秒.alog，文件名中包含文件创建时间\u003cbr\u003e\n示例：\u003c/p\u003e","title":"海量 9 接口 E100审计"},{"content":"yum install perf git clone https://github.com/brendangregg/FlameGraph.git touch perf.sh pids=$(pgrep $1 | head -n 4) rm -rf ./tmp_graph mkdir ./tmp_graph for pid in $pids; do echo \u0026#34;-- collecting data for $pid\u0026#34; perf record -F 600 -p $pid -g -- sleep 5 perf script -i perf.data \u0026gt; ./tmp_graph/perf.unfold.$pid ./flame/stackcollapse-perf.pl ./tmp_graph/perf.unfold.$pid \u0026gt; ./tmp_graph/perf.folded.$pid done cat ./tmp_graph/perf.folded.* \u0026gt; ./tmp_graph/all.folded ./flame/flamegraph.pl ./tmp_graph/all.folded \u0026gt; ./all.svg sh perf.sh 进程名 rm -rf ./tmp_graph mkdir ./tmp_graph pid=$1 echo \u0026#34;-- collecting data for $pid\u0026#34; perf record -F 600 -p $pid -g -- sleep 5 perf script -i perf.data \u0026gt; ./tmp_graph/perf.unfold.$pid ./flame/stackcollapse-perf.pl ./tmp_graph/perf.unfold.$pid \u0026gt; ./tmp_graph/perf.folded.$pid done cat ./tmp_graph/perf.folded.* \u0026gt; ./tmp_graph/all.folded ./flame/flamegraph.pl ./tmp_graph/all.folded \u0026gt; ./all.svg ","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/graph/","summary":"\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eyum install perf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit clone https://github.com/brendangregg/FlameGraph.git\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etouch perf.sh\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003epids\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003e$(\u003c/span\u003epgrep \u003cspan class=\"nv\"\u003e$1\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e head -n 4\u003cspan class=\"k\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003erm -rf ./tmp_graph\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir ./tmp_graph\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003efor\u003c/span\u003e pid in \u003cspan class=\"nv\"\u003e$pids\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"k\"\u003edo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;-- collecting data for \u003c/span\u003e\u003cspan class=\"nv\"\u003e$pid\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    perf record -F \u003cspan class=\"m\"\u003e600\u003c/span\u003e -p \u003cspan class=\"nv\"\u003e$pid\u003c/span\u003e -g -- sleep \u003cspan class=\"m\"\u003e5\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    perf script -i perf.data \u0026gt; ./tmp_graph/perf.unfold.\u003cspan class=\"nv\"\u003e$pid\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    ./flame/stackcollapse-perf.pl ./tmp_graph/perf.unfold.\u003cspan class=\"nv\"\u003e$pid\u003c/span\u003e \u0026gt; ./tmp_graph/perf.folded.\u003cspan class=\"nv\"\u003e$pid\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edone\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecat ./tmp_graph/perf.folded.* \u0026gt; ./tmp_graph/all.folded\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e./flame/flamegraph.pl ./tmp_graph/all.folded \u0026gt; ./all.svg\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esh perf.sh 进程名\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003erm -rf ./tmp_graph\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir ./tmp_graph\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003epid\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;-- collecting data for \u003c/span\u003e\u003cspan class=\"nv\"\u003e$pid\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eperf record -F \u003cspan class=\"m\"\u003e600\u003c/span\u003e -p \u003cspan class=\"nv\"\u003e$pid\u003c/span\u003e -g -- sleep \u003cspan class=\"m\"\u003e5\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eperf script -i perf.data \u0026gt; ./tmp_graph/perf.unfold.\u003cspan class=\"nv\"\u003e$pid\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e./flame/stackcollapse-perf.pl ./tmp_graph/perf.unfold.\u003cspan class=\"nv\"\u003e$pid\u003c/span\u003e \u0026gt; ./tmp_graph/perf.folded.\u003cspan class=\"nv\"\u003e$pid\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edone\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecat ./tmp_graph/perf.folded.* \u0026gt; ./tmp_graph/all.folded\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e./flame/flamegraph.pl ./tmp_graph/all.folded \u0026gt; ./all.svg\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"flamegraph 火焰图"},{"content":"1 E100 fdw +---- | User | 定义外表 -- \\c atlasdb -- ALTER SYSTEM SET password_encryption = \u0026#39;scram-sha-256\u0026#39;; -- SELECT pg_reload_conf(); -- SHOW password_encryption; -- 外部数据库：fdb1 CREATE DATABASE fdb1; CREATE USER fu1 PASSWORd \u0026#39;QAZ2wsx@123\u0026#39;; \\c fdb1 set role fu1; CREATE TABLE ft1 (c1 INT); INSERT INTO ft1 VALUES (11); reset role; -- 配置本地数据库 \\c atlasdb CREATE EXTENSION postgres_fdw; CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; CREATE SERVER s1 FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host \u0026#39;172.16.100.134\u0026#39;, port \u0026#39;5432\u0026#39;, dbname \u0026#39;fdb1\u0026#39;); GRANT ALL ON FOREIGN SERVER s1 TO u1; set role u1; CREATE FOREIGN TABLE t1 (c1 INT) SERVER s1 OPTIONS (schema_name \u0026#39;public\u0026#39;, table_name \u0026#39;ft1\u0026#39;); CREATE USER MAPPING FOR u1 SERVER s1 OPTIONS (user \u0026#39;fu1\u0026#39;, password \u0026#39;QAZ2wsx@123\u0026#39;); -- 配置远程登录 echo \u0026#39;host all u1 0.0.0.0/0 md5\u0026#39; \u0026gt;\u0026gt; $PG_HOME/data/atlasdb_hba.conf echo \u0026#39;host all fu1 0.0.0.0/0 md5\u0026#39; \u0026gt;\u0026gt; $PG_HOME/data/atlasdb_hba.conf echo \u0026#34;listen_addresses=\u0026#39;0.0.0.0\u0026#39;\u0026#34; \u0026gt;\u0026gt; $PG_HOME/data/atlasdb.conf pstop pstart -- 访问外表 set role u1; SELECT * FROM t1; SELECT * FROM pg_user_mapping; -- clean DROP SERVER s1 CASCADE; DROP USER u1; DROP DATABASE fdb1; DROP USER fu1; 2 G100 fdw 安装外部集群\n# 1. 安装外部集群，设置端口为6432 # 2. 创建数据库、用户、表 vsql -d postgres -p 6432 -c \u0026#34;CREATE DATABASE fdb1;\u0026#34; vsql -d postgres -p 6432 -c \u0026#34;CREATE USER fu1 PASSWORd \u0026#39;fu1.password\u0026#39;; \u0026#34; vsql -d fdb1 -p 6432 -c \u0026#34;CREATE TABLE ft1 (c1 INT); INSERT INTO ft1 VALUES (11); \u0026#34; 集群创建关联\n-- 1. 安装集群，该设置端口为5432（通过fdw从该集群访问外部集群） -- 2. 安装插件 \\c vastbase CREATE EXTENSION postgres_fdw; -- 3. 生成访问外部服务器的密码 \\! gs_guc generate -S \u0026#39;fu1.password\u0026#39; -D $GAUSSHOME/bin -o usermapping -- 3. 创建外部服务器 CREATE PUBLIC DATABASE LINK flink CONNECT TO fu1 IDENTIFIED BY \u0026#39;fu1.password\u0026#39; USING postgres_fdw(host \u0026#39;localhost\u0026#39;, port \u0026#39;6432\u0026#39;, dbname \u0026#39;fdb\u0026#39;); -- 4. 尝试访问外部服务器（报错没权限正常，因为fu1本就无权限访问ft1） SELECT * FROM ft1@flink; -- 5. 创建用户 CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;; CREATE USER u2 PASSWORD \u0026#39;u1.password\u0026#39;; -- 使用u1查询 SET ROLE u1 PASSWORD \u0026#39;u1.password\u0026#39;; SELECT count(*) FROM information_schema.columns@flink; 其他操作\n-- 使用u2查询 SET ROLE u2 PASSWORD \u0026#39;u2.password\u0026#39;; SELECT count(*) FROM information_schema.columns@flink; -- 6 查看dblink相关信息 SELECT oid,* FROM pg_foreign_data_wrapper; SELECT oid,* FROM pg_foreign_server; SELECT oid,* FROM pg_user_mapping; SELECT *,ftrelid::regclass FROM pg_foreign_table; -- 清理 DROP EXTENSION postgres_fdw CASCADE; DROP USER u1; DROP USER u2; PostgresMain exec_simple_query pg_analyze_and_rewrite parser_analzye transformTopLevelStmt taransfromStmt transformSelectStlt transformFromClause transformTableEntry parserOpenTable dblinkTableHandle execute_sql_string(\u0026#39;create schema vbdbkinl_pub....; grant all on schemma vbdblinkpub... to public; alter default privileges in schema vbdblinkpub...\u0026#39;) exec_simple_query PortalStart standatd_ExecutorStart InitPlan ExecInitNode ExecInitForeignScan postgresBeginForeignScan GetUserMapping SearchSysCache(\u0026#39;pg_user_mapping\u0026#39;) decryptUserMapping GetConnection connect_pg_server ","permalink":"https://my-blog.j8465383071.workers.dev/posts/postgresql/fdw/","summary":"\u003ch1 id=\"1-e100-fdw\"\u003e1 E100 fdw\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e+----\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e User\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003col\u003e\n\u003cli\u003e定义外表\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- \\c atlasdb\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- ALTER SYSTEM SET password_encryption = \u0026#39;scram-sha-256\u0026#39;;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- SELECT pg_reload_conf();\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- SHOW password_encryption;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 外部数据库：fdb1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efdb1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORd\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;QAZ2wsx@123\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efdb1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003erole\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eft1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eft1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e11\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003ereset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003erole\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 配置本地数据库\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"err\"\u003e\\\u003c/span\u003e\u003cspan class=\"k\"\u003ec\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eatlasdb\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eEXTENSION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres_fdw\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.password\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSERVER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOREIGN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATA\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eWRAPPER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres_fdw\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eOPTIONS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003ehost\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;172.16.100.134\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eport\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;5432\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;fdb1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eGRANT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eALL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOREIGN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSERVER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003erole\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOREIGN\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSERVER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eOPTIONS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003eschema_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;public\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etable_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;ft1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eMAPPING\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSERVER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eOPTIONS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003euser\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;fu1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;QAZ2wsx@123\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 配置远程登录\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eecho\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;host all u1 0.0.0.0/0 md5\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003ePG_HOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003eatlasdb_hba\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003econf\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eecho\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;host all fu1 0.0.0.0/0 md5\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003ePG_HOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003eatlasdb_hba\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003econf\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eecho\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;listen_addresses=\u0026#39;0.0.0.0\u0026#39;\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003ePG_HOME\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"k\"\u003edata\u003c/span\u003e\u003cspan class=\"o\"\u003e/\u003c/span\u003e\u003cspan class=\"n\"\u003eatlasdb\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003econf\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003epstop\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003epstart\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 访问外表\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eset\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003erole\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_user_mapping\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- clean\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSERVER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003es1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCASCADE\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efdb1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003efu1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"2-g100-fdw\"\u003e2 G100 fdw\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e安装外部集群\u003c/p\u003e","title":"PostgreSQL fdw"},{"content":"1 多线程框架 gcc thd.c -lpthread -o thd #include \u0026lt;stdio.h\u0026gt; #include \u0026lt;stdlib.h\u0026gt; #include \u0026lt;string.h\u0026gt; #include \u0026lt;stdbool.h\u0026gt; #include \u0026lt;pthread.h\u0026gt; #include \u0026lt;unistd.h\u0026gt; #include \u0026lt;semaphore.h\u0026gt; bool prtlog = true; #define ASSERT(cond) \\ if (!(cond)) {printf(\u0026#34;ASSERT | file: %s line: %d func: %s\\n\u0026#34;, __FILE__, __LINE__, __FUNCTION__); exit(-1);} #define LOG(thdctl, fmt, ...) \\ do { \\ if (prtlog) { \\ char data_[2048]; \\ snprintf(data_, 2048, (fmt), ##__VA_ARGS__); \\ thdctl != NULL ? \\ printf(\u0026#34; \u0026gt;%-3d %s\\n\u0026#34;, ((ThdCtl *)(thdctl))-\u0026gt;id, data_) : \\ printf(\u0026#34;%s\\n\u0026#34;, data_); \\ } \\ } while (0) /* ---------------------------------------------------------------------- */ typedef struct ThdCtl ThdCtl; typedef struct ThdData ThdData; typedef void (*ThdHookFunc)(ThdCtl *thdctl, ThdData *data); struct ThdCtl { /* thread info */ int stat; pthread_t thd; int id; /* thread function */ ThdHookFunc init_func; ThdHookFunc exec_func; ThdHookFunc exit_func; ThdData *data; /* thread control */ bool iswait; sem_t wait; }; typedef struct { int thdnum; ThdCtl *thdarr[10000]; } ProCtl; /* ---------------------------------------------------------------------- */ void multi_execute(ThdHookFunc initfunc, ThdHookFunc execfunc, ThdHookFunc exitfunc, int thdnum, ThdData *dataarr); typedef struct ThdData { int id; } ThdData; void init(ThdCtl *thdctl, ThdData *data) { LOG(thdctl, \u0026#34;init\u0026#34;); data-\u0026gt;id = thdctl-\u0026gt;id; } void execute(ThdCtl *thdctl, ThdData *data) { LOG(thdctl, \u0026#34;execute, id: %d\u0026#34;, data-\u0026gt;id); } void finish(ThdCtl *thdctl, ThdData *data) { LOG(thdctl, \u0026#34;finish, id: %d\u0026#34;, data-\u0026gt;id); } int main() { ThdData datas[10] = {0}; multi_execute(init, execute, finish, 10, datas); return 0; } /* ---------------------------------------------------------------------- */ void *thread_main(void *arg) { ThdCtl *tctl = (ThdCtl *)arg; if (tctl-\u0026gt;init_func != NULL) { tctl-\u0026gt;init_func(tctl, tctl-\u0026gt;data); } /* wait to be wake up */ // LOG(tctl, \u0026#34;sleep\u0026#34;); sem_wait(\u0026amp;tctl-\u0026gt;wait); /* wake up now */ // LOG(tctl, \u0026#34;wakeup\u0026#34;); tctl-\u0026gt;iswait = false; /* ====== user funtion begin ========== */ if (tctl-\u0026gt;exec_func != NULL) { tctl-\u0026gt;exec_func(tctl, tctl-\u0026gt;data); } /* ====== user funtion finish ========== */ if (tctl-\u0026gt;exit_func != NULL) { tctl-\u0026gt;exit_func(tctl, tctl-\u0026gt;data); } return NULL; } ThdCtl *create_thread(ProCtl *process, ThdHookFunc initfunc, ThdHookFunc execfunc, ThdHookFunc exitfunc, void *thddata) { static int thdid = 0; ThdCtl *t = (ThdCtl *)malloc(sizeof(ThdCtl)); if (t == NULL) { ASSERT(false); return NULL; } /* thread info */ t-\u0026gt;stat = -1; t-\u0026gt;id = thdid++; /* thread function */ t-\u0026gt;init_func = initfunc; t-\u0026gt;exec_func = execfunc; t-\u0026gt;exit_func = exitfunc; t-\u0026gt;data = thddata; t-\u0026gt;stat = pthread_create(\u0026amp;t-\u0026gt;thd, NULL, thread_main, t); /* thread control */ t-\u0026gt;iswait = true; sem_init(\u0026amp;t-\u0026gt;wait, 0, 0); process-\u0026gt;thdarr[process-\u0026gt;thdnum] = t; process-\u0026gt;thdnum++; return t; } ProCtl *create_process() { ProCtl *pro = (ProCtl *)malloc(sizeof(ProCtl)); ASSERT(pro != NULL); pro-\u0026gt;thdnum = 0; memset(pro-\u0026gt;thdarr, 0, sizeof(pro-\u0026gt;thdarr)); return pro; } void multi_execute(ThdHookFunc initfunc, ThdHookFunc execfunc, ThdHookFunc exitfunc, int thdnum, ThdData *dataarr) { ProCtl *pro = create_process(); LOG(NULL, \u0026#34;init ------------------------\u0026#34;); int i; for (i = 0; i \u0026lt; thdnum; i++) { create_thread(pro, initfunc, execfunc, exitfunc, \u0026amp;dataarr[i]); } LOG(NULL, \u0026#34;execute ------------------------\u0026#34;); for (i = 0; i \u0026lt; pro-\u0026gt;thdnum; i++) { ThdCtl *tctl = pro-\u0026gt;thdarr[i]; sem_post(\u0026amp;tctl-\u0026gt;wait); } for (i = 0; i \u0026lt; pro-\u0026gt;thdnum; i++) { pthread_join(pro-\u0026gt;thdarr[i]-\u0026gt;thd, NULL); } LOG(NULL, \u0026#34;finish ------------------------\u0026#34;); } 2 多线程示例 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/thread/","summary":"\u003ch1 id=\"1-多线程框架\"\u003e1 多线程框架\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egcc thd.c -lpthread -o thd\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;stdio.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;stdlib.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;string.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;stdbool.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;pthread.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;unistd.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#include\u003c/span\u003e \u003cspan class=\"cpf\"\u003e\u0026lt;semaphore.h\u0026gt;\u003c/span\u003e\u003cspan class=\"cp\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003eprtlog\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define ASSERT(cond) \\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e    if (!(cond)) {printf(\u0026#34;ASSERT | file: %s  line: %d  func: %s\\n\u0026#34;, __FILE__, __LINE__, __FUNCTION__); exit(-1);}\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e#define LOG(thdctl, fmt, ...)                                              \\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e    do {                                                                   \\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e        if (prtlog) {                                                      \\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e            char data_[2048];                                              \\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e            snprintf(data_, 2048, (fmt), ##__VA_ARGS__);                   \\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e            thdctl != NULL ?                                               \\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e                printf(\u0026#34;  \u0026gt;%-3d %s\\n\u0026#34;,  ((ThdCtl *)(thdctl))-\u0026gt;id, data_) : \\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e                printf(\u0026#34;%s\\n\u0026#34;, data_);                                     \\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e        }                                                                  \\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e    } while (0)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cp\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/*  ---------------------------------------------------------------------- */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003etypedef\u003c/span\u003e \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003eThdCtl\u003c/span\u003e \u003cspan class=\"n\"\u003eThdCtl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003etypedef\u003c/span\u003e \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003eThdData\u003c/span\u003e \u003cspan class=\"n\"\u003eThdData\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003etypedef\u003c/span\u003e \u003cspan class=\"nf\"\u003evoid\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eThdHookFunc\u003c/span\u003e\u003cspan class=\"p\"\u003e)(\u003c/span\u003e\u003cspan class=\"n\"\u003eThdCtl\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ethdctl\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eThdData\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003eThdCtl\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* thread info */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003estat\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003epthread_t\u003c/span\u003e \u003cspan class=\"n\"\u003ethd\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* thread function */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eThdHookFunc\u003c/span\u003e \u003cspan class=\"n\"\u003einit_func\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eThdHookFunc\u003c/span\u003e \u003cspan class=\"n\"\u003eexec_func\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eThdHookFunc\u003c/span\u003e \u003cspan class=\"n\"\u003eexit_func\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eThdData\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* thread control */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003ebool\u003c/span\u003e \u003cspan class=\"n\"\u003eiswait\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003esem_t\u003c/span\u003e \u003cspan class=\"n\"\u003ewait\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003etypedef\u003c/span\u003e \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ethdnum\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eThdCtl\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ethdarr\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e10000\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"n\"\u003eProCtl\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/*  ---------------------------------------------------------------------- */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003emulti_execute\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eThdHookFunc\u003c/span\u003e \u003cspan class=\"n\"\u003einitfunc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eThdHookFunc\u003c/span\u003e \u003cspan class=\"n\"\u003eexecfunc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eThdHookFunc\u003c/span\u003e \u003cspan class=\"n\"\u003eexitfunc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ethdnum\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eThdData\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003edataarr\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003etypedef\u003c/span\u003e \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"n\"\u003eThdData\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e \u003cspan class=\"n\"\u003eThdData\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003einit\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eThdCtl\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ethdctl\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eThdData\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eLOG\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ethdctl\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;init\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ethdctl\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eexecute\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eThdCtl\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ethdctl\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eThdData\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eLOG\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ethdctl\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;execute, id: %d\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003efinish\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eThdCtl\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ethdctl\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eThdData\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eLOG\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ethdctl\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;finish, id: %d\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003emain\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eThdData\u003c/span\u003e \u003cspan class=\"n\"\u003edatas\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003emulti_execute\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003einit\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eexecute\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003efinish\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003edatas\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/*  ---------------------------------------------------------------------- */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"nf\"\u003ethread_main\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003earg\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eThdCtl\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003etctl\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eThdCtl\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"n\"\u003earg\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etctl\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003einit_func\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003etctl\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"nf\"\u003einit_func\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etctl\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003etctl\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* wait to be wake up */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e// LOG(tctl, \u0026#34;sleep\u0026#34;);\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e    \u003cspan class=\"nf\"\u003esem_wait\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003etctl\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ewait\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* wake up now */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e// LOG(tctl, \u0026#34;wakeup\u0026#34;);\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e    \u003cspan class=\"n\"\u003etctl\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eiswait\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* ====== user funtion begin  ========== */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etctl\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eexec_func\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003etctl\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"nf\"\u003eexec_func\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etctl\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003etctl\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* ====== user funtion finish ========== */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etctl\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eexit_func\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003etctl\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"nf\"\u003eexit_func\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003etctl\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003etctl\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003edata\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eThdCtl\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"nf\"\u003ecreate_thread\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eProCtl\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eprocess\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eThdHookFunc\u003c/span\u003e \u003cspan class=\"n\"\u003einitfunc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eThdHookFunc\u003c/span\u003e \u003cspan class=\"n\"\u003eexecfunc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eThdHookFunc\u003c/span\u003e \u003cspan class=\"n\"\u003eexitfunc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003ethddata\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003estatic\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ethdid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eThdCtl\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003et\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eThdCtl\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"nf\"\u003emalloc\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003esizeof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eThdCtl\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003et\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003eASSERT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* thread info */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003et\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003estat\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003et\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eid\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ethdid\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* thread function */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003et\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003einit_func\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003einitfunc\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003et\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eexec_func\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eexecfunc\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003et\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eexit_func\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eexitfunc\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003et\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003edata\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003ethddata\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003et\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003estat\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003epthread_create\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003et\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ethd\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003ethread_main\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003et\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"cm\"\u003e/* thread control */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003et\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eiswait\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nb\"\u003etrue\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003esem_init\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003et\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ewait\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eprocess\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ethdarr\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003eprocess\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ethdnum\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003et\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eprocess\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ethdnum\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003et\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eProCtl\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"nf\"\u003ecreate_process\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eProCtl\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epro\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eProCtl\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"nf\"\u003emalloc\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003esizeof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eProCtl\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eASSERT\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epro\u003c/span\u003e \u003cspan class=\"o\"\u003e!=\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003epro\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ethdnum\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003ememset\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epro\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ethdarr\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"k\"\u003esizeof\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epro\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ethdarr\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003epro\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003emulti_execute\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eThdHookFunc\u003c/span\u003e \u003cspan class=\"n\"\u003einitfunc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eThdHookFunc\u003c/span\u003e \u003cspan class=\"n\"\u003eexecfunc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eThdHookFunc\u003c/span\u003e \u003cspan class=\"n\"\u003eexitfunc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ethdnum\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eThdData\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003edataarr\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eProCtl\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003epro\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"nf\"\u003ecreate_process\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eLOG\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;init ------------------------\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003ethdnum\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003ecreate_thread\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epro\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003einitfunc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eexecfunc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eexitfunc\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003edataarr\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eLOG\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;execute ------------------------\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003epro\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ethdnum\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eThdCtl\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003etctl\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003epro\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ethdarr\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e];\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003esem_post\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026amp;\u003c/span\u003e\u003cspan class=\"n\"\u003etctl\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ewait\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u003c/span\u003e \u003cspan class=\"n\"\u003epro\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ethdnum\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"o\"\u003e++\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"nf\"\u003epthread_join\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epro\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ethdarr\u003c/span\u003e\u003cspan class=\"p\"\u003e[\u003c/span\u003e\u003cspan class=\"n\"\u003ei\u003c/span\u003e\u003cspan class=\"p\"\u003e]\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003ethd\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"nf\"\u003eLOG\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"nb\"\u003eNULL\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"s\"\u003e\u0026#34;finish ------------------------\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"2-多线程示例\"\u003e2 多线程示例\u003c/h1\u003e","title":"工具 多线程 thread"},{"content":"# 安装nodejs yum install -y nodejs # 安装claude npm install -g @anthropic-ai/claude-code # 验证 claude --version cd /data/postgresql17 # 5. 启动 Claude Code 并进行首次认证 # 运行后，终端会提供一个链接，在浏览器中完成账号授权即可 claude # 6. (可选但推荐) 生成项目记忆文件 # 在 Claude 交互界面中，输入以下命令，它会分析项目并生成 CLAUDE.md 文件 /init ","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/feparser/","summary":"\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 安装nodejs\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eyum install -y nodejs\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 安装claude\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enpm install -g @anthropic-ai/claude-code\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 验证\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eclaude --version\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e /data/postgresql17\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 5. 启动 Claude Code 并进行首次认证\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 运行后，终端会提供一个链接，在浏览器中完成账号授权即可\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eclaude\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 6. (可选但推荐) 生成项目记忆文件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 在 Claude 交互界面中，输入以下命令，它会分析项目并生成 CLAUDE.md 文件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e/init\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"fepaser"},{"content":"非国密 生成证书 数据库服务端：配置证书、配置传输加密算法 数据库客户端：配置证书 # 检查openssl版本 which openssl # 确保使用的是vastbase发布包中的openssl，而非操作系统中的openssl cp $GAUSSHOME/share/sslcert/gsql/openssl.cnf ./ export OPENSSL_CONF=`pwd`/openssl.cnf # 创建文件 mkdir cert cd cert mkdir ./demoCA ./demoCA/newcerts ./demoCA/private chmod 700 ./demoCA/private echo \u0026#39;01\u0026#39;\u0026gt;./demoCA/serial touch ./demoCA/index.txt # ca openssl genrsa -out ./demoCA/private/cakey.pem 2048 openssl req -new -key ./demoCA/private/cakey.pem -out ./demoCA/private/ca_cert_req.pem -subj \u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=root\u0026#34; openssl x509 -req -in ./demoCA/private/ca_cert_req.pem -days 7300 -signkey ./demoCA/private/cakey.pem -out ./demoCA/cacert.pem # server openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr -subj \u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=server\u0026#34; openssl x509 -req -in server.csr -days 3650 -CA ./demoCA/cacert.pem -CAkey ./demoCA/private/cakey.pem -CAcreateserial -out server.crt # client openssl genrsa -out client.key 2048 openssl req -new -key client.key -out client.csr -subj \u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=client\u0026#34; openssl x509 -req -in client.csr -days 3650 -CA ./demoCA/cacert.pem -CAkey ./demoCA/private/cakey.pem -CAcreateserial -out client.crt # 查看内容 openssl x509 -in client.crt -text # 设置权限 chmod 600 client.key chmod 600 client.crt chmod 600 server.key chmod 600 server.crt chmod 600 ./demoCA/cacert.pem export CERT=`pwd` echo \u0026#39; export CERT=`pwd` export PGSSLMODE=verify-ca export PGSSLROOTCERT=$CERT/demoCA/cacert.pem export PGSSLKEY=$CERT/client.key export PGSSLCERT=$CERT/client.crt \u0026#39; \u0026gt; client_env source client_env # 设置服务端参数 gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl=on\u0026#34; gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl_ciphers = \u0026#39;ALL\u0026#39;\u0026#34; gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl_ca_file = \u0026#39;$CERT/demoCA/cacert.pem\u0026#39;\u0026#34; gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl_key_file=\u0026#39;$CERT/server.key\u0026#39;\u0026#34; gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl_cert_file=\u0026#39;$CERT/server.crt\u0026#39;\u0026#34; # 重启数据库 vsql -d postgres -c \u0026#34; CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39; \u0026#34; # 连接数据库：需加-h参数 vsql -h localhost -d postgres -U u1 -W \u0026#39;u1.password\u0026#39; -r rm -f client.* server.* gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl_ciphers = \u0026#39;ECDHE-ECDSA-SM4-CBC-SM3\u0026#39;\u0026#34; openssl ecparam -name SM2 -genkey -out ./demoCA/private/cakey.pem openssl req -new -key ./demoCA/private/cakey.pem -out ./demoCA/private/ca_cert_req.pem -subj \u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=root\u0026#34; openssl x509 -req -in ./demoCA/private/ca_cert_req.pem -days 7300 -signkey ./demoCA/private/cakey.pem -out ./demoCA/cacert.pem # server openssl ecparam -name SM2 -genkey -out server.key openssl req -new -key server.key -out server.csr -subj \u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=server\u0026#34; openssl x509 -req -in server.csr -days 3650 -CA ./demoCA/cacert.pem -CAkey ./demoCA/private/cakey.pem -CAcreateserial -out server.crt # client openssl ecparam -name SM2 -genkey -out client.key openssl req -new -key client.key -out client.csr -subj \u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=client\u0026#34; openssl x509 -req -in client.csr -days 3650 -CA ./demoCA/cacert.pem -CAkey ./demoCA/private/cakey.pem -CAcreateserial -out client.crt chmod 600 client.key client.crt server.key server.crt ./demoCA/cacert.pem openssl x509 -in client.crt -text 国密 mkdir cert cd cert openssl version # OpenSSL 1.1.1s Tassl 2.1.2 1 Nov 2022 cp ../tassl/install/openssl.cnf ./ chmod +w ./openssl.cnf echo \u0026#39; [ gm_ca_cert ] subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer basicConstraints = critical,CA:true keyUsage = critical, cRLSign, keyCertSign [ gm_sign_cert ] basicConstraints = CA:FALSE keyUsage = critical, digitalSignature, nonRepudiation [ gm_enc_cert ] basicConstraints = CA:FALSE keyUsage = critical, keyEncipherment, dataEncipherment, keyAgreement\u0026#39; \u0026gt;\u0026gt; ./openssl.cnf mkdir ./demoCA ./demoCA/newcerts ./demoCA/private chmod 700 ./demoCA/private echo \u0026#39;01\u0026#39;\u0026gt;./demoCA/serial touch ./demoCA/index.txt # ca openssl ecparam -name SM2 -genkey -out ./demoCA/private/cakey.pem openssl req -config openssl.cnf -new -key ./demoCA/private/cakey.pem -sm3 -out ./demoCA/private/ca_cert_req.pem -subj \u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=root\u0026#34; openssl x509 -req -extfile openssl.cnf -extensions gm_ca_cert -in ./demoCA/private/ca_cert_req.pem -sm3 -days 7300 -signkey ./demoCA/private/cakey.pem -out ./demoCA/cacert.pem # server openssl ecparam -name SM2 -genkey -out server.key openssl ec -in server.key -passout pass:gauss@123 -sm4 -out server.key openssl req -config openssl.cnf -new -key server.key -passin pass:gauss@123 -sm3 -out server.csr -subj \u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=server\u0026#34; openssl x509 -req -extfile openssl.cnf -extensions gm_sign_cert -in server.csr -sm3 -days 3650 -CA ./demoCA/cacert.pem -CAkey ./demoCA/private/cakey.pem -passin pass:gauss@123 -CAcreateserial -out server.crt # server.enc openssl ecparam -name SM2 -genkey -out server_enc.key openssl ec -in server_enc.key -passout pass:gauss@123 -sm4 -out server_enc.key openssl req -config openssl.cnf -new -key server_enc.key -passin pass:gauss@123 -sm3 -out server_enc.csr -subj \u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=server\u0026#34; openssl x509 -req -extfile openssl.cnf -extensions gm_enc_cert -in server_enc.csr -sm3 -days 3650 -CA ./demoCA/cacert.pem -CAkey ./demoCA/private/cakey.pem -passin pass:gauss@123 -CAcreateserial -out server_enc.crt gs_guc encrypt -M server -D ./ -K gauss@123 # client openssl ecparam -name SM2 -genkey -out client.key openssl ec -in client.key -passout pass:gauss@123 -sm4 -out client.key openssl req -config openssl.cnf -new -key client.key -passin pass:gauss@123 -sm3 -out client.csr -subj \u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=client\u0026#34; openssl x509 -req -extfile openssl.cnf -extensions gm_sign_cert -in client.csr -sm3 -days 3650 -CA ./demoCA/cacert.pem -CAkey ./demoCA/private/cakey.pem -passin pass:gauss@123 -CAcreateserial -out client.crt # client.enc openssl ecparam -name SM2 -genkey -out client_enc.key openssl ec -in client_enc.key -passout pass:gauss@123 -sm4 -out client_enc.key openssl req -config openssl.cnf -new -key client_enc.key -passin pass:gauss@123 -sm3 -out client_enc.csr -subj \u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=client\u0026#34; openssl x509 -req -extfile openssl.cnf -extensions gm_enc_cert -in client_enc.csr -sm3 -days 3650 -CA ./demoCA/cacert.pem -CAkey ./demoCA/private/cakey.pem -passin pass:gauss@123 -CAcreateserial -out client_enc.crt gs_guc encrypt -M client -D ./ -K gauss@123 # openssl x509 -in client.crt -text export CERT=`pwd` echo \u0026#39; export CERT=`pwd` export PGSSLMODE=verify-ca export PGSSLTLCP=1 export PGSSLROOTCERT=$CERT/demoCA/cacert.pem export PGSSLKEY=$CERT/client.key export PGSSLCERT=$CERT/client.crt export PGSSLENCKEY=$CERT/client_enc.key export PGSSLENCCERT=$CERT/client_enc.crt \u0026#39; \u0026gt; client_env source client_env # 设置服务端参数 gs_guc set -D $GAUSSHOME/data/single_node -c \u0026#34;ssl=on\u0026#34; gs_guc set -D $GAUSSHOME/data/single_node -c \u0026#34;ssl_ciphers = \u0026#39;ALL\u0026#39;\u0026#34; gs_guc set -D $GAUSSHOME/data/single_node -c \u0026#34;ssl_use_tlcp=on\u0026#34; gs_guc set -D $GAUSSHOME/data/single_node -c \u0026#34;ssl_ca_file = \u0026#39;$CERT/demoCA/cacert.pem\u0026#39;\u0026#34; gs_guc set -D $GAUSSHOME/data/single_node -c \u0026#34;ssl_key_file=\u0026#39;$CERT/server.key\u0026#39;\u0026#34; gs_guc set -D $GAUSSHOME/data/single_node -c \u0026#34;ssl_cert_file=\u0026#39;$CERT/server.crt\u0026#39;\u0026#34; gs_guc set -D $GAUSSHOME/data/single_node -c \u0026#34;ssl_enc_key_file=\u0026#39;$CERT/server_enc.key\u0026#39;\u0026#34; gs_guc set -D $GAUSSHOME/data/single_node -c \u0026#34;ssl_enc_cert_file=\u0026#39;$CERT/server_enc.crt\u0026#39;\u0026#34; # 重启数据库 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/transport-encryption/","summary":"\u003ch1 id=\"非国密\"\u003e非国密\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e生成证书\u003c/li\u003e\n\u003cli\u003e数据库服务端：配置证书、配置传输加密算法\u003c/li\u003e\n\u003cli\u003e数据库客户端：配置证书\u003c/li\u003e\n\u003c/ol\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 检查openssl版本\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ewhich openssl\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 确保使用的是vastbase发布包中的openssl，而非操作系统中的openssl\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/share/sslcert/gsql/openssl.cnf ./\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eOPENSSL_CONF\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e/openssl.cnf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 创建文件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir cert\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e cert\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir ./demoCA ./demoCA/newcerts ./demoCA/private\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod \u003cspan class=\"m\"\u003e700\u003c/span\u003e ./demoCA/private\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;01\u0026#39;\u003c/span\u003e\u0026gt;./demoCA/serial\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etouch ./demoCA/index.txt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# ca\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl genrsa -out ./demoCA/private/cakey.pem \u003cspan class=\"m\"\u003e2048\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -new -key ./demoCA/private/cakey.pem -out ./demoCA/private/ca_cert_req.pem -subj \u003cspan class=\"s2\"\u003e\u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=root\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -req -in ./demoCA/private/ca_cert_req.pem -days \u003cspan class=\"m\"\u003e7300\u003c/span\u003e -signkey ./demoCA/private/cakey.pem -out ./demoCA/cacert.pem\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# server\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl genrsa -out server.key \u003cspan class=\"m\"\u003e2048\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -new -key server.key -out server.csr -subj \u003cspan class=\"s2\"\u003e\u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=server\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -req -in server.csr -days \u003cspan class=\"m\"\u003e3650\u003c/span\u003e -CA ./demoCA/cacert.pem -CAkey ./demoCA/private/cakey.pem -CAcreateserial -out server.crt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# client\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl genrsa -out client.key \u003cspan class=\"m\"\u003e2048\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -new -key client.key -out client.csr -subj \u003cspan class=\"s2\"\u003e\u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=client\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -req -in client.csr -days \u003cspan class=\"m\"\u003e3650\u003c/span\u003e -CA ./demoCA/cacert.pem -CAkey ./demoCA/private/cakey.pem -CAcreateserial -out client.crt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 查看内容\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -in client.crt -text\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 设置权限\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod \u003cspan class=\"m\"\u003e600\u003c/span\u003e client.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod \u003cspan class=\"m\"\u003e600\u003c/span\u003e client.crt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod \u003cspan class=\"m\"\u003e600\u003c/span\u003e server.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod \u003cspan class=\"m\"\u003e600\u003c/span\u003e server.crt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod \u003cspan class=\"m\"\u003e600\u003c/span\u003e ./demoCA/cacert.pem\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCERT\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport CERT=`pwd`\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLMODE=verify-ca\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLROOTCERT=$CERT/demoCA/cacert.pem\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLKEY=$CERT/client.key\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLCERT=$CERT/client.crt\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u003c/span\u003e \u0026gt; client_env\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003esource\u003c/span\u003e client_env\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 设置服务端参数\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl=on\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_ciphers = \u0026#39;ALL\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_ca_file = \u0026#39;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$CERT\u003c/span\u003e\u003cspan class=\"s2\"\u003e/demoCA/cacert.pem\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_key_file=\u0026#39;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$CERT\u003c/span\u003e\u003cspan class=\"s2\"\u003e/server.key\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_cert_file=\u0026#39;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$CERT\u003c/span\u003e\u003cspan class=\"s2\"\u003e/server.crt\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 重启数据库\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -d postgres -c \u003cspan class=\"s2\"\u003e\u0026#34; CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39; \u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 连接数据库：需加-h参数\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -h localhost -d postgres -U u1 -W \u003cspan class=\"s1\"\u003e\u0026#39;u1.password\u0026#39;\u003c/span\u003e -r\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003erm -f client.* server.*\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_ciphers = \u0026#39;ECDHE-ECDSA-SM4-CBC-SM3\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -name SM2 -genkey -out ./demoCA/private/cakey.pem\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -new -key ./demoCA/private/cakey.pem -out ./demoCA/private/ca_cert_req.pem -subj \u003cspan class=\"s2\"\u003e\u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=root\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -req -in ./demoCA/private/ca_cert_req.pem -days \u003cspan class=\"m\"\u003e7300\u003c/span\u003e -signkey ./demoCA/private/cakey.pem -out ./demoCA/cacert.pem\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# server\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -name SM2 -genkey -out server.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -new -key server.key -out server.csr -subj \u003cspan class=\"s2\"\u003e\u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=server\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -req -in server.csr -days \u003cspan class=\"m\"\u003e3650\u003c/span\u003e -CA ./demoCA/cacert.pem -CAkey ./demoCA/private/cakey.pem -CAcreateserial -out server.crt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# client\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -name SM2 -genkey -out client.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -new -key client.key -out client.csr -subj \u003cspan class=\"s2\"\u003e\u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=client\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -req -in client.csr -days \u003cspan class=\"m\"\u003e3650\u003c/span\u003e -CA ./demoCA/cacert.pem -CAkey ./demoCA/private/cakey.pem -CAcreateserial -out client.crt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod \u003cspan class=\"m\"\u003e600\u003c/span\u003e client.key client.crt server.key server.crt ./demoCA/cacert.pem\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -in client.crt -text\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"国密\"\u003e国密\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir cert\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e cert\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl version\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# OpenSSL 1.1.1s  Tassl 2.1.2 1 Nov 2022\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp ../tassl/install/openssl.cnf ./\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod +w ./openssl.cnf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e[ gm_ca_cert ]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003esubjectKeyIdentifier=hash\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eauthorityKeyIdentifier=keyid:always,issuer\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003ebasicConstraints = critical,CA:true\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003ekeyUsage = critical, cRLSign, keyCertSign\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e[ gm_sign_cert ]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003ebasicConstraints = CA:FALSE\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003ekeyUsage = critical, digitalSignature, nonRepudiation\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e[ gm_enc_cert ]\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003ebasicConstraints = CA:FALSE\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003ekeyUsage = critical, keyEncipherment, dataEncipherment, keyAgreement\u0026#39;\u003c/span\u003e \u0026gt;\u0026gt; ./openssl.cnf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir ./demoCA ./demoCA/newcerts ./demoCA/private\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod \u003cspan class=\"m\"\u003e700\u003c/span\u003e ./demoCA/private\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;01\u0026#39;\u003c/span\u003e\u0026gt;./demoCA/serial\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etouch ./demoCA/index.txt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# ca\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -name SM2 -genkey -out ./demoCA/private/cakey.pem\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -config openssl.cnf -new -key ./demoCA/private/cakey.pem -sm3 -out ./demoCA/private/ca_cert_req.pem -subj \u003cspan class=\"s2\"\u003e\u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=root\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -req -extfile openssl.cnf -extensions gm_ca_cert -in ./demoCA/private/ca_cert_req.pem -sm3 -days \u003cspan class=\"m\"\u003e7300\u003c/span\u003e -signkey ./demoCA/private/cakey.pem -out ./demoCA/cacert.pem\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# server\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -name SM2 -genkey -out server.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ec -in server.key -passout pass:gauss@123 -sm4 -out server.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -config openssl.cnf -new -key server.key -passin pass:gauss@123 -sm3 -out server.csr -subj \u003cspan class=\"s2\"\u003e\u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=server\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -req -extfile openssl.cnf -extensions gm_sign_cert -in server.csr -sm3 -days \u003cspan class=\"m\"\u003e3650\u003c/span\u003e -CA ./demoCA/cacert.pem -CAkey ./demoCA/private/cakey.pem -passin pass:gauss@123 -CAcreateserial -out server.crt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# server.enc\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -name SM2 -genkey -out server_enc.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ec -in server_enc.key -passout pass:gauss@123 -sm4 -out server_enc.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -config openssl.cnf -new -key server_enc.key -passin pass:gauss@123 -sm3 -out server_enc.csr -subj \u003cspan class=\"s2\"\u003e\u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=server\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -req -extfile openssl.cnf -extensions gm_enc_cert -in server_enc.csr -sm3 -days \u003cspan class=\"m\"\u003e3650\u003c/span\u003e -CA ./demoCA/cacert.pem -CAkey ./demoCA/private/cakey.pem -passin pass:gauss@123 -CAcreateserial -out server_enc.crt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc encrypt -M server -D ./ -K gauss@123\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# client\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -name SM2 -genkey -out client.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ec -in client.key -passout pass:gauss@123 -sm4 -out client.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -config openssl.cnf -new -key client.key -passin pass:gauss@123 -sm3 -out client.csr -subj \u003cspan class=\"s2\"\u003e\u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=client\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -req -extfile openssl.cnf -extensions gm_sign_cert -in client.csr -sm3 -days \u003cspan class=\"m\"\u003e3650\u003c/span\u003e -CA ./demoCA/cacert.pem -CAkey ./demoCA/private/cakey.pem -passin pass:gauss@123 -CAcreateserial -out client.crt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# client.enc\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -name SM2 -genkey -out client_enc.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ec -in client_enc.key -passout pass:gauss@123 -sm4 -out client_enc.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -config openssl.cnf -new -key client_enc.key -passin pass:gauss@123 -sm3 -out client_enc.csr -subj \u003cspan class=\"s2\"\u003e\u0026#34;/C=CN/ST=Beijing/O=huawei/OU=gauss/CN=client\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -req -extfile openssl.cnf -extensions gm_enc_cert -in client_enc.csr -sm3 -days \u003cspan class=\"m\"\u003e3650\u003c/span\u003e -CA ./demoCA/cacert.pem -CAkey ./demoCA/private/cakey.pem -passin pass:gauss@123 -CAcreateserial -out client_enc.crt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc encrypt -M client -D ./ -K gauss@123\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# openssl x509 -in client.crt -text\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCERT\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport CERT=`pwd`\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLMODE=verify-ca\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLTLCP=1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLROOTCERT=$CERT/demoCA/cacert.pem\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLKEY=$CERT/client.key\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLCERT=$CERT/client.crt\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLENCKEY=$CERT/client_enc.key\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLENCCERT=$CERT/client_enc.crt\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u003c/span\u003e \u0026gt; client_env\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003esource\u003c/span\u003e client_env\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 设置服务端参数\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data/single_node -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl=on\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data/single_node -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_ciphers = \u0026#39;ALL\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data/single_node -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_use_tlcp=on\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data/single_node -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_ca_file = \u0026#39;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$CERT\u003c/span\u003e\u003cspan class=\"s2\"\u003e/demoCA/cacert.pem\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data/single_node -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_key_file=\u0026#39;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$CERT\u003c/span\u003e\u003cspan class=\"s2\"\u003e/server.key\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data/single_node -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_cert_file=\u0026#39;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$CERT\u003c/span\u003e\u003cspan class=\"s2\"\u003e/server.crt\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data/single_node -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_enc_key_file=\u0026#39;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$CERT\u003c/span\u003e\u003cspan class=\"s2\"\u003e/server_enc.key\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data/single_node -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_enc_cert_file=\u0026#39;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$CERT\u003c/span\u003e\u003cspan class=\"s2\"\u003e/server_enc.crt\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 重启数据库\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"数据库安全 传输加密"},{"content":"PQconnectStart makeEmptyPGconn connectOptions1 parse_connection_string fillPGconn conninfo_getval(\u0026#34;enable_ce\u0026#34;) # 解析 \u0026#39;enable_ce\u0026#39; connectDBStart PQconnectPoll if CONNECTION_NEEDED: # 建立TCP连接 connect elif CONNECTION_MADE: # 发送连接参数 pqBuildStartupPacket3 build_startup_packet pqPacketSend elif CONNECTION_AWAITING_RESPONSE # 进行身份认证 pg_fe_sendauth PQexec PQexecStart PQsendQuery Processor::run_pre_query # 加密SQL语句中的数据 Parser::Parse run_pre_statement run_pre_insert_statement CachedColumnManager::get_cached_columns RawValues::get_raw_values_from_insert_statement ValuesProcessor::process_values process_inside_value # 加密 StatementData::replace_raw_values pqPutMsgStart pqPuts pqPutMsgEnd pqFlush PQexecFinish PQgetResult parseInput pqParseInput3 pqGetc pqGetInt case \u0026#39;D\u0026#39; getAnotherTuple pqRowProcessor ValuesProcessor::deprocess_value # 解密服务端返回的数据 pqGets case \u0026#39;Z\u0026#39; Processor::run_post_query pqReadData ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/fully-encrypted-overview/","summary":"\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ePQconnectStart\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003emakeEmptyPGconn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003econnectOptions1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eparse_connection_string\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003efillPGconn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003econninfo_getval\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;enable_ce\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 解析 \u0026#39;enable_ce\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003econnectDBStart\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ePQconnectPoll\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"n\"\u003eCONNECTION_NEEDED\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 建立TCP连接\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003econnect\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003eelif\u003c/span\u003e \u003cspan class=\"n\"\u003eCONNECTION_MADE\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 发送连接参数\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003epqBuildStartupPacket3\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003ebuild_startup_packet\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003epqPacketSend\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003eelif\u003c/span\u003e \u003cspan class=\"n\"\u003eCONNECTION_AWAITING_RESPONSE\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 进行身份认证\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003epg_fe_sendauth\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003ePQexec\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ePQexecStart\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ePQsendQuery\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eProcessor\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003erun_pre_query\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 加密SQL语句中的数据\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eParser\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eParse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003erun_pre_statement\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003erun_pre_insert_statement\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eCachedColumnManager\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eget_cached_columns\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eRawValues\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eget_raw_values_from_insert_statement\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eValuesProcessor\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003eprocess_values\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eprocess_inside_value\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 加密\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eStatementData\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003ereplace_raw_values\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003epqPutMsgStart\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003epqPuts\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003epqPutMsgEnd\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003epqFlush\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ePQexecFinish\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003ePQgetResult\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eparseInput\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003epqParseInput3\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003epqGetc\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003epqGetInt\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;D\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003egetAnotherTuple\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003epqRowProcessor\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003eValuesProcessor\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003edeprocess_value\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 解密服务端返回的数据\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003epqGets\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"k\"\u003ecase\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;Z\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eProcessor\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"n\"\u003erun_post_query\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003epqReadData\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"数据库安全 全密态"},{"content":"2 安装数据库 scp shenkun@172.16.100.134:/home/shenkun/g100/pkg-5-19.tar.gz ./ vast@123 export GAUSSHOME=`pwd` export PATH=$PATH:$GAUSSHOME/bin export LD_ alias vinit=\u0026#39;vb_initdb -D $GAUSSHOME/data -w vb.12345 --nodename=db1\u0026#39; alias vstart=\u0026#39;vb_ctl start -D $GAUSSHOME/data\u0026#39; alias vrestart=\u0026#39;vb_ctl restart -D $GAUSSHOME/data\u0026#39; 3 安装benchmarksql 一、下载benchmarksql\n# 1.安装java openjdk yum install java yum install java-1.8.0-openjdk-devel # 2.下载benchmark安装包 https://sourceforge.net/projects/benchmarksql/files/latest/download # 3.下载ant安装包 https://dlcdn.apache.org//ant/binaries/apache-ant-1.10.15-bin.tar.gz # 4.解压benchmark与ant安装包 # 建议git初始化benchmark安装包，如果改错了可以回退 二、配置环境变量\n# 1.生成环境变量脚本 touch envbm # 在envbm中添加一下内容 export BMROOT=`pwd` export BMCODE=$BMROOT/benchmarksql-5.0 export PATH=$PATH:$BMROOT/apache-ant-1.10.15/bin export DBIP=127.0.0.1 export DBPORT=5432 # 2.配置环境变量 source envbm 三、配置benchmarksql配置文件\n# 1.生成配置文件 mkdir cfg cp $BMCODE/run/props.pg $BMROOT/cfg/props.pg # 2.编辑配置文件 sed -i \u0026#39;/^user=/s/=.*/=u1/\u0026#39; f1 # user=bmuser # password=bmuser@123 # warehouses=10 # loadWorkers=10 # terminals=10 # runMins=5 # limitTxnsPerMin=0 # 3. 设置表的fillfictor=80 cp $BMCODE/run/sql.common/tableCreates.sql $BMCODE/run/sql.common/_tableCreates.sql sed -i \u0026#39;/^);/s/);.*/) with (fillfactor=80);/\u0026#39; $BMCODE/run/sql.common/tableCreates.sql 四、生成便捷使用benchmarksql的脚本\ntouch toolbm # 复制以下内容 sed -i \u0026#34;s/^conn=.*/conn=jdbc:postgresql:\\/\\/$DBIP:$DBPORT\\/bmdb?prepareThreshold=1\\\u0026amp;batchMode=on\\\u0026amp;fetchsize=10/\u0026#34; $BMROOT/cfg/props.pg case $1 in init) cd $BMCODE ant cd - gsql -p $DBPORT -d postgres -c \u0026#34; DROP DATABASE IF EXISTS bmdb; DROP USER IF EXISTS bmuser; CREATE USER bmuser PASSWORD \u0026#39;bmuser@123\u0026#39; SYSADMIN; CREATE DATABASE bmdb OWNER bmuser; \u0026#34; ;; check) gsql -p $DBPORT -d bmdb -U bmuser -W \u0026#39;bmuser@123\u0026#39; -c \u0026#34;\\d+\u0026#34; ;; create) cd $BMCODE/run ./runDatabaseBuild.sh $BMROOT/cfg/props.pg cd - ;; run) cd $BMCODE/run ./runBenchmark.sh $BMROOT/cfg/props.pg cd - ;; run_full) # run 5 min first sed -i \u0026#39;/^runMins=/s/=.*/=5/\u0026#39; $BMROOT/cfg/props.pg cd $BMCODE/run ./runBenchmark.sh $BMROOT/cfg/props.pg # then run 30 min sed -i \u0026#39;/^runMins=/s/=.*/=30/\u0026#39; $BMROOT/cfg/props.pg ./runBenchmark.sh $BMROOT/cfg/props.pg cd - ;; drop) cd $BMCODE/run ./runDatabaseDestroy.sh $BMROOT/cfg/props.pg cd - ;; *) echo \u0026#34; command | function \u0026#34; echo \u0026#34;-----------+------------------------------------------------\u0026#34; echo \u0026#34; init : create user, database\u0026#34; echo \u0026#34; create : create table, index, ..; insert data\u0026#34; echo \u0026#34; check ：show all tables\u0026#34; echo \u0026#34; run : select, update\u0026#34; echo \u0026#34; run_full : select, update (run 5 min, then run 30 min)\u0026#34; echo \u0026#34; drop : drop table, index, ..\u0026#34; ;; esac # 设置脚本执行权限 chmod +x toolbm 3 使用benchmarksql测试tpcc # 1.创建用户、创建database ./toolbm init # 2.创建表，导入数据 ./toolbm create # 3.运行tpcc ./toolbm run # 4.删除数据 ./toolbm drop 测试模型 tpc-c (oltp)\nneworder(45%)\n-- 1. 查询客户信用额度、折扣和余额 (点查) SELECT c_discount, c_last, c_credit, w_tax FROM customer, warehouse WHERE w_id = ? AND c_w_id = ? AND c_d_id = ? AND c_id = ?; -- 2. 查询地区税率 (点查) SELECT d_tax, d_next_o_id FROM district WHERE d_w_id = ? AND d_id = ? FOR UPDATE; -- ⚠️ 关键: FOR UPDATE 行锁 -- 3. 更新地区下一个订单ID (UPDATE) UPDATE district SET d_next_o_id = d_next_o_id + 1 WHERE d_w_id = ? AND d_id = ?; -- 4. 插入订单头 (INSERT) INSERT INTO orders (o_id, o_d_id, o_w_id, o_c_id, o_entry_d, o_ol_cnt, o_all_local) VALUES (?, ?, ?, ?, ?, ?, ?); -- 5. 插入新订单记录 (INSERT) INSERT INTO new_order (no_o_id, no_d_id, no_w_id) VALUES (?, ?, ?); -- 6. 循环执行以下3条 (每个订单项一次, 平均10次): -- 6a. 查询商品信息 (点查) SELECT i_price, i_name, i_data FROM item WHERE i_id = ?; -- 6b. 查询并锁定库存 (FOR UPDATE) SELECT s_quantity, s_ytd, s_order_cnt, s_remote_cnt, s_data, s_dist_xx FROM stock WHERE s_i_id = ? AND s_w_id = ? FOR UPDATE; -- 6c. 更新库存 (条件UPDATE) UPDATE stock SET s_quantity = ?, s_ytd = ?, s_order_cnt = ?, s_remote_cnt = ? WHERE s_i_id = ? AND s_w_id = ?; -- 6d. 插入订单明细 (INSERT) INSERT INTO order_line (ol_o_id, ol_d_id, ol_w_id, ol_number, ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_dist_info) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?); payment(43%)\n-- 1. 更新仓库余额 (点查+UPDATE) UPDATE warehouse SET w_ytd = w_ytd + ? WHERE w_id = ?; -- 2. 查询仓库信息 (用于历史记录) SELECT w_street_1, w_street_2, w_city, w_state, w_zip, w_name FROM warehouse WHERE w_id = ?; -- 3. 更新地区余额 (点查+UPDATE) UPDATE district SET d_ytd = d_ytd + ? WHERE d_w_id = ? AND d_id = ?; -- 4. 查询地区信息 SELECT d_street_1, d_street_2, d_city, d_state, d_zip, d_name FROM district WHERE d_w_id = ? AND d_id = ?; -- 5. 按ID或姓名查找客户 (⚠️ 两种路径) -- 路径A (60%概率): 按主键点查 SELECT c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, c_phone, c_credit, c_credit_lim, c_discount, c_balance, c_since FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_id = ? FOR UPDATE; -- 路径B (40%概率): 按姓名范围扫描 + 排序取中间值 SELECT c_first, c_middle, c_last, c_street_1, c_street_2, c_city, c_state, c_zip, c_phone, c_credit, c_credit_lim, c_discount, c_balance, c_since FROM customer WHERE c_w_id = ? AND c_d_id = ? AND c_last = ? ORDER BY c_first FOR UPDATE; -- 6. 更新客户余额和历史计数 UPDATE customer SET c_balance = ?, c_ytd_payment = ?, c_payment_cnt = ? WHERE c_w_id = ? AND c_d_id = ? AND c_id = ?; -- 7. 如果客户信用为 \u0026#39;BC\u0026#39;, 追加数据到 c_data (TEXT/CLOB 操作) UPDATE customer SET c_data = substring(? || c_data, 1, 500) WHERE c_w_id = ? AND c_d_id = ? AND c_id = ?; -- 8. 插入历史流水 (INSERT) INSERT INTO history (h_c_d_id, h_c_w_id, h_c_id, h_d_id, h_w_id, h_date, h_amount, h_data) VALUES (?, ?, ?, ?, ?, ?, ?, ?); Order-Status (%4)\n-- 1. 查找客户 (同 Payment 的路径A/B) -- ... (同上) -- 2. 查询客户最近一笔订单 (⚠️ 相关子查询 / LIMIT) SELECT o_id, o_carrier_id, o_entry_d FROM orders WHERE o_w_id = ? AND o_d_id = ? AND o_c_id = ? ORDER BY o_id DESC LIMIT 1; -- 3. 查询该订单的所有明细 (范围扫描) SELECT ol_i_id, ol_supply_w_id, ol_quantity, ol_amount, ol_delivery_d FROM order_line WHERE ol_w_id = ? AND ol_d_id = ? AND ol_o_id = ?; delivery (4%)\n-- 循环处理10个地区: -- 1. 删除并获取最早的新订单 (DELETE + RETURNING) DELETE FROM new_order WHERE no_w_id = ? AND no_d_id = ? AND no_o_id = ( SELECT min(no_o_id) FROM new_order WHERE no_w_id = ? AND no_d_id = ? ) RETURNING no_o_id; -- 2. 查询订单关联的客户ID SELECT o_c_id FROM orders WHERE o_id = ? AND o_d_id = ? AND o_w_id = ?; -- 3. 更新订单承运商 UPDATE orders SET o_carrier_id = ? WHERE o_id = ? AND o_d_id = ? AND o_w_id = ?; -- 4. 更新所有订单明细的配送时间 UPDATE order_line SET ol_delivery_d = ? WHERE ol_w_id = ? AND ol_d_id = ? AND ol_o_id = ?; -- 5. 汇总订单金额并更新客户余额 UPDATE customer SET c_balance = c_balance + ?, c_delivery_cnt = c_delivery_cnt + 1 WHERE c_w_id = ? AND c_d_id = ? AND c_id = ?; stock-level(4%)\n-- 1. 查询地区阈值 SELECT d_next_o_id FROM district WHERE d_w_id = ? AND d_id = ?; -- 2. 统计低库存商品种类数 (⚠️ 三表JOIN + 子查询 + GROUP BY) SELECT COUNT(DISTINCT s_i_id) AS stock_count FROM order_line, stock WHERE ol_w_id = ? AND ol_d_id = ? AND ol_o_id \u0026lt; ? AND ol_o_id \u0026gt;= ? - 20 AND s_w_id = ? AND s_i_id = ol_i_id AND s_quantity \u0026lt; ?; tpc-h (olap)\ntpc-ds (优化器，99条查询)\n\\timing on -- start query 1 in stream 0 using template query96.tpl select count(*) from store_sales , household_demographics , time_dim , store where ss_sold_time_sk = time_dim.t_time_sk and ss_hdemo_sk = household_demographics.hd_demo_sk and ss_store_sk = s_store_sk and time_dim.t_hour = 8 and time_dim.t_minute \u0026gt;= 30 and household_demographics.hd_dep_count = 5 and store.s_store_name = \u0026#39;ese\u0026#39; order by count(*) LIMIT 100; -- end query 1 in stream 0 using template query96.tpl -- start query 2 in stream 0 using template query7.tpl select i_item_id, avg(ss_quantity) agg1, avg(ss_list_price) agg2, avg(ss_coupon_amt) agg3, avg(ss_sales_price) agg4 from store_sales, customer_demographics, date_dim, item, promotion where ss_sold_date_sk = d_date_sk and ss_item_sk = i_item_sk and ss_cdemo_sk = cd_demo_sk and ss_promo_sk = p_promo_sk and cd_gender = \u0026#39;M\u0026#39; and cd_marital_status = \u0026#39;M\u0026#39; and cd_education_status = \u0026#39;4 yr Degree\u0026#39; and (p_channel_email = \u0026#39;N\u0026#39; or p_channel_event = \u0026#39;N\u0026#39;) and d_year = 2001 group by i_item_id order by i_item_id LIMIT 100; -- end query 2 in stream 0 using template query7.tpl -- start query 3 in stream 0 using template query75.tpl WITH all_sales AS (SELECT d_year , i_brand_id , i_class_id , i_category_id , i_manufact_id , SUM(sales_cnt) AS sales_cnt , SUM(sales_amt) AS sales_amt FROM (SELECT d_year , i_brand_id , i_class_id , i_category_id , i_manufact_id , cs_quantity - COALESCE(cr_return_quantity, 0) AS sales_cnt , cs_ext_sales_price - COALESCE(cr_return_amount, 0.0) AS sales_amt FROM catalog_sales JOIN item ON i_item_sk = cs_item_sk JOIN date_dim ON d_date_sk = cs_sold_date_sk LEFT JOIN catalog_returns ON (cs_order_number = cr_order_number AND cs_item_sk = cr_item_sk) WHERE i_category = \u0026#39;Shoes\u0026#39; UNION SELECT d_year , i_brand_id , i_class_id , i_category_id , i_manufact_id , ss_quantity - COALESCE(sr_return_quantity, 0) AS sales_cnt , ss_ext_sales_price - COALESCE(sr_return_amt, 0.0) AS sales_amt FROM store_sales JOIN item ON i_item_sk = ss_item_sk JOIN date_dim ON d_date_sk = ss_sold_date_sk LEFT JOIN store_returns ON (ss_ticket_number = sr_ticket_number AND ss_item_sk = sr_item_sk) WHERE i_category = \u0026#39;Shoes\u0026#39; UNION SELECT d_year , i_brand_id , i_class_id , i_category_id , i_manufact_id , ws_quantity - COALESCE(wr_return_quantity, 0) AS sales_cnt , ws_ext_sales_price - COALESCE(wr_return_amt, 0.0) AS sales_amt FROM web_sales JOIN item ON i_item_sk = ws_item_sk JOIN date_dim ON d_date_sk = ws_sold_date_sk LEFT JOIN web_returns ON (ws_order_number = wr_order_number AND ws_item_sk = wr_item_sk) WHERE i_category = \u0026#39;Shoes\u0026#39;) sales_detail GROUP BY d_year, i_brand_id, i_class_id, i_category_id, i_manufact_id) SELECT prev_yr.d_year AS prev_year , curr_yr.d_year AS year ,curr_yr.i_brand_id ,curr_yr.i_class_id ,curr_yr.i_category_id ,curr_yr.i_manufact_id ,prev_yr.sales_cnt AS prev_yr_cnt ,curr_yr.sales_cnt AS curr_yr_cnt ,curr_yr.sales_cnt-prev_yr.sales_cnt AS sales_cnt_diff ,curr_yr.sales_amt-prev_yr.sales_amt AS sales_amt_diff FROM all_sales curr_yr, all_sales prev_yr WHERE curr_yr.i_brand_id=prev_yr.i_brand_id AND curr_yr.i_class_id=prev_yr.i_class_id AND curr_yr.i_category_id=prev_yr.i_category_id AND curr_yr.i_manufact_id=prev_yr.i_manufact_id AND curr_yr.d_year=2000 AND prev_yr.d_year=2000-1 AND CAST (curr_yr.sales_cnt AS DECIMAL (17 , 2))/ CAST (prev_yr.sales_cnt AS DECIMAL (17 , 2)) \u0026lt;0.9 ORDER BY sales_cnt_diff, sales_amt_diff LIMIT 100; -- end query 3 in stream 0 using template query75.tpl -- start query 4 in stream 0 using template query44.tpl select asceding.rnk, i1.i_product_name best_performing, i2.i_product_name worst_performing from (select * from (select item_sk, rank() over (order by rank_col asc) rnk from (select ss_item_sk item_sk, avg(ss_net_profit) rank_col from store_sales ss1 where ss_store_sk = 6 group by ss_item_sk having avg(ss_net_profit) \u0026gt; 0.9 * (select avg(ss_net_profit) rank_col from store_sales where ss_store_sk = 6 and ss_hdemo_sk is null group by ss_store_sk)) V1) V11 where rnk \u0026lt; 11) asceding, (select * from (select item_sk, rank() over (order by rank_col desc) rnk from (select ss_item_sk item_sk, avg(ss_net_profit) rank_col from store_sales ss1 where ss_store_sk = 6 group by ss_item_sk having avg(ss_net_profit) \u0026gt; 0.9 * (select avg(ss_net_profit) rank_col from store_sales where ss_store_sk = 6 and ss_hdemo_sk is null group by ss_store_sk)) V2) V21 where rnk \u0026lt; 11) descending, item i1, item i2 where asceding.rnk = descending.rnk and i1.i_item_sk = asceding.item_sk and i2.i_item_sk = descending.item_sk order by asceding.rnk LIMIT 100; -- end query 4 in stream 0 using template query44.tpl -- start query 5 in stream 0 using template query39.tpl with inv as (select w_warehouse_name , w_warehouse_sk , i_item_sk , d_moy , stdev , mean , case mean when 0 then null else stdev / mean end cov from (select w_warehouse_name , w_warehouse_sk , i_item_sk , d_moy , stddev_samp(inv_quantity_on_hand) stdev , avg(inv_quantity_on_hand) mean from inventory , item , warehouse , date_dim where inv_item_sk = i_item_sk and inv_warehouse_sk = w_warehouse_sk and inv_date_sk = d_date_sk and d_year = 2001 group by w_warehouse_name, w_warehouse_sk, i_item_sk, d_moy) foo where case mean when 0 then 0 else stdev / mean end \u0026gt; 1) select inv1.w_warehouse_sk , inv1.i_item_sk , inv1.d_moy , inv1.mean , inv1.cov , inv2.w_warehouse_sk , inv2.i_item_sk , inv2.d_moy , inv2.mean , inv2.cov from inv inv1, inv inv2 where inv1.i_item_sk = inv2.i_item_sk and inv1.w_warehouse_sk = inv2.w_warehouse_sk and inv1.d_moy = 1 and inv2.d_moy = 1 + 1 order by inv1.w_warehouse_sk, inv1.i_item_sk, inv1.d_moy, inv1.mean, inv1.cov , inv2.d_moy, inv2.mean, inv2.cov ; with inv as (select w_warehouse_name , w_warehouse_sk , i_item_sk , d_moy , stdev , mean , case mean when 0 then null else stdev / mean end cov from (select w_warehouse_name , w_warehouse_sk , i_item_sk , d_moy , stddev_samp(inv_quantity_on_hand) stdev , avg(inv_quantity_on_hand) mean from inventory , item , warehouse , date_dim where inv_item_sk = i_item_sk and inv_warehouse_sk = w_warehouse_sk and inv_date_sk = d_date_sk and d_year = 2001 group by w_warehouse_name, w_warehouse_sk, i_item_sk, d_moy) foo where case mean when 0 then 0 else stdev / mean end \u0026gt; 1) select inv1.w_warehouse_sk , inv1.i_item_sk , inv1.d_moy , inv1.mean , inv1.cov , inv2.w_warehouse_sk , inv2.i_item_sk , inv2.d_moy , inv2.mean , inv2.cov from inv inv1, inv inv2 where inv1.i_item_sk = inv2.i_item_sk and inv1.w_warehouse_sk = inv2.w_warehouse_sk and inv1.d_moy = 1 and inv2.d_moy = 1 + 1 and inv1.cov \u0026gt; 1.5 order by inv1.w_warehouse_sk, inv1.i_item_sk, inv1.d_moy, inv1.mean, inv1.cov , inv2.d_moy, inv2.mean, inv2.cov ; -- end query 5 in stream 0 using template query39.tpl -- start query 6 in stream 0 using template query80.tpl with ssr as (select s_store_id as store_id, sum(ss_ext_sales_price) as sales, sum(coalesce(sr_return_amt, 0)) as returns, sum(ss_net_profit - coalesce(sr_net_loss, 0)) as profit from store_sales left outer join store_returns on (ss_item_sk = sr_item_sk and ss_ticket_number = sr_ticket_number), date_dim, store, item, promotion where ss_sold_date_sk = d_date_sk and d_date between cast(\u0026#39;2002-08-04\u0026#39; as date) and (cast(\u0026#39;2002-08-04\u0026#39; as date) + 30 days) and ss_store_sk = s_store_sk and ss_item_sk = i_item_sk and i_current_price \u0026gt; 50 and ss_promo_sk = p_promo_sk and p_channel_tv = \u0026#39;N\u0026#39; group by s_store_id) , csr as (select cp_catalog_page_id as catalog_page_id, sum(cs_ext_sales_price) as sales, sum(coalesce(cr_return_amount, 0)) as returns, sum(cs_net_profit - coalesce(cr_net_loss, 0)) as profit from catalog_sales left outer join catalog_returns on (cs_item_sk = cr_item_sk and cs_order_number = cr_order_number), date_dim, catalog_page, item, promotion where cs_sold_date_sk = d_date_sk and d_date between cast(\u0026#39;2002-08-04\u0026#39; as date) and (cast(\u0026#39;2002-08-04\u0026#39; as date) + 30 days) and cs_catalog_page_sk = cp_catalog_page_sk and cs_item_sk = i_item_sk and i_current_price \u0026gt; 50 and cs_promo_sk = p_promo_sk and p_channel_tv = \u0026#39;N\u0026#39; group by cp_catalog_page_id) , wsr as (select web_site_id, sum(ws_ext_sales_price) as sales, sum(coalesce(wr_return_amt, 0)) as returns, sum(ws_net_profit - coalesce(wr_net_loss, 0)) as profit from web_sales left outer join web_returns on (ws_item_sk = wr_item_sk and ws_order_number = wr_order_number), date_dim, web_site, item, promotion where ws_sold_date_sk = d_date_sk and d_date between cast(\u0026#39;2002-08-04\u0026#39; as date) and (cast(\u0026#39;2002-08-04\u0026#39; as date) + 30 days) and ws_web_site_sk = web_site_sk and ws_item_sk = i_item_sk and i_current_price \u0026gt; 50 and ws_promo_sk = p_promo_sk and p_channel_tv = \u0026#39;N\u0026#39; group by web_site_id) select channel , id , sum(sales) as sales , sum(returns) as returns , sum(profit) as profit from (select \u0026#39;store channel\u0026#39; as channel , \u0026#39;store\u0026#39; || store_id as id , sales , returns , profit from ssr union all select \u0026#39;catalog channel\u0026#39; as channel , \u0026#39;catalog_page\u0026#39; || catalog_page_id as id , sales , returns , profit from csr union all select \u0026#39;web channel\u0026#39; as channel , \u0026#39;web_site\u0026#39; || web_site_id as id , sales , returns , profit from wsr) x group by rollup (channel, id) order by channel , id LIMIT 100; -- end query 6 in stream 0 using template query80.tpl -- start query 7 in stream 0 using template query32.tpl select sum(cs_ext_discount_amt) as \u0026#34;excess discount amount\u0026#34; from catalog_sales , item , date_dim where i_manufact_id = 283 and i_item_sk = cs_item_sk and d_date between \u0026#39;1999-02-22\u0026#39; and (cast(\u0026#39;1999-02-22\u0026#39; as date) + 90 days) and d_date_sk = cs_sold_date_sk and cs_ext_discount_amt \u0026gt; (select 1.3 * avg(cs_ext_discount_amt) from catalog_sales , date_dim where cs_item_sk = i_item_sk and d_date between \u0026#39;1999-02-22\u0026#39; and (cast(\u0026#39;1999-02-22\u0026#39; as date) + 90 days) and d_date_sk = cs_sold_date_sk) LIMIT 100; -- end query 7 in stream 0 using template query32.tpl -- start query 8 in stream 0 using template query19.tpl select i_brand_id brand_id, i_brand brand, i_manufact_id, i_manufact, sum(ss_ext_sales_price) ext_price from date_dim, store_sales, item, customer, customer_address, store where d_date_sk = ss_sold_date_sk and ss_item_sk = i_item_sk and i_manager_id = 8 and d_moy = 11 and d_year = 1999 and ss_customer_sk = c_customer_sk and c_current_addr_sk = ca_address_sk and substr(ca_zip, 1, 5) \u0026lt;\u0026gt; substr(s_zip, 1, 5) and ss_store_sk = s_store_sk group by i_brand , i_brand_id , i_manufact_id , i_manufact order by ext_price desc , i_brand , i_brand_id , i_manufact_id , i_manufact LIMIT 100; -- end query 8 in stream 0 using template query19.tpl -- start query 9 in stream 0 using template query25.tpl select i_item_id , i_item_desc , s_store_id , s_store_name , min(ss_net_profit) as store_sales_profit , min(sr_net_loss) as store_returns_loss , min(cs_net_profit) as catalog_sales_profit from store_sales , store_returns , catalog_sales , date_dim d1 , date_dim d2 , date_dim d3 , store , item where d1.d_moy = 4 and d1.d_year = 2002 and d1.d_date_sk = ss_sold_date_sk and i_item_sk = ss_item_sk and s_store_sk = ss_store_sk and ss_customer_sk = sr_customer_sk and ss_item_sk = sr_item_sk and ss_ticket_number = sr_ticket_number and sr_returned_date_sk = d2.d_date_sk and d2.d_moy between 4 and 10 and d2.d_year = 2002 and sr_customer_sk = cs_bill_customer_sk and sr_item_sk = cs_item_sk and cs_sold_date_sk = d3.d_date_sk and d3.d_moy between 4 and 10 and d3.d_year = 2002 group by i_item_id , i_item_desc , s_store_id , s_store_name order by i_item_id , i_item_desc , s_store_id , s_store_name LIMIT 100; -- end query 9 in stream 0 using template query25.tpl -- start query 10 in stream 0 using template query78.tpl with ws as (select d_year AS ws_sold_year, ws_item_sk, ws_bill_customer_sk ws_customer_sk, sum(ws_quantity) ws_qty, sum(ws_wholesale_cost) ws_wc, sum(ws_sales_price) ws_sp from web_sales left join web_returns on wr_order_number = ws_order_number and ws_item_sk = wr_item_sk join date_dim on ws_sold_date_sk = d_date_sk where wr_order_number is null group by d_year, ws_item_sk, ws_bill_customer_sk), cs as (select d_year AS cs_sold_year, cs_item_sk, cs_bill_customer_sk cs_customer_sk, sum(cs_quantity) cs_qty, sum(cs_wholesale_cost) cs_wc, sum(cs_sales_price) cs_sp from catalog_sales left join catalog_returns on cr_order_number = cs_order_number and cs_item_sk = cr_item_sk join date_dim on cs_sold_date_sk = d_date_sk where cr_order_number is null group by d_year, cs_item_sk, cs_bill_customer_sk), ss as (select d_year AS ss_sold_year, ss_item_sk, ss_customer_sk, sum(ss_quantity) ss_qty, sum(ss_wholesale_cost) ss_wc, sum(ss_sales_price) ss_sp from store_sales left join store_returns on sr_ticket_number = ss_ticket_number and ss_item_sk = sr_item_sk join date_dim on ss_sold_date_sk = d_date_sk where sr_ticket_number is null group by d_year, ss_item_sk, ss_customer_sk) select ss_customer_sk, round(ss_qty / (coalesce(ws_qty, 0) + coalesce(cs_qty, 0)), 2) ratio, ss_qty store_qty, ss_wc store_wholesale_cost, ss_sp store_sales_price, coalesce(ws_qty, 0) + coalesce(cs_qty, 0) other_chan_qty, coalesce(ws_wc, 0) + coalesce(cs_wc, 0) other_chan_wholesale_cost, coalesce(ws_sp, 0) + coalesce(cs_sp, 0) other_chan_sales_price from ss left join ws on (ws_sold_year = ss_sold_year and ws_item_sk = ss_item_sk and ws_customer_sk = ss_customer_sk) left join cs on (cs_sold_year = ss_sold_year and cs_item_sk = ss_item_sk and cs_customer_sk = ss_customer_sk) where (coalesce(ws_qty, 0) \u0026gt; 0 or coalesce(cs_qty, 0) \u0026gt; 0) and ss_sold_year = 2001 order by ss_customer_sk, ss_qty desc, ss_wc desc, ss_sp desc, other_chan_qty, other_chan_wholesale_cost, other_chan_sales_price, ratio LIMIT 100; -- end query 10 in stream 0 using template query78.tpl -- start query 11 in stream 0 using template query86.tpl select sum(ws_net_paid) as total_sum , i_category , i_class , grouping(i_category) + grouping(i_class) as lochierarchy , rank() over ( partition by grouping(i_category)+grouping(i_class), case when grouping(i_class) = 0 then i_category end order by sum(ws_net_paid) desc) as rank_within_parent from web_sales , date_dim d1 , item where d1.d_month_seq between 1205 and 1205 + 11 and d1.d_date_sk = ws_sold_date_sk and i_item_sk = ws_item_sk group by rollup (i_category, i_class) order by lochierarchy desc, case when lochierarchy = 0 then i_category end, rank_within_parent LIMIT 100; -- end query 11 in stream 0 using template query86.tpl -- start query 12 in stream 0 using template query1.tpl with customer_total_return as (select sr_customer_sk as ctr_customer_sk , sr_store_sk as ctr_store_sk , sum(SR_RETURN_AMT_INC_TAX) as ctr_total_return from store_returns , date_dim where sr_returned_date_sk = d_date_sk and d_year = 1999 group by sr_customer_sk , sr_store_sk) select c_customer_id from customer_total_return ctr1 , store , customer where ctr1.ctr_total_return \u0026gt; (select avg(ctr_total_return) * 1.2 from customer_total_return ctr2 where ctr1.ctr_store_sk = ctr2.ctr_store_sk) and s_store_sk = ctr1.ctr_store_sk and s_state = \u0026#39;TN\u0026#39; and ctr1.ctr_customer_sk = c_customer_sk order by c_customer_id LIMIT 100; -- end query 12 in stream 0 using template query1.tpl -- start query 13 in stream 0 using template query91.tpl select cc_call_center_id Call_Center, cc_name Call_Center_Name, cc_manager Manager, sum(cr_net_loss) Returns_Loss from call_center, catalog_returns, date_dim, customer, customer_address, customer_demographics, household_demographics where cr_call_center_sk = cc_call_center_sk and cr_returned_date_sk = d_date_sk and cr_returning_customer_sk = c_customer_sk and cd_demo_sk = c_current_cdemo_sk and hd_demo_sk = c_current_hdemo_sk and ca_address_sk = c_current_addr_sk and d_year = 2002 and d_moy = 11 and ((cd_marital_status = \u0026#39;M\u0026#39; and cd_education_status = \u0026#39;Unknown\u0026#39;) or (cd_marital_status = \u0026#39;W\u0026#39; and cd_education_status = \u0026#39;Advanced Degree\u0026#39;)) and hd_buy_potential like \u0026#39;Unknown%\u0026#39; and ca_gmt_offset = -6 group by cc_call_center_id, cc_name, cc_manager, cd_marital_status, cd_education_status order by sum(cr_net_loss) desc; -- end query 13 in stream 0 using template query91.tpl -- start query 14 in stream 0 using template query21.tpl select * from (select w_warehouse_name , i_item_id , sum(case when (cast(d_date as date) \u0026lt; cast(\u0026#39;2000-05-19\u0026#39; as date)) then inv_quantity_on_hand else 0 end) as inv_before , sum(case when (cast(d_date as date) \u0026gt;= cast(\u0026#39;2000-05-19\u0026#39; as date)) then inv_quantity_on_hand else 0 end) as inv_after from inventory , warehouse , item , date_dim where i_current_price between 0.99 and 1.49 and i_item_sk = inv_item_sk and inv_warehouse_sk = w_warehouse_sk and inv_date_sk = d_date_sk and d_date between (cast(\u0026#39;2000-05-19\u0026#39; as date) - 30 days) and (cast(\u0026#39;2000-05-19\u0026#39; as date) + 30 days) group by w_warehouse_name, i_item_id) x where (case when inv_before \u0026gt; 0 then inv_after / inv_before else null end) between 2.0 / 3.0 and 3.0 / 2.0 order by w_warehouse_name , i_item_id LIMIT 100; -- end query 14 in stream 0 using template query21.tpl -- start query 15 in stream 0 using template query43.tpl select s_store_name, s_store_id, sum(case when (d_day_name = \u0026#39;Sunday\u0026#39;) then ss_sales_price else null end) sun_sales, sum(case when (d_day_name = \u0026#39;Monday\u0026#39;) then ss_sales_price else null end) mon_sales, sum(case when (d_day_name = \u0026#39;Tuesday\u0026#39;) then ss_sales_price else null end) tue_sales, sum(case when (d_day_name = \u0026#39;Wednesday\u0026#39;) then ss_sales_price else null end) wed_sales, sum(case when (d_day_name = \u0026#39;Thursday\u0026#39;) then ss_sales_price else null end) thu_sales, sum(case when (d_day_name = \u0026#39;Friday\u0026#39;) then ss_sales_price else null end) fri_sales, sum(case when (d_day_name = \u0026#39;Saturday\u0026#39;) then ss_sales_price else null end) sat_sales from date_dim, store_sales, store where d_date_sk = ss_sold_date_sk and s_store_sk = ss_store_sk and s_gmt_offset = -5 and d_year = 2000 group by s_store_name, s_store_id order by s_store_name, s_store_id, sun_sales, mon_sales, tue_sales, wed_sales, thu_sales, fri_sales, sat_sales LIMIT 100; -- end query 15 in stream 0 using template query43.tpl -- start query 16 in stream 0 using template query27.tpl select i_item_id, s_state, grouping(s_state) g_state, avg(ss_quantity) agg1, avg(ss_list_price) agg2, avg(ss_coupon_amt) agg3, avg(ss_sales_price) agg4 from store_sales, customer_demographics, date_dim, store, item where ss_sold_date_sk = d_date_sk and ss_item_sk = i_item_sk and ss_store_sk = s_store_sk and ss_cdemo_sk = cd_demo_sk and cd_gender = \u0026#39;M\u0026#39; and cd_marital_status = \u0026#39;U\u0026#39; and cd_education_status = \u0026#39;Secondary\u0026#39; and d_year = 2000 and s_state in (\u0026#39;TN\u0026#39;, \u0026#39;TN\u0026#39;, \u0026#39;TN\u0026#39;, \u0026#39;TN\u0026#39;, \u0026#39;TN\u0026#39;, \u0026#39;TN\u0026#39;) group by rollup (i_item_id, s_state) order by i_item_id , s_state LIMIT 100; -- end query 16 in stream 0 using template query27.tpl -- start query 17 in stream 0 using template query94.tpl select count(distinct ws_order_number) as \u0026#34;order count\u0026#34; , sum(ws_ext_ship_cost) as \u0026#34;total shipping cost\u0026#34; , sum(ws_net_profit) as \u0026#34;total net profit\u0026#34; from web_sales ws1 , date_dim , customer_address , web_site where d_date between \u0026#39;1999-4-01\u0026#39; and (cast(\u0026#39;1999-4-01\u0026#39; as date) + 60 days) and ws1.ws_ship_date_sk = d_date_sk and ws1.ws_ship_addr_sk = ca_address_sk and ca_state = \u0026#39;WI\u0026#39; and ws1.ws_web_site_sk = web_site_sk and web_company_name = \u0026#39;pri\u0026#39; and exists (select * from web_sales ws2 where ws1.ws_order_number = ws2.ws_order_number and ws1.ws_warehouse_sk \u0026lt;\u0026gt; ws2.ws_warehouse_sk) and not exists(select * from web_returns wr1 where ws1.ws_order_number = wr1.wr_order_number) order by count(distinct ws_order_number) LIMIT 100; -- end query 17 in stream 0 using template query94.tpl -- start query 18 in stream 0 using template query45.tpl select ca_zip, ca_city, sum(ws_sales_price) from web_sales, customer, customer_address, date_dim, item where ws_bill_customer_sk = c_customer_sk and c_current_addr_sk = ca_address_sk and ws_item_sk = i_item_sk and (substr(ca_zip, 1, 5) in (\u0026#39;85669\u0026#39;, \u0026#39;86197\u0026#39;, \u0026#39;88274\u0026#39;, \u0026#39;83405\u0026#39;, \u0026#39;86475\u0026#39;, \u0026#39;85392\u0026#39;, \u0026#39;85460\u0026#39;, \u0026#39;80348\u0026#39;, \u0026#39;81792\u0026#39;) or i_item_id in (select i_item_id from item where i_item_sk in (2, 3, 5, 7, 11, 13, 17, 19, 23, 29)) ) and ws_sold_date_sk = d_date_sk and d_qoy = 2 and d_year = 2000 group by ca_zip, ca_city order by ca_zip, ca_city LIMIT 100; -- end query 18 in stream 0 using template query45.tpl -- start query 19 in stream 0 using template query58.tpl with ss_items as (select i_item_id item_id , sum(ss_ext_sales_price) ss_item_rev from store_sales , item , date_dim where ss_item_sk = i_item_sk and d_date in (select d_date from date_dim where d_week_seq = (select d_week_seq from date_dim where d_date = \u0026#39;2000-02-12\u0026#39;)) and ss_sold_date_sk = d_date_sk group by i_item_id), cs_items as (select i_item_id item_id , sum(cs_ext_sales_price) cs_item_rev from catalog_sales , item , date_dim where cs_item_sk = i_item_sk and d_date in (select d_date from date_dim where d_week_seq = (select d_week_seq from date_dim where d_date = \u0026#39;2000-02-12\u0026#39;)) and cs_sold_date_sk = d_date_sk group by i_item_id), ws_items as (select i_item_id item_id , sum(ws_ext_sales_price) ws_item_rev from web_sales , item , date_dim where ws_item_sk = i_item_sk and d_date in (select d_date from date_dim where d_week_seq = (select d_week_seq from date_dim where d_date = \u0026#39;2000-02-12\u0026#39;)) and ws_sold_date_sk = d_date_sk group by i_item_id) select ss_items.item_id , ss_item_rev , ss_item_rev / ((ss_item_rev + cs_item_rev + ws_item_rev) / 3) * 100 ss_dev , cs_item_rev , cs_item_rev / ((ss_item_rev + cs_item_rev + ws_item_rev) / 3) * 100 cs_dev , ws_item_rev , ws_item_rev / ((ss_item_rev + cs_item_rev + ws_item_rev) / 3) * 100 ws_dev , (ss_item_rev + cs_item_rev + ws_item_rev) / 3 average from ss_items, cs_items, ws_items where ss_items.item_id = cs_items.item_id and ss_items.item_id = ws_items.item_id and ss_item_rev between 0.9 * cs_item_rev and 1.1 * cs_item_rev and ss_item_rev between 0.9 * ws_item_rev and 1.1 * ws_item_rev and cs_item_rev between 0.9 * ss_item_rev and 1.1 * ss_item_rev and cs_item_rev between 0.9 * ws_item_rev and 1.1 * ws_item_rev and ws_item_rev between 0.9 * ss_item_rev and 1.1 * ss_item_rev and ws_item_rev between 0.9 * cs_item_rev and 1.1 * cs_item_rev order by item_id , ss_item_rev LIMIT 100; -- end query 19 in stream 0 using template query58.tpl -- start query 20 in stream 0 using template query64.tpl with cs_ui as (select cs_item_sk , sum(cs_ext_list_price) as sale , sum(cr_refunded_cash + cr_reversed_charge + cr_store_credit) as refund from catalog_sales , catalog_returns where cs_item_sk = cr_item_sk and cs_order_number = cr_order_number group by cs_item_sk having sum(cs_ext_list_price) \u0026gt; 2 * sum(cr_refunded_cash + cr_reversed_charge + cr_store_credit)), cross_sales as (select i_product_name product_name , i_item_sk item_sk , s_store_name store_name , s_zip store_zip , ad1.ca_street_number b_street_number , ad1.ca_street_name b_street_name , ad1.ca_city b_city , ad1.ca_zip b_zip , ad2.ca_street_number c_street_number , ad2.ca_street_name c_street_name , ad2.ca_city c_city , ad2.ca_zip c_zip , d1.d_year as syear , d2.d_year as fsyear , d3.d_year s2year , count(*) cnt , sum(ss_wholesale_cost) s1 , sum(ss_list_price) s2 , sum(ss_coupon_amt) s3 FROM store_sales , store_returns , cs_ui , date_dim d1 , date_dim d2 , date_dim d3 , store , customer , customer_demographics cd1 , customer_demographics cd2 , promotion , household_demographics hd1 , household_demographics hd2 , customer_address ad1 , customer_address ad2 , income_band ib1 , income_band ib2 , item WHERE ss_store_sk = s_store_sk AND ss_sold_date_sk = d1.d_date_sk AND ss_customer_sk = c_customer_sk AND ss_cdemo_sk = cd1.cd_demo_sk AND ss_hdemo_sk = hd1.hd_demo_sk AND ss_addr_sk = ad1.ca_address_sk and ss_item_sk = i_item_sk and ss_item_sk = sr_item_sk and ss_ticket_number = sr_ticket_number and ss_item_sk = cs_ui.cs_item_sk and c_current_cdemo_sk = cd2.cd_demo_sk AND c_current_hdemo_sk = hd2.hd_demo_sk AND c_current_addr_sk = ad2.ca_address_sk and c_first_sales_date_sk = d2.d_date_sk and c_first_shipto_date_sk = d3.d_date_sk and ss_promo_sk = p_promo_sk and hd1.hd_income_band_sk = ib1.ib_income_band_sk and hd2.hd_income_band_sk = ib2.ib_income_band_sk and cd1.cd_marital_status \u0026lt;\u0026gt; cd2.cd_marital_status and i_color in (\u0026#39;light\u0026#39;, \u0026#39;cyan\u0026#39;, \u0026#39;burnished\u0026#39;, \u0026#39;green\u0026#39;, \u0026#39;almond\u0026#39;, \u0026#39;smoke\u0026#39;) and i_current_price between 22 and 22 + 10 and i_current_price between 22 + 1 and 22 + 15 group by i_product_name , i_item_sk , s_store_name , s_zip , ad1.ca_street_number , ad1.ca_street_name , ad1.ca_city , ad1.ca_zip , ad2.ca_street_number , ad2.ca_street_name , ad2.ca_city , ad2.ca_zip , d1.d_year , d2.d_year , d3.d_year) select cs1.product_name , cs1.store_name , cs1.store_zip , cs1.b_street_number , cs1.b_street_name , cs1.b_city , cs1.b_zip , cs1.c_street_number , cs1.c_street_name , cs1.c_city , cs1.c_zip , cs1.syear , cs1.cnt , cs1.s1 as s11 , cs1.s2 as s21 , cs1.s3 as s31 , cs2.s1 as s12 , cs2.s2 as s22 , cs2.s3 as s32 , cs2.syear , cs2.cnt from cross_sales cs1, cross_sales cs2 where cs1.item_sk = cs2.item_sk and cs1.syear = 2001 and cs2.syear = 2001 + 1 and cs2.cnt \u0026lt;= cs1.cnt and cs1.store_name = cs2.store_name and cs1.store_zip = cs2.store_zip order by cs1.product_name , cs1.store_name , cs2.cnt , cs1.s1 , cs2.s1; -- end query 20 in stream 0 using template query64.tpl -- start query 21 in stream 0 using template query36.tpl select sum(ss_net_profit) / sum(ss_ext_sales_price) as gross_margin , i_category , i_class , grouping(i_category) + grouping(i_class) as lochierarchy , rank() over ( partition by grouping(i_category)+grouping(i_class), case when grouping(i_class) = 0 then i_category end order by sum(ss_net_profit)/sum(ss_ext_sales_price) asc) as rank_within_parent from store_sales , date_dim d1 , item , store where d1.d_year = 2001 and d1.d_date_sk = ss_sold_date_sk and i_item_sk = ss_item_sk and s_store_sk = ss_store_sk and s_state in (\u0026#39;TN\u0026#39;, \u0026#39;TN\u0026#39;, \u0026#39;TN\u0026#39;, \u0026#39;TN\u0026#39;, \u0026#39;TN\u0026#39;, \u0026#39;TN\u0026#39;, \u0026#39;TN\u0026#39;, \u0026#39;TN\u0026#39;) group by rollup (i_category, i_class) order by lochierarchy desc , case when lochierarchy = 0 then i_category end , rank_within_parent LIMIT 100; -- end query 21 in stream 0 using template query36.tpl -- start query 22 in stream 0 using template query33.tpl with ss as (select i_manufact_id, sum(ss_ext_sales_price) total_sales from store_sales, date_dim, customer_address, item where i_manufact_id in (select i_manufact_id from item where i_category in (\u0026#39;Books\u0026#39;)) and ss_item_sk = i_item_sk and ss_sold_date_sk = d_date_sk and d_year = 1999 and d_moy = 4 and ss_addr_sk = ca_address_sk and ca_gmt_offset = -5 group by i_manufact_id), cs as (select i_manufact_id, sum(cs_ext_sales_price) total_sales from catalog_sales, date_dim, customer_address, item where i_manufact_id in (select i_manufact_id from item where i_category in (\u0026#39;Books\u0026#39;)) and cs_item_sk = i_item_sk and cs_sold_date_sk = d_date_sk and d_year = 1999 and d_moy = 4 and cs_bill_addr_sk = ca_address_sk and ca_gmt_offset = -5 group by i_manufact_id), ws as (select i_manufact_id, sum(ws_ext_sales_price) total_sales from web_sales, date_dim, customer_address, item where i_manufact_id in (select i_manufact_id from item where i_category in (\u0026#39;Books\u0026#39;)) and ws_item_sk = i_item_sk and ws_sold_date_sk = d_date_sk and d_year = 1999 and d_moy = 4 and ws_bill_addr_sk = ca_address_sk and ca_gmt_offset = -5 group by i_manufact_id) select i_manufact_id, sum(total_sales) total_sales from (select * from ss union all select * from cs union all select * from ws) tmp1 group by i_manufact_id order by total_sales LIMIT 100; -- end query 22 in stream 0 using template query33.tpl -- start query 23 in stream 0 using template query46.tpl select c_last_name , c_first_name , ca_city , bought_city , ss_ticket_number , amt , profit from (select ss_ticket_number , ss_customer_sk , ca_city bought_city , sum(ss_coupon_amt) amt , sum(ss_net_profit) profit from store_sales, date_dim, store, household_demographics, customer_address where store_sales.ss_sold_date_sk = date_dim.d_date_sk and store_sales.ss_store_sk = store.s_store_sk and store_sales.ss_hdemo_sk = household_demographics.hd_demo_sk and store_sales.ss_addr_sk = customer_address.ca_address_sk and (household_demographics.hd_dep_count = 3 or household_demographics.hd_vehicle_count = 1) and date_dim.d_dow in (6, 0) and date_dim.d_year in (1999, 1999 + 1, 1999 + 2) and store.s_city in (\u0026#39;Midway\u0026#39;, \u0026#39;Fairview\u0026#39;, \u0026#39;Fairview\u0026#39;, \u0026#39;Midway\u0026#39;, \u0026#39;Fairview\u0026#39;) group by ss_ticket_number, ss_customer_sk, ss_addr_sk, ca_city) dn, customer, customer_address current_addr where ss_customer_sk = c_customer_sk and customer.c_current_addr_sk = current_addr.ca_address_sk and current_addr.ca_city \u0026lt;\u0026gt; bought_city order by c_last_name , c_first_name , ca_city , bought_city , ss_ticket_number LIMIT 100; -- end query 23 in stream 0 using template query46.tpl -- start query 24 in stream 0 using template query62.tpl select substr(w_warehouse_name, 1, 20) , sm_type , web_name , sum(case when (ws_ship_date_sk - ws_sold_date_sk \u0026lt;= 30) then 1 else 0 end) as \u0026#34;30 days\u0026#34; , sum(case when (ws_ship_date_sk - ws_sold_date_sk \u0026gt; 30) and (ws_ship_date_sk - ws_sold_date_sk \u0026lt;= 60) then 1 else 0 end) as \u0026#34;31-60 days\u0026#34; , sum(case when (ws_ship_date_sk - ws_sold_date_sk \u0026gt; 60) and (ws_ship_date_sk - ws_sold_date_sk \u0026lt;= 90) then 1 else 0 end) as \u0026#34;61-90 days\u0026#34; , sum(case when (ws_ship_date_sk - ws_sold_date_sk \u0026gt; 90) and (ws_ship_date_sk - ws_sold_date_sk \u0026lt;= 120) then 1 else 0 end) as \u0026#34;91-120 days\u0026#34; , sum(case when (ws_ship_date_sk - ws_sold_date_sk \u0026gt; 120) then 1 else 0 end) as \u0026#34;\u0026gt;120 days\u0026#34; from web_sales , warehouse , ship_mode , web_site , date_dim where d_month_seq between 1217 and 1217 + 11 and ws_ship_date_sk = d_date_sk and ws_warehouse_sk = w_warehouse_sk and ws_ship_mode_sk = sm_ship_mode_sk and ws_web_site_sk = web_site_sk group by substr(w_warehouse_name, 1, 20) , sm_type , web_name order by substr(w_warehouse_name, 1, 20) , sm_type , web_name LIMIT 100; -- end query 24 in stream 0 using template query62.tpl -- start query 25 in stream 0 using template query16.tpl select count(distinct cs_order_number) as \u0026#34;order count\u0026#34; , sum(cs_ext_ship_cost) as \u0026#34;total shipping cost\u0026#34; , sum(cs_net_profit) as \u0026#34;total net profit\u0026#34; from catalog_sales cs1 , date_dim , customer_address , call_center where d_date between \u0026#39;1999-5-01\u0026#39; and (cast(\u0026#39;1999-5-01\u0026#39; as date) + 60 days) and cs1.cs_ship_date_sk = d_date_sk and cs1.cs_ship_addr_sk = ca_address_sk and ca_state = \u0026#39;ID\u0026#39; and cs1.cs_call_center_sk = cc_call_center_sk and cc_county in (\u0026#39;Williamson County\u0026#39;, \u0026#39;Williamson County\u0026#39;, \u0026#39;Williamson County\u0026#39;, \u0026#39;Williamson County\u0026#39;, \u0026#39;Williamson County\u0026#39; ) and exists (select * from catalog_sales cs2 where cs1.cs_order_number = cs2.cs_order_number and cs1.cs_warehouse_sk \u0026lt;\u0026gt; cs2.cs_warehouse_sk) and not exists(select * from catalog_returns cr1 where cs1.cs_order_number = cr1.cr_order_number) order by count(distinct cs_order_number) LIMIT 100; -- end query 25 in stream 0 using template query16.tpl -- start query 26 in stream 0 using template query10.tpl select cd_gender, cd_marital_status, cd_education_status, count(*) cnt1, cd_purchase_estimate, count(*) cnt2, cd_credit_rating, count(*) cnt3, cd_dep_count, count(*) cnt4, cd_dep_employed_count, count(*) cnt5, cd_dep_college_count, count(*) cnt6 from customer c, customer_address ca, customer_demographics where c.c_current_addr_sk = ca.ca_address_sk and ca_county in (\u0026#39;Clinton County\u0026#39;, \u0026#39;Platte County\u0026#39;, \u0026#39;Franklin County\u0026#39;, \u0026#39;Louisa County\u0026#39;, \u0026#39;Harmon County\u0026#39;) and cd_demo_sk = c.c_current_cdemo_sk and exists (select * from store_sales, date_dim where c.c_customer_sk = ss_customer_sk and ss_sold_date_sk = d_date_sk and d_year = 2002 and d_moy between 3 and 3 + 3) and (exists (select * from web_sales, date_dim where c.c_customer_sk = ws_bill_customer_sk and ws_sold_date_sk = d_date_sk and d_year = 2002 and d_moy between 3 ANd 3 + 3) or exists (select * from catalog_sales, date_dim where c.c_customer_sk = cs_ship_customer_sk and cs_sold_date_sk = d_date_sk and d_year = 2002 and d_moy between 3 and 3 + 3)) group by cd_gender, cd_marital_status, cd_education_status, cd_purchase_estimate, cd_credit_rating, cd_dep_count, cd_dep_employed_count, cd_dep_college_count order by cd_gender, cd_marital_status, cd_education_status, cd_purchase_estimate, cd_credit_rating, cd_dep_count, cd_dep_employed_count, cd_dep_college_count LIMIT 100; -- end query 26 in stream 0 using template query10.tpl -- start query 27 in stream 0 using template query63.tpl select * from (select i_manager_id , sum(ss_sales_price) sum_sales , avg(sum(ss_sales_price)) over (partition by i_manager_id) avg_monthly_sales from item , store_sales , date_dim , store where ss_item_sk = i_item_sk and ss_sold_date_sk = d_date_sk and ss_store_sk = s_store_sk and d_month_seq in (1181, 1181 + 1, 1181 + 2, 1181 + 3, 1181 + 4, 1181 + 5, 1181 + 6, 1181 + 7, 1181 + 8, 1181 + 9, 1181 + 10, 1181 + 11) and ((i_category in (\u0026#39;Books\u0026#39;, \u0026#39;Children\u0026#39;, \u0026#39;Electronics\u0026#39;) and i_class in (\u0026#39;personal\u0026#39;, \u0026#39;portable\u0026#39;, \u0026#39;reference\u0026#39;, \u0026#39;self-help\u0026#39;) and i_brand in (\u0026#39;scholaramalgamalg #14\u0026#39;, \u0026#39;scholaramalgamalg #7\u0026#39;, \u0026#39;exportiunivamalg #9\u0026#39;, \u0026#39;scholaramalgamalg #9\u0026#39;)) or (i_category in (\u0026#39;Women\u0026#39;, \u0026#39;Music\u0026#39;, \u0026#39;Men\u0026#39;) and i_class in (\u0026#39;accessories\u0026#39;, \u0026#39;classical\u0026#39;, \u0026#39;fragrances\u0026#39;, \u0026#39;pants\u0026#39;) and i_brand in (\u0026#39;amalgimporto #1\u0026#39;, \u0026#39;edu packscholar #1\u0026#39;, \u0026#39;exportiimporto #1\u0026#39;, \u0026#39;importoamalg #1\u0026#39;))) group by i_manager_id, d_moy) tmp1 where case when avg_monthly_sales \u0026gt; 0 then abs(sum_sales - avg_monthly_sales) / avg_monthly_sales else null end \u0026gt; 0.1 order by i_manager_id , avg_monthly_sales , sum_sales LIMIT 100; -- end query 27 in stream 0 using template query63.tpl -- start query 28 in stream 0 using template query69.tpl select cd_gender, cd_marital_status, cd_education_status, count(*) cnt1, cd_purchase_estimate, count(*) cnt2, cd_credit_rating, count(*) cnt3 from customer c, customer_address ca, customer_demographics where c.c_current_addr_sk = ca.ca_address_sk and ca_state in (\u0026#39;IN\u0026#39;, \u0026#39;VA\u0026#39;, \u0026#39;MS\u0026#39;) and cd_demo_sk = c.c_current_cdemo_sk and exists (select * from store_sales, date_dim where c.c_customer_sk = ss_customer_sk and ss_sold_date_sk = d_date_sk and d_year = 2002 and d_moy between 2 and 2 + 2) and (not exists (select * from web_sales, date_dim where c.c_customer_sk = ws_bill_customer_sk and ws_sold_date_sk = d_date_sk and d_year = 2002 and d_moy between 2 and 2 + 2) and not exists (select * from catalog_sales, date_dim where c.c_customer_sk = cs_ship_customer_sk and cs_sold_date_sk = d_date_sk and d_year = 2002 and d_moy between 2 and 2 + 2)) group by cd_gender, cd_marital_status, cd_education_status, cd_purchase_estimate, cd_credit_rating order by cd_gender, cd_marital_status, cd_education_status, cd_purchase_estimate, cd_credit_rating LIMIT 100; -- end query 28 in stream 0 using template query69.tpl -- start query 29 in stream 0 using template query60.tpl with ss as (select i_item_id, sum(ss_ext_sales_price) total_sales from store_sales, date_dim, customer_address, item where i_item_id in (select i_item_id from item where i_category in (\u0026#39;Shoes\u0026#39;)) and ss_item_sk = i_item_sk and ss_sold_date_sk = d_date_sk and d_year = 2001 and d_moy = 10 and ss_addr_sk = ca_address_sk and ca_gmt_offset = -6 group by i_item_id), cs as (select i_item_id, sum(cs_ext_sales_price) total_sales from catalog_sales, date_dim, customer_address, item where i_item_id in (select i_item_id from item where i_category in (\u0026#39;Shoes\u0026#39;)) and cs_item_sk = i_item_sk and cs_sold_date_sk = d_date_sk and d_year = 2001 and d_moy = 10 and cs_bill_addr_sk = ca_address_sk and ca_gmt_offset = -6 group by i_item_id), ws as (select i_item_id, sum(ws_ext_sales_price) total_sales from web_sales, date_dim, customer_address, item where i_item_id in (select i_item_id from item where i_category in (\u0026#39;Shoes\u0026#39;)) and ws_item_sk = i_item_sk and ws_sold_date_sk = d_date_sk and d_year = 2001 and d_moy = 10 and ws_bill_addr_sk = ca_address_sk and ca_gmt_offset = -6 group by i_item_id) select i_item_id , sum(total_sales) total_sales from (select * from ss union all select * from cs union all select * from ws) tmp1 group by i_item_id order by i_item_id , total_sales LIMIT 100; -- end query 29 in stream 0 using template query60.tpl -- start query 30 in stream 0 using template query59.tpl with wss as (select d_week_seq, ss_store_sk, sum(case when (d_day_name = \u0026#39;Sunday\u0026#39;) then ss_sales_price else null end) sun_sales, sum(case when (d_day_name = \u0026#39;Monday\u0026#39;) then ss_sales_price else null end) mon_sales, sum(case when (d_day_name = \u0026#39;Tuesday\u0026#39;) then ss_sales_price else null end) tue_sales, sum(case when (d_day_name = \u0026#39;Wednesday\u0026#39;) then ss_sales_price else null end) wed_sales, sum(case when (d_day_name = \u0026#39;Thursday\u0026#39;) then ss_sales_price else null end) thu_sales, sum(case when (d_day_name = \u0026#39;Friday\u0026#39;) then ss_sales_price else null end) fri_sales, sum(case when (d_day_name = \u0026#39;Saturday\u0026#39;) then ss_sales_price else null end) sat_sales from store_sales, date_dim where d_date_sk = ss_sold_date_sk group by d_week_seq, ss_store_sk) select s_store_name1 , s_store_id1 , d_week_seq1 , sun_sales1 / sun_sales2 , mon_sales1 / mon_sales2 , tue_sales1 / tue_sales2 , wed_sales1 / wed_sales2 , thu_sales1 / thu_sales2 , fri_sales1 / fri_sales2 , sat_sales1 / sat_sales2 from (select s_store_name s_store_name1 , wss.d_week_seq d_week_seq1 , s_store_id s_store_id1 , sun_sales sun_sales1 , mon_sales mon_sales1 , tue_sales tue_sales1 , wed_sales wed_sales1 , thu_sales thu_sales1 , fri_sales fri_sales1 , sat_sales sat_sales1 from wss, store, date_dim d where d.d_week_seq = wss.d_week_seq and ss_store_sk = s_store_sk and d_month_seq between 1206 and 1206 + 11) y, (select s_store_name s_store_name2 , wss.d_week_seq d_week_seq2 , s_store_id s_store_id2 , sun_sales sun_sales2 , mon_sales mon_sales2 , tue_sales tue_sales2 , wed_sales wed_sales2 , thu_sales thu_sales2 , fri_sales fri_sales2 , sat_sales sat_sales2 from wss, store, date_dim d where d.d_week_seq = wss.d_week_seq and ss_store_sk = s_store_sk and d_month_seq between 1206 + 12 and 1206 + 23) x where s_store_id1 = s_store_id2 and d_week_seq1 = d_week_seq2 - 52 order by s_store_name1, s_store_id1, d_week_seq1 LIMIT 100; -- end query 30 in stream 0 using template query59.tpl -- start query 31 in stream 0 using template query37.tpl select i_item_id , i_item_desc , i_current_price from item, inventory, date_dim, catalog_sales where i_current_price between 26 and 26 + 30 and inv_item_sk = i_item_sk and d_date_sk = inv_date_sk and d_date between cast(\u0026#39;2001-06-09\u0026#39; as date) and (cast(\u0026#39;2001-06-09\u0026#39; as date) + 60 days) and i_manufact_id in (744, 884, 722, 693) and inv_quantity_on_hand between 100 and 500 and cs_item_sk = i_item_sk group by i_item_id, i_item_desc, i_current_price order by i_item_id LIMIT 100; -- end query 31 in stream 0 using template query37.tpl -- start query 32 in stream 0 using template query98.tpl select i_item_id , i_item_desc , i_category , i_class , i_current_price , sum(ss_ext_sales_price) as itemrevenue , sum(ss_ext_sales_price) * 100 / sum(sum(ss_ext_sales_price)) over (partition by i_class) as revenueratio from store_sales , item , date_dim where ss_item_sk = i_item_sk and i_category in (\u0026#39;Shoes\u0026#39;, \u0026#39;Music\u0026#39;, \u0026#39;Men\u0026#39;) and ss_sold_date_sk = d_date_sk and d_date between cast(\u0026#39;2000-01-05\u0026#39; as date) and (cast(\u0026#39;2000-01-05\u0026#39; as date) + 30 days) group by i_item_id , i_item_desc , i_category , i_class , i_current_price order by i_category , i_class , i_item_id , i_item_desc , revenueratio; -- end query 32 in stream 0 using template query98.tpl -- start query 33 in stream 0 using template query85.tpl select substr(r_reason_desc, 1, 20) , avg(ws_quantity) , avg(wr_refunded_cash) , avg(wr_fee) from web_sales, web_returns, web_page, customer_demographics cd1, customer_demographics cd2, customer_address, date_dim, reason where ws_web_page_sk = wp_web_page_sk and ws_item_sk = wr_item_sk and ws_order_number = wr_order_number and ws_sold_date_sk = d_date_sk and d_year = 2001 and cd1.cd_demo_sk = wr_refunded_cdemo_sk and cd2.cd_demo_sk = wr_returning_cdemo_sk and ca_address_sk = wr_refunded_addr_sk and r_reason_sk = wr_reason_sk and ( ( cd1.cd_marital_status = \u0026#39;D\u0026#39; and cd1.cd_marital_status = cd2.cd_marital_status and cd1.cd_education_status = \u0026#39;Primary\u0026#39; and cd1.cd_education_status = cd2.cd_education_status and ws_sales_price between 100.00 and 150.00 ) or ( cd1.cd_marital_status = \u0026#39;U\u0026#39; and cd1.cd_marital_status = cd2.cd_marital_status and cd1.cd_education_status = \u0026#39;Unknown\u0026#39; and cd1.cd_education_status = cd2.cd_education_status and ws_sales_price between 50.00 and 100.00 ) or ( cd1.cd_marital_status = \u0026#39;M\u0026#39; and cd1.cd_marital_status = cd2.cd_marital_status and cd1.cd_education_status = \u0026#39;Advanced Degree\u0026#39; and cd1.cd_education_status = cd2.cd_education_status and ws_sales_price between 150.00 and 200.00 ) ) and ( ( ca_country = \u0026#39;United States\u0026#39; and ca_state in (\u0026#39;SC\u0026#39;, \u0026#39;IN\u0026#39;, \u0026#39;VA\u0026#39;) and ws_net_profit between 100 and 200 ) or ( ca_country = \u0026#39;United States\u0026#39; and ca_state in (\u0026#39;WA\u0026#39;, \u0026#39;KS\u0026#39;, \u0026#39;KY\u0026#39;) and ws_net_profit between 150 and 300 ) or ( ca_country = \u0026#39;United States\u0026#39; and ca_state in (\u0026#39;SD\u0026#39;, \u0026#39;WI\u0026#39;, \u0026#39;NE\u0026#39;) and ws_net_profit between 50 and 250 ) ) group by r_reason_desc order by substr(r_reason_desc, 1, 20) , avg(ws_quantity) , avg(wr_refunded_cash) , avg(wr_fee) LIMIT 100; -- end query 33 in stream 0 using template query85.tpl -- start query 34 in stream 0 using template query70.tpl select sum(ss_net_profit) as total_sum , s_state , s_county , grouping(s_state) + grouping(s_county) as lochierarchy , rank() over ( partition by grouping(s_state)+grouping(s_county), case when grouping(s_county) = 0 then s_state end order by sum(ss_net_profit) desc) as rank_within_parent from store_sales , date_dim d1 , store where d1.d_month_seq between 1180 and 1180 + 11 and d1.d_date_sk = ss_sold_date_sk and s_store_sk = ss_store_sk and s_state in (select s_state from (select s_state as s_state, rank() over ( partition by s_state order by sum(ss_net_profit) desc) as ranking from store_sales, store, date_dim where d_month_seq between 1180 and 1180 + 11 and d_date_sk = ss_sold_date_sk and s_store_sk = ss_store_sk group by s_state) tmp1 where ranking \u0026lt;= 5) group by rollup (s_state, s_county) order by lochierarchy desc , case when lochierarchy = 0 then s_state end , rank_within_parent LIMIT 100; -- end query 34 in stream 0 using template query70.tpl -- start query 35 in stream 0 using template query67.tpl select * from (select i_category , i_class , i_brand , i_product_name , d_year , d_qoy , d_moy , s_store_id , sumsales , rank() over (partition by i_category order by sumsales desc) rk from (select i_category , i_class , i_brand , i_product_name , d_year , d_qoy , d_moy , s_store_id , sum(coalesce(ss_sales_price * ss_quantity, 0)) sumsales from store_sales , date_dim , store , item where ss_sold_date_sk = d_date_sk and ss_item_sk = i_item_sk and ss_store_sk = s_store_sk and d_month_seq between 1194 and 1194 + 11 group by rollup (i_category, i_class, i_brand, i_product_name, d_year, d_qoy, d_moy, s_store_id)) dw1) dw2 where rk \u0026lt;= 100 order by i_category , i_class , i_brand , i_product_name , d_year , d_qoy , d_moy , s_store_id , sumsales , rk LIMIT 100; -- end query 35 in stream 0 using template query67.tpl -- start query 36 in stream 0 using template query28.tpl select * from (select avg(ss_list_price) B1_LP , count(ss_list_price) B1_CNT , count(distinct ss_list_price) B1_CNTD from store_sales where ss_quantity between 0 and 5 and (ss_list_price between 28 and 28 + 10 or ss_coupon_amt between 12573 and 12573 + 1000 or ss_wholesale_cost between 33 and 33 + 20)) B1, (select avg(ss_list_price) B2_LP , count(ss_list_price) B2_CNT , count(distinct ss_list_price) B2_CNTD from store_sales where ss_quantity between 6 and 10 and (ss_list_price between 143 and 143 + 10 or ss_coupon_amt between 5562 and 5562 + 1000 or ss_wholesale_cost between 45 and 45 + 20)) B2, (select avg(ss_list_price) B3_LP , count(ss_list_price) B3_CNT , count(distinct ss_list_price) B3_CNTD from store_sales where ss_quantity between 11 and 15 and (ss_list_price between 159 and 159 + 10 or ss_coupon_amt between 2807 and 2807 + 1000 or ss_wholesale_cost between 24 and 24 + 20)) B3, (select avg(ss_list_price) B4_LP , count(ss_list_price) B4_CNT , count(distinct ss_list_price) B4_CNTD from store_sales where ss_quantity between 16 and 20 and (ss_list_price between 24 and 24 + 10 or ss_coupon_amt between 3706 and 3706 + 1000 or ss_wholesale_cost between 46 and 46 + 20)) B4, (select avg(ss_list_price) B5_LP , count(ss_list_price) B5_CNT , count(distinct ss_list_price) B5_CNTD from store_sales where ss_quantity between 21 and 25 and (ss_list_price between 76 and 76 + 10 or ss_coupon_amt between 2096 and 2096 + 1000 or ss_wholesale_cost between 50 and 50 + 20)) B5, (select avg(ss_list_price) B6_LP , count(ss_list_price) B6_CNT , count(distinct ss_list_price) B6_CNTD from store_sales where ss_quantity between 26 and 30 and (ss_list_price between 169 and 169 + 10 or ss_coupon_amt between 10672 and 10672 + 1000 or ss_wholesale_cost between 58 and 58 + 20)) B6 LIMIT 100; -- end query 36 in stream 0 using template query28.tpl -- start query 37 in stream 0 using template query81.tpl with customer_total_return as (select cr_returning_customer_sk as ctr_customer_sk , ca_state as ctr_state, sum(cr_return_amt_inc_tax) as ctr_total_return from catalog_returns , date_dim , customer_address where cr_returned_date_sk = d_date_sk and d_year = 1998 and cr_returning_addr_sk = ca_address_sk group by cr_returning_customer_sk , ca_state) select c_customer_id , c_salutation , c_first_name , c_last_name , ca_street_number , ca_street_name , ca_street_type , ca_suite_number , ca_city , ca_county , ca_state , ca_zip , ca_country , ca_gmt_offset , ca_location_type , ctr_total_return from customer_total_return ctr1 , customer_address , customer where ctr1.ctr_total_return \u0026gt; (select avg(ctr_total_return) * 1.2 from customer_total_return ctr2 where ctr1.ctr_state = ctr2.ctr_state) and ca_address_sk = c_current_addr_sk and ca_state = \u0026#39;TX\u0026#39; and ctr1.ctr_customer_sk = c_customer_sk order by c_customer_id, c_salutation, c_first_name, c_last_name, ca_street_number, ca_street_name , ca_street_type, ca_suite_number, ca_city, ca_county, ca_state, ca_zip, ca_country, ca_gmt_offset , ca_location_type, ctr_total_return LIMIT 100; -- end query 37 in stream 0 using template query81.tpl -- start query 38 in stream 0 using template query97.tpl with ssci as (select ss_customer_sk customer_sk , ss_item_sk item_sk from store_sales, date_dim where ss_sold_date_sk = d_date_sk and d_month_seq between 1211 and 1211 + 11 group by ss_customer_sk , ss_item_sk), csci as (select cs_bill_customer_sk customer_sk , cs_item_sk item_sk from catalog_sales, date_dim where cs_sold_date_sk = d_date_sk and d_month_seq between 1211 and 1211 + 11 group by cs_bill_customer_sk , cs_item_sk) select sum(case when ssci.customer_sk is not null and csci.customer_sk is null then 1 else 0 end) store_only , sum(case when ssci.customer_sk is null and csci.customer_sk is not null then 1 else 0 end) catalog_only , sum(case when ssci.customer_sk is not null and csci.customer_sk is not null then 1 else 0 end) store_and_catalog from ssci full outer join csci on (ssci.customer_sk = csci.customer_sk and ssci.item_sk = csci.item_sk) LIMIT 100; -- end query 38 in stream 0 using template query97.tpl -- start query 39 in stream 0 using template query66.tpl select w_warehouse_name , w_warehouse_sq_ft , w_city , w_county , w_state , w_country , ship_carriers , year , sum (jan_sales) as jan_sales , sum (feb_sales) as feb_sales , sum (mar_sales) as mar_sales , sum (apr_sales) as apr_sales , sum (may_sales) as may_sales , sum (jun_sales) as jun_sales , sum (jul_sales) as jul_sales , sum (aug_sales) as aug_sales , sum (sep_sales) as sep_sales , sum (oct_sales) as oct_sales , sum (nov_sales) as nov_sales , sum (dec_sales) as dec_sales , sum (jan_sales/w_warehouse_sq_ft) as jan_sales_per_sq_foot , sum (feb_sales/w_warehouse_sq_ft) as feb_sales_per_sq_foot , sum (mar_sales/w_warehouse_sq_ft) as mar_sales_per_sq_foot , sum (apr_sales/w_warehouse_sq_ft) as apr_sales_per_sq_foot , sum (may_sales/w_warehouse_sq_ft) as may_sales_per_sq_foot , sum (jun_sales/w_warehouse_sq_ft) as jun_sales_per_sq_foot , sum (jul_sales/w_warehouse_sq_ft) as jul_sales_per_sq_foot , sum (aug_sales/w_warehouse_sq_ft) as aug_sales_per_sq_foot , sum (sep_sales/w_warehouse_sq_ft) as sep_sales_per_sq_foot , sum (oct_sales/w_warehouse_sq_ft) as oct_sales_per_sq_foot , sum (nov_sales/w_warehouse_sq_ft) as nov_sales_per_sq_foot , sum (dec_sales/w_warehouse_sq_ft) as dec_sales_per_sq_foot , sum (jan_net) as jan_net , sum (feb_net) as feb_net , sum (mar_net) as mar_net , sum (apr_net) as apr_net , sum (may_net) as may_net , sum (jun_net) as jun_net , sum (jul_net) as jul_net , sum (aug_net) as aug_net , sum (sep_net) as sep_net , sum (oct_net) as oct_net , sum (nov_net) as nov_net , sum (dec_net) as dec_net from ( select w_warehouse_name , w_warehouse_sq_ft , w_city , w_county , w_state , w_country , \u0026#39;FEDEX\u0026#39; || \u0026#39;,\u0026#39; || \u0026#39;GERMA\u0026#39; as ship_carriers , d_year as year , sum (case when d_moy = 1 then ws_ext_list_price* ws_quantity else 0 end) as jan_sales , sum (case when d_moy = 2 then ws_ext_list_price* ws_quantity else 0 end) as feb_sales , sum (case when d_moy = 3 then ws_ext_list_price* ws_quantity else 0 end) as mar_sales , sum (case when d_moy = 4 then ws_ext_list_price* ws_quantity else 0 end) as apr_sales , sum (case when d_moy = 5 then ws_ext_list_price* ws_quantity else 0 end) as may_sales , sum (case when d_moy = 6 then ws_ext_list_price* ws_quantity else 0 end) as jun_sales , sum (case when d_moy = 7 then ws_ext_list_price* ws_quantity else 0 end) as jul_sales , sum (case when d_moy = 8 then ws_ext_list_price* ws_quantity else 0 end) as aug_sales , sum (case when d_moy = 9 then ws_ext_list_price* ws_quantity else 0 end) as sep_sales , sum (case when d_moy = 10 then ws_ext_list_price* ws_quantity else 0 end) as oct_sales , sum (case when d_moy = 11 then ws_ext_list_price* ws_quantity else 0 end) as nov_sales , sum (case when d_moy = 12 then ws_ext_list_price* ws_quantity else 0 end) as dec_sales , sum (case when d_moy = 1 then ws_net_profit * ws_quantity else 0 end) as jan_net , sum (case when d_moy = 2 then ws_net_profit * ws_quantity else 0 end) as feb_net , sum (case when d_moy = 3 then ws_net_profit * ws_quantity else 0 end) as mar_net , sum (case when d_moy = 4 then ws_net_profit * ws_quantity else 0 end) as apr_net , sum (case when d_moy = 5 then ws_net_profit * ws_quantity else 0 end) as may_net , sum (case when d_moy = 6 then ws_net_profit * ws_quantity else 0 end) as jun_net , sum (case when d_moy = 7 then ws_net_profit * ws_quantity else 0 end) as jul_net , sum (case when d_moy = 8 then ws_net_profit * ws_quantity else 0 end) as aug_net , sum (case when d_moy = 9 then ws_net_profit * ws_quantity else 0 end) as sep_net , sum (case when d_moy = 10 then ws_net_profit * ws_quantity else 0 end) as oct_net , sum (case when d_moy = 11 then ws_net_profit * ws_quantity else 0 end) as nov_net , sum (case when d_moy = 12 then ws_net_profit * ws_quantity else 0 end) as dec_net from web_sales , warehouse , date_dim , time_dim , ship_mode where ws_warehouse_sk = w_warehouse_sk and ws_sold_date_sk = d_date_sk and ws_sold_time_sk = t_time_sk and ws_ship_mode_sk = sm_ship_mode_sk and d_year = 2001 and t_time between 19072 and 19072+28800 and sm_carrier in (\u0026#39;FEDEX\u0026#39;, \u0026#39;GERMA\u0026#39;) group by w_warehouse_name , w_warehouse_sq_ft , w_city , w_county , w_state , w_country , d_year union all select w_warehouse_name , w_warehouse_sq_ft , w_city , w_county , w_state , w_country , \u0026#39;FEDEX\u0026#39; || \u0026#39;,\u0026#39; || \u0026#39;GERMA\u0026#39; as ship_carriers , d_year as year , sum (case when d_moy = 1 then cs_sales_price* cs_quantity else 0 end) as jan_sales , sum (case when d_moy = 2 then cs_sales_price* cs_quantity else 0 end) as feb_sales , sum (case when d_moy = 3 then cs_sales_price* cs_quantity else 0 end) as mar_sales , sum (case when d_moy = 4 then cs_sales_price* cs_quantity else 0 end) as apr_sales , sum (case when d_moy = 5 then cs_sales_price* cs_quantity else 0 end) as may_sales , sum (case when d_moy = 6 then cs_sales_price* cs_quantity else 0 end) as jun_sales , sum (case when d_moy = 7 then cs_sales_price* cs_quantity else 0 end) as jul_sales , sum (case when d_moy = 8 then cs_sales_price* cs_quantity else 0 end) as aug_sales , sum (case when d_moy = 9 then cs_sales_price* cs_quantity else 0 end) as sep_sales , sum (case when d_moy = 10 then cs_sales_price* cs_quantity else 0 end) as oct_sales , sum (case when d_moy = 11 then cs_sales_price* cs_quantity else 0 end) as nov_sales , sum (case when d_moy = 12 then cs_sales_price* cs_quantity else 0 end) as dec_sales , sum (case when d_moy = 1 then cs_net_paid * cs_quantity else 0 end) as jan_net , sum (case when d_moy = 2 then cs_net_paid * cs_quantity else 0 end) as feb_net , sum (case when d_moy = 3 then cs_net_paid * cs_quantity else 0 end) as mar_net , sum (case when d_moy = 4 then cs_net_paid * cs_quantity else 0 end) as apr_net , sum (case when d_moy = 5 then cs_net_paid * cs_quantity else 0 end) as may_net , sum (case when d_moy = 6 then cs_net_paid * cs_quantity else 0 end) as jun_net , sum (case when d_moy = 7 then cs_net_paid * cs_quantity else 0 end) as jul_net , sum (case when d_moy = 8 then cs_net_paid * cs_quantity else 0 end) as aug_net , sum (case when d_moy = 9 then cs_net_paid * cs_quantity else 0 end) as sep_net , sum (case when d_moy = 10 then cs_net_paid * cs_quantity else 0 end) as oct_net , sum (case when d_moy = 11 then cs_net_paid * cs_quantity else 0 end) as nov_net , sum (case when d_moy = 12 then cs_net_paid * cs_quantity else 0 end) as dec_net from catalog_sales , warehouse , date_dim , time_dim , ship_mode where cs_warehouse_sk = w_warehouse_sk and cs_sold_date_sk = d_date_sk and cs_sold_time_sk = t_time_sk and cs_ship_mode_sk = sm_ship_mode_sk and d_year = 2001 and t_time between 19072 AND 19072+28800 and sm_carrier in (\u0026#39;FEDEX\u0026#39;, \u0026#39;GERMA\u0026#39;) group by w_warehouse_name , w_warehouse_sq_ft , w_city , w_county , w_state , w_country , d_year ) x group by w_warehouse_name , w_warehouse_sq_ft , w_city , w_county , w_state , w_country , ship_carriers , year order by w_warehouse_name LIMIT 100; -- end query 39 in stream 0 using template query66.tpl -- start query 40 in stream 0 using template query90.tpl select cast(amc as decimal(15, 4)) / cast(pmc as decimal(15, 4)) am_pm_ratio from (select count(*) amc from web_sales, household_demographics, time_dim, web_page where ws_sold_time_sk = time_dim.t_time_sk and ws_ship_hdemo_sk = household_demographics.hd_demo_sk and ws_web_page_sk = web_page.wp_web_page_sk and time_dim.t_hour between 9 and 9 + 1 and household_demographics.hd_dep_count = 2 and web_page.wp_char_count between 5000 and 5200) at, ( select count(*) pmc from web_sales, household_demographics , time_dim, web_page where ws_sold_time_sk = time_dim.t_time_sk and ws_ship_hdemo_sk = household_demographics.hd_demo_sk and ws_web_page_sk = web_page.wp_web_page_sk and time_dim.t_hour between 15 and 15+1 and household_demographics.hd_dep_count = 2 and web_page.wp_char_count between 5000 and 5200) pt order by am_pm_ratio LIMIT 100; -- end query 40 in stream 0 using template query90.tpl -- start query 41 in stream 0 using template query17.tpl select i_item_id , i_item_desc , s_state , count(ss_quantity) as store_sales_quantitycount , avg(ss_quantity) as store_sales_quantityave , stddev_samp(ss_quantity) as store_sales_quantitystdev , stddev_samp(ss_quantity) / avg(ss_quantity) as store_sales_quantitycov , count(sr_return_quantity) as store_returns_quantitycount , avg(sr_return_quantity) as store_returns_quantityave , stddev_samp(sr_return_quantity) as store_returns_quantitystdev , stddev_samp(sr_return_quantity) / avg(sr_return_quantity) as store_returns_quantitycov , count(cs_quantity) as catalog_sales_quantitycount , avg(cs_quantity) as catalog_sales_quantityave , stddev_samp(cs_quantity) as catalog_sales_quantitystdev , stddev_samp(cs_quantity) / avg(cs_quantity) as catalog_sales_quantitycov from store_sales , store_returns , catalog_sales , date_dim d1 , date_dim d2 , date_dim d3 , store , item where d1.d_quarter_name = \u0026#39;1999Q1\u0026#39; and d1.d_date_sk = ss_sold_date_sk and i_item_sk = ss_item_sk and s_store_sk = ss_store_sk and ss_customer_sk = sr_customer_sk and ss_item_sk = sr_item_sk and ss_ticket_number = sr_ticket_number and sr_returned_date_sk = d2.d_date_sk and d2.d_quarter_name in (\u0026#39;1999Q1\u0026#39;, \u0026#39;1999Q2\u0026#39;, \u0026#39;1999Q3\u0026#39;) and sr_customer_sk = cs_bill_customer_sk and sr_item_sk = cs_item_sk and cs_sold_date_sk = d3.d_date_sk and d3.d_quarter_name in (\u0026#39;1999Q1\u0026#39;, \u0026#39;1999Q2\u0026#39;, \u0026#39;1999Q3\u0026#39;) group by i_item_id , i_item_desc , s_state order by i_item_id , i_item_desc , s_state LIMIT 100; -- end query 41 in stream 0 using template query17.tpl -- start query 42 in stream 0 using template query47.tpl with v1 as (select i_category, i_brand, s_store_name, s_company_name, d_year, d_moy, sum(ss_sales_price) sum_sales, avg(sum(ss_sales_price)) over (partition by i_category, i_brand, s_store_name, s_company_name, d_year) avg_monthly_sales, rank() over (partition by i_category, i_brand, s_store_name, s_company_name order by d_year, d_moy) rn from item, store_sales, date_dim, store where ss_item_sk = i_item_sk and ss_sold_date_sk = d_date_sk and ss_store_sk = s_store_sk and ( d_year = 2001 or (d_year = 2001 - 1 and d_moy = 12) or (d_year = 2001 + 1 and d_moy = 1) ) group by i_category, i_brand, s_store_name, s_company_name, d_year, d_moy), v2 as (select v1.i_category , v1.i_brand , v1.s_store_name , v1.s_company_name , v1.d_year , v1.avg_monthly_sales , v1.sum_sales , v1_lag.sum_sales psum , v1_lead.sum_sales nsum from v1, v1 v1_lag, v1 v1_lead where v1.i_category = v1_lag.i_category and v1.i_category = v1_lead.i_category and v1.i_brand = v1_lag.i_brand and v1.i_brand = v1_lead.i_brand and v1.s_store_name = v1_lag.s_store_name and v1.s_store_name = v1_lead.s_store_name and v1.s_company_name = v1_lag.s_company_name and v1.s_company_name = v1_lead.s_company_name and v1.rn = v1_lag.rn + 1 and v1.rn = v1_lead.rn - 1) select * from v2 where d_year = 2001 and avg_monthly_sales \u0026gt; 0 and case when avg_monthly_sales \u0026gt; 0 then abs(sum_sales - avg_monthly_sales) / avg_monthly_sales else null end \u0026gt; 0.1 order by sum_sales - avg_monthly_sales, nsum LIMIT 100; -- end query 42 in stream 0 using template query47.tpl -- start query 43 in stream 0 using template query95.tpl with ws_wh as (select ws1.ws_order_number, ws1.ws_warehouse_sk wh1, ws2.ws_warehouse_sk wh2 from web_sales ws1, web_sales ws2 where ws1.ws_order_number = ws2.ws_order_number and ws1.ws_warehouse_sk \u0026lt;\u0026gt; ws2.ws_warehouse_sk) select count(distinct ws_order_number) as \u0026#34;order count\u0026#34; , sum(ws_ext_ship_cost) as \u0026#34;total shipping cost\u0026#34; , sum(ws_net_profit) as \u0026#34;total net profit\u0026#34; from web_sales ws1 , date_dim , customer_address , web_site where d_date between \u0026#39;2002-5-01\u0026#39; and (cast(\u0026#39;2002-5-01\u0026#39; as date) + 60 days) and ws1.ws_ship_date_sk = d_date_sk and ws1.ws_ship_addr_sk = ca_address_sk and ca_state = \u0026#39;MA\u0026#39; and ws1.ws_web_site_sk = web_site_sk and web_company_name = \u0026#39;pri\u0026#39; and ws1.ws_order_number in (select ws_order_number from ws_wh) and ws1.ws_order_number in (select wr_order_number from web_returns, ws_wh where wr_order_number = ws_wh.ws_order_number) order by count(distinct ws_order_number) LIMIT 100; -- end query 43 in stream 0 using template query95.tpl -- start query 44 in stream 0 using template query92.tpl select sum(ws_ext_discount_amt) as \u0026#34;Excess Discount Amount\u0026#34; from web_sales , item , date_dim where i_manufact_id = 914 and i_item_sk = ws_item_sk and d_date between \u0026#39;2001-01-25\u0026#39; and (cast(\u0026#39;2001-01-25\u0026#39; as date) + 90 days) and d_date_sk = ws_sold_date_sk and ws_ext_discount_amt \u0026gt; (SELECT 1.3 * avg(ws_ext_discount_amt) FROM web_sales , date_dim WHERE ws_item_sk = i_item_sk and d_date between \u0026#39;2001-01-25\u0026#39; and (cast(\u0026#39;2001-01-25\u0026#39; as date) + 90 days) and d_date_sk = ws_sold_date_sk) order by sum(ws_ext_discount_amt) LIMIT 100; -- end query 44 in stream 0 using template query92.tpl -- start query 45 in stream 0 using template query3.tpl select dt.d_year , item.i_brand_id brand_id , item.i_brand brand , sum(ss_net_profit) sum_agg from date_dim dt , store_sales , item where dt.d_date_sk = store_sales.ss_sold_date_sk and store_sales.ss_item_sk = item.i_item_sk and item.i_manufact_id = 445 and dt.d_moy = 12 group by dt.d_year , item.i_brand , item.i_brand_id order by dt.d_year , sum_agg desc , brand_id LIMIT 100; -- end query 45 in stream 0 using template query3.tpl -- start query 46 in stream 0 using template query51.tpl WITH web_v1 as (select ws_item_sk item_sk, d_date, sum(sum(ws_sales_price)) over (partition by ws_item_sk order by d_date rows between unbounded preceding and current row) cume_sales from web_sales , date_dim where ws_sold_date_sk = d_date_sk and d_month_seq between 1215 and 1215 + 11 and ws_item_sk is not NULL group by ws_item_sk, d_date), store_v1 as (select ss_item_sk item_sk, d_date, sum(sum(ss_sales_price)) over (partition by ss_item_sk order by d_date rows between unbounded preceding and current row) cume_sales from store_sales , date_dim where ss_sold_date_sk = d_date_sk and d_month_seq between 1215 and 1215 + 11 and ss_item_sk is not NULL group by ss_item_sk, d_date) select * from (select item_sk , d_date , web_sales , store_sales , max(web_sales) over (partition by item_sk order by d_date rows between unbounded preceding and current row) web_cumulative ,max(store_sales) over (partition by item_sk order by d_date rows between unbounded preceding and current row) store_cumulative from (select case when web.item_sk is not null then web.item_sk else store.item_sk end item_sk , case when web.d_date is not null then web.d_date else store.d_date end d_date , web.cume_sales web_sales , store.cume_sales store_sales from web_v1 web full outer join store_v1 store on (web.item_sk = store.item_sk and web.d_date = store.d_date)) x) y where web_cumulative \u0026gt; store_cumulative order by item_sk , d_date LIMIT 100; -- end query 46 in stream 0 using template query51.tpl -- start query 47 in stream 0 using template query35.tpl select ca_state, cd_gender, cd_marital_status, cd_dep_count, count(*) cnt1, max(cd_dep_count), stddev_samp(cd_dep_count), stddev_samp(cd_dep_count), cd_dep_employed_count, count(*) cnt2, max(cd_dep_employed_count), stddev_samp(cd_dep_employed_count), stddev_samp(cd_dep_employed_count), cd_dep_college_count, count(*) cnt3, max(cd_dep_college_count), stddev_samp(cd_dep_college_count), stddev_samp(cd_dep_college_count) from customer c, customer_address ca, customer_demographics where c.c_current_addr_sk = ca.ca_address_sk and cd_demo_sk = c.c_current_cdemo_sk and exists (select * from store_sales, date_dim where c.c_customer_sk = ss_customer_sk and ss_sold_date_sk = d_date_sk and d_year = 2000 and d_qoy \u0026lt; 4) and (exists (select * from web_sales, date_dim where c.c_customer_sk = ws_bill_customer_sk and ws_sold_date_sk = d_date_sk and d_year = 2000 and d_qoy \u0026lt; 4) or exists (select * from catalog_sales, date_dim where c.c_customer_sk = cs_ship_customer_sk and cs_sold_date_sk = d_date_sk and d_year = 2000 and d_qoy \u0026lt; 4)) group by ca_state, cd_gender, cd_marital_status, cd_dep_count, cd_dep_employed_count, cd_dep_college_count order by ca_state, cd_gender, cd_marital_status, cd_dep_count, cd_dep_employed_count, cd_dep_college_count LIMIT 100; -- end query 47 in stream 0 using template query35.tpl -- start query 48 in stream 0 using template query49.tpl select channel, item, return_ratio, return_rank, currency_rank from (select \u0026#39;web\u0026#39; as channel , web.item , web.return_ratio , web.return_rank , web.currency_rank from (select item , return_ratio , currency_ratio , rank() over (order by return_ratio) as return_rank ,rank() over (order by currency_ratio) as currency_rank from (select ws.ws_item_sk as item , (cast(sum(coalesce(wr.wr_return_quantity, 0)) as decimal(15, 4)) / cast(sum(coalesce(ws.ws_quantity, 0)) as decimal(15, 4))) as return_ratio , (cast(sum(coalesce(wr.wr_return_amt, 0)) as decimal(15, 4)) / cast(sum(coalesce(ws.ws_net_paid, 0)) as decimal(15, 4))) as currency_ratio from web_sales ws left outer join web_returns wr on (ws.ws_order_number = wr.wr_order_number and ws.ws_item_sk = wr.wr_item_sk) , date_dim where wr.wr_return_amt \u0026gt; 10000 and ws.ws_net_profit \u0026gt; 1 and ws.ws_net_paid \u0026gt; 0 and ws.ws_quantity \u0026gt; 0 and ws_sold_date_sk = d_date_sk and d_year = 2000 and d_moy = 12 group by ws.ws_item_sk) in_web) web where ( web.return_rank \u0026lt;= 10 or web.currency_rank \u0026lt;= 10 ) union select \u0026#39;catalog\u0026#39; as channel , catalog.item , catalog.return_ratio , catalog.return_rank , catalog.currency_rank from (select item , return_ratio , currency_ratio , rank() over (order by return_ratio) as return_rank ,rank() over (order by currency_ratio) as currency_rank from (select cs.cs_item_sk as item , (cast(sum(coalesce(cr.cr_return_quantity, 0)) as decimal(15, 4)) / cast(sum(coalesce(cs.cs_quantity, 0)) as decimal(15, 4))) as return_ratio , (cast(sum(coalesce(cr.cr_return_amount, 0)) as decimal(15, 4)) / cast(sum(coalesce(cs.cs_net_paid, 0)) as decimal(15, 4))) as currency_ratio from catalog_sales cs left outer join catalog_returns cr on (cs.cs_order_number = cr.cr_order_number and cs.cs_item_sk = cr.cr_item_sk) , date_dim where cr.cr_return_amount \u0026gt; 10000 and cs.cs_net_profit \u0026gt; 1 and cs.cs_net_paid \u0026gt; 0 and cs.cs_quantity \u0026gt; 0 and cs_sold_date_sk = d_date_sk and d_year = 2000 and d_moy = 12 group by cs.cs_item_sk) in_cat) catalog where ( catalog.return_rank \u0026lt;= 10 or catalog.currency_rank \u0026lt;=10 ) union select \u0026#39;store\u0026#39; as channel , store.item , store.return_ratio , store.return_rank , store.currency_rank from ( select item , return_ratio , currency_ratio , rank() over (order by return_ratio) as return_rank , rank() over (order by currency_ratio) as currency_rank from ( select sts.ss_item_sk as item , (cast (sum (coalesce (sr.sr_return_quantity, 0)) as decimal (15, 4))/ cast (sum (coalesce (sts.ss_quantity, 0)) as decimal (15, 4) )) as return_ratio , (cast (sum (coalesce (sr.sr_return_amt, 0)) as decimal (15, 4))/ cast (sum (coalesce (sts.ss_net_paid, 0)) as decimal (15, 4) )) as currency_ratio from store_sales sts left outer join store_returns sr on (sts.ss_ticket_number = sr.sr_ticket_number and sts.ss_item_sk = sr.sr_item_sk) , date_dim where sr.sr_return_amt \u0026gt; 10000 and sts.ss_net_profit \u0026gt; 1 and sts.ss_net_paid \u0026gt; 0 and sts.ss_quantity \u0026gt; 0 and ss_sold_date_sk = d_date_sk and d_year = 2000 and d_moy = 12 group by sts.ss_item_sk ) in_store ) store where ( store.return_rank \u0026lt;= 10 or store.currency_rank \u0026lt;= 10 )) order by 1, 4, 5, 2 LIMIT 100; -- end query 48 in stream 0 using template query49.tpl -- start query 49 in stream 0 using template query9.tpl select case when (select count(*) from store_sales where ss_quantity between 1 and 20) \u0026gt; 31002 then (select avg(ss_ext_discount_amt) from store_sales where ss_quantity between 1 and 20) else (select avg(ss_net_profit) from store_sales where ss_quantity between 1 and 20) end bucket1, case when (select count(*) from store_sales where ss_quantity between 21 and 40) \u0026gt; 588 then (select avg(ss_ext_discount_amt) from store_sales where ss_quantity between 21 and 40) else (select avg(ss_net_profit) from store_sales where ss_quantity between 21 and 40) end bucket2, case when (select count(*) from store_sales where ss_quantity between 41 and 60) \u0026gt; 2456 then (select avg(ss_ext_discount_amt) from store_sales where ss_quantity between 41 and 60) else (select avg(ss_net_profit) from store_sales where ss_quantity between 41 and 60) end bucket3, case when (select count(*) from store_sales where ss_quantity between 61 and 80) \u0026gt; 21645 then (select avg(ss_ext_discount_amt) from store_sales where ss_quantity between 61 and 80) else (select avg(ss_net_profit) from store_sales where ss_quantity between 61 and 80) end bucket4, case when (select count(*) from store_sales where ss_quantity between 81 and 100) \u0026gt; 20553 then (select avg(ss_ext_discount_amt) from store_sales where ss_quantity between 81 and 100) else (select avg(ss_net_profit) from store_sales where ss_quantity between 81 and 100) end bucket5 from reason where r_reason_sk = 1 ; -- end query 49 in stream 0 using template query9.tpl -- start query 50 in stream 0 using template query31.tpl with ss as (select ca_county, d_qoy, d_year, sum(ss_ext_sales_price) as store_sales from store_sales, date_dim, customer_address where ss_sold_date_sk = d_date_sk and ss_addr_sk = ca_address_sk group by ca_county, d_qoy, d_year), ws as (select ca_county, d_qoy, d_year, sum(ws_ext_sales_price) as web_sales from web_sales, date_dim, customer_address where ws_sold_date_sk = d_date_sk and ws_bill_addr_sk = ca_address_sk group by ca_county, d_qoy, d_year) select ss1.ca_county , ss1.d_year , ws2.web_sales / ws1.web_sales web_q1_q2_increase , ss2.store_sales / ss1.store_sales store_q1_q2_increase , ws3.web_sales / ws2.web_sales web_q2_q3_increase , ss3.store_sales / ss2.store_sales store_q2_q3_increase from ss ss1 , ss ss2 , ss ss3 , ws ws1 , ws ws2 , ws ws3 where ss1.d_qoy = 1 and ss1.d_year = 1999 and ss1.ca_county = ss2.ca_county and ss2.d_qoy = 2 and ss2.d_year = 1999 and ss2.ca_county = ss3.ca_county and ss3.d_qoy = 3 and ss3.d_year = 1999 and ss1.ca_county = ws1.ca_county and ws1.d_qoy = 1 and ws1.d_year = 1999 and ws1.ca_county = ws2.ca_county and ws2.d_qoy = 2 and ws2.d_year = 1999 and ws1.ca_county = ws3.ca_county and ws3.d_qoy = 3 and ws3.d_year = 1999 and case when ws1.web_sales \u0026gt; 0 then ws2.web_sales / ws1.web_sales else null end \u0026gt; case when ss1.store_sales \u0026gt; 0 then ss2.store_sales / ss1.store_sales else null end and case when ws2.web_sales \u0026gt; 0 then ws3.web_sales / ws2.web_sales else null end \u0026gt; case when ss2.store_sales \u0026gt; 0 then ss3.store_sales / ss2.store_sales else null end order by ss1.ca_county; -- end query 50 in stream 0 using template query31.tpl -- start query 51 in stream 0 using template query11.tpl with year_total as (select c_customer_id customer_id , c_first_name customer_first_name , c_last_name customer_last_name , c_preferred_cust_flag customer_preferred_cust_flag , c_birth_country customer_birth_country , c_login customer_login , c_email_address customer_email_address , d_year dyear , sum(ss_ext_list_price - ss_ext_discount_amt) year_total , \u0026#39;s\u0026#39; sale_type from customer , store_sales , date_dim where c_customer_sk = ss_customer_sk and ss_sold_date_sk = d_date_sk group by c_customer_id , c_first_name , c_last_name , c_preferred_cust_flag , c_birth_country , c_login , c_email_address , d_year union all select c_customer_id customer_id , c_first_name customer_first_name , c_last_name customer_last_name , c_preferred_cust_flag customer_preferred_cust_flag , c_birth_country customer_birth_country , c_login customer_login , c_email_address customer_email_address , d_year dyear , sum(ws_ext_list_price - ws_ext_discount_amt) year_total , \u0026#39;w\u0026#39; sale_type from customer , web_sales , date_dim where c_customer_sk = ws_bill_customer_sk and ws_sold_date_sk = d_date_sk group by c_customer_id , c_first_name , c_last_name , c_preferred_cust_flag , c_birth_country , c_login , c_email_address , d_year) select t_s_secyear.customer_id , t_s_secyear.customer_first_name , t_s_secyear.customer_last_name , t_s_secyear.customer_email_address from year_total t_s_firstyear , year_total t_s_secyear , year_total t_w_firstyear , year_total t_w_secyear where t_s_secyear.customer_id = t_s_firstyear.customer_id and t_s_firstyear.customer_id = t_w_secyear.customer_id and t_s_firstyear.customer_id = t_w_firstyear.customer_id and t_s_firstyear.sale_type = \u0026#39;s\u0026#39; and t_w_firstyear.sale_type = \u0026#39;w\u0026#39; and t_s_secyear.sale_type = \u0026#39;s\u0026#39; and t_w_secyear.sale_type = \u0026#39;w\u0026#39; and t_s_firstyear.dyear = 1999 and t_s_secyear.dyear = 1999 + 1 and t_w_firstyear.dyear = 1999 and t_w_secyear.dyear = 1999 + 1 and t_s_firstyear.year_total \u0026gt; 0 and t_w_firstyear.year_total \u0026gt; 0 and case when t_w_firstyear.year_total \u0026gt; 0 then t_w_secyear.year_total / t_w_firstyear.year_total else 0.0 end \u0026gt; case when t_s_firstyear.year_total \u0026gt; 0 then t_s_secyear.year_total / t_s_firstyear.year_total else 0.0 end order by t_s_secyear.customer_id , t_s_secyear.customer_first_name , t_s_secyear.customer_last_name , t_s_secyear.customer_email_address LIMIT 100; -- end query 51 in stream 0 using template query11.tpl -- start query 52 in stream 0 using template query93.tpl select ss_customer_sk , sum(act_sales) sumsales from (select ss_item_sk , ss_ticket_number , ss_customer_sk , case when sr_return_quantity is not null then (ss_quantity - sr_return_quantity) * ss_sales_price else (ss_quantity * ss_sales_price) end act_sales from store_sales left outer join store_returns on (sr_item_sk = ss_item_sk and sr_ticket_number = ss_ticket_number) , reason where sr_reason_sk = r_reason_sk and r_reason_desc = \u0026#39;Did not get it on time\u0026#39;) t group by ss_customer_sk order by sumsales, ss_customer_sk LIMIT 100; -- end query 52 in stream 0 using template query93.tpl -- start query 53 in stream 0 using template query29.tpl select i_item_id , i_item_desc , s_store_id , s_store_name , stddev_samp(ss_quantity) as store_sales_quantity , stddev_samp(sr_return_quantity) as store_returns_quantity , stddev_samp(cs_quantity) as catalog_sales_quantity from store_sales , store_returns , catalog_sales , date_dim d1 , date_dim d2 , date_dim d3 , store , item where d1.d_moy = 4 and d1.d_year = 1999 and d1.d_date_sk = ss_sold_date_sk and i_item_sk = ss_item_sk and s_store_sk = ss_store_sk and ss_customer_sk = sr_customer_sk and ss_item_sk = sr_item_sk and ss_ticket_number = sr_ticket_number and sr_returned_date_sk = d2.d_date_sk and d2.d_moy between 4 and 4 + 3 and d2.d_year = 1999 and sr_customer_sk = cs_bill_customer_sk and sr_item_sk = cs_item_sk and cs_sold_date_sk = d3.d_date_sk and d3.d_year in (1999, 1999 + 1, 1999 + 2) group by i_item_id , i_item_desc , s_store_id , s_store_name order by i_item_id , i_item_desc , s_store_id , s_store_name LIMIT 100; -- end query 53 in stream 0 using template query29.tpl -- start query 54 in stream 0 using template query38.tpl select count(*) from (select distinct c_last_name, c_first_name, d_date from store_sales, date_dim, customer where store_sales.ss_sold_date_sk = date_dim.d_date_sk and store_sales.ss_customer_sk = customer.c_customer_sk and d_month_seq between 1190 and 1190 + 11 intersect select distinct c_last_name, c_first_name, d_date from catalog_sales, date_dim, customer where catalog_sales.cs_sold_date_sk = date_dim.d_date_sk and catalog_sales.cs_bill_customer_sk = customer.c_customer_sk and d_month_seq between 1190 and 1190 + 11 intersect select distinct c_last_name, c_first_name, d_date from web_sales, date_dim, customer where web_sales.ws_sold_date_sk = date_dim.d_date_sk and web_sales.ws_bill_customer_sk = customer.c_customer_sk and d_month_seq between 1190 and 1190 + 11) hot_cust LIMIT 100; -- end query 54 in stream 0 using template query38.tpl -- start query 55 in stream 0 using template query22.tpl select i_product_name , i_brand , i_class , i_category , avg(inv_quantity_on_hand) qoh from inventory , date_dim , item where inv_date_sk = d_date_sk and inv_item_sk = i_item_sk and d_month_seq between 1201 and 1201 + 11 group by rollup (i_product_name , i_brand , i_class , i_category) order by qoh, i_product_name, i_brand, i_class, i_category LIMIT 100; -- end query 55 in stream 0 using template query22.tpl -- start query 56 in stream 0 using template query89.tpl select * from (select i_category, i_class, i_brand, s_store_name, s_company_name, d_moy, sum(ss_sales_price) sum_sales, avg(sum(ss_sales_price)) over (partition by i_category, i_brand, s_store_name, s_company_name) avg_monthly_sales from item, store_sales, date_dim, store where ss_item_sk = i_item_sk and ss_sold_date_sk = d_date_sk and ss_store_sk = s_store_sk and d_year in (2001) and ((i_category in (\u0026#39;Children\u0026#39;, \u0026#39;Jewelry\u0026#39;, \u0026#39;Home\u0026#39;) and i_class in (\u0026#39;infants\u0026#39;, \u0026#39;birdal\u0026#39;, \u0026#39;flatware\u0026#39;) ) or (i_category in (\u0026#39;Electronics\u0026#39;, \u0026#39;Music\u0026#39;, \u0026#39;Books\u0026#39;) and i_class in (\u0026#39;audio\u0026#39;, \u0026#39;classical\u0026#39;, \u0026#39;science\u0026#39;) )) group by i_category, i_class, i_brand, s_store_name, s_company_name, d_moy) tmp1 where case when (avg_monthly_sales \u0026lt;\u0026gt; 0) then (abs(sum_sales - avg_monthly_sales) / avg_monthly_sales) else null end \u0026gt; 0.1 order by sum_sales - avg_monthly_sales, s_store_name LIMIT 100; -- end query 56 in stream 0 using template query89.tpl -- start query 57 in stream 0 using template query15.tpl select ca_zip , sum(cs_sales_price) from catalog_sales , customer , customer_address , date_dim where cs_bill_customer_sk = c_customer_sk and c_current_addr_sk = ca_address_sk and (substr(ca_zip, 1, 5) in (\u0026#39;85669\u0026#39;, \u0026#39;86197\u0026#39;, \u0026#39;88274\u0026#39;, \u0026#39;83405\u0026#39;, \u0026#39;86475\u0026#39;, \u0026#39;85392\u0026#39;, \u0026#39;85460\u0026#39;, \u0026#39;80348\u0026#39;, \u0026#39;81792\u0026#39;) or ca_state in (\u0026#39;CA\u0026#39;, \u0026#39;WA\u0026#39;, \u0026#39;GA\u0026#39;) or cs_sales_price \u0026gt; 500) and cs_sold_date_sk = d_date_sk and d_qoy = 2 and d_year = 2002 group by ca_zip order by ca_zip LIMIT 100; -- end query 57 in stream 0 using template query15.tpl -- start query 58 in stream 0 using template query6.tpl select a.ca_state state, count(*) cnt from customer_address a , customer c , store_sales s , date_dim d , item i where a.ca_address_sk = c.c_current_addr_sk and c.c_customer_sk = s.ss_customer_sk and s.ss_sold_date_sk = d.d_date_sk and s.ss_item_sk = i.i_item_sk and d.d_month_seq = (select distinct (d_month_seq) from date_dim where d_year = 1998 and d_moy = 3) and i.i_current_price \u0026gt; 1.2 * (select avg(j.i_current_price) from item j where j.i_category = i.i_category) group by a.ca_state having count(*) \u0026gt;= 10 order by cnt, a.ca_state LIMIT 100; -- end query 58 in stream 0 using template query6.tpl -- start query 59 in stream 0 using template query52.tpl select dt.d_year , item.i_brand_id brand_id , item.i_brand brand , sum(ss_ext_sales_price) ext_price from date_dim dt , store_sales , item where dt.d_date_sk = store_sales.ss_sold_date_sk and store_sales.ss_item_sk = item.i_item_sk and item.i_manager_id = 1 and dt.d_moy = 11 and dt.d_year = 2000 group by dt.d_year , item.i_brand , item.i_brand_id order by dt.d_year , ext_price desc , brand_id LIMIT 100; -- end query 59 in stream 0 using template query52.tpl -- start query 60 in stream 0 using template query50.tpl select s_store_name , s_company_id , s_street_number , s_street_name , s_street_type , s_suite_number , s_city , s_county , s_state , s_zip , sum(case when (sr_returned_date_sk - ss_sold_date_sk \u0026lt;= 30) then 1 else 0 end) as \u0026#34;30 days\u0026#34; , sum(case when (sr_returned_date_sk - ss_sold_date_sk \u0026gt; 30) and (sr_returned_date_sk - ss_sold_date_sk \u0026lt;= 60) then 1 else 0 end) as \u0026#34;31-60 days\u0026#34; , sum(case when (sr_returned_date_sk - ss_sold_date_sk \u0026gt; 60) and (sr_returned_date_sk - ss_sold_date_sk \u0026lt;= 90) then 1 else 0 end) as \u0026#34;61-90 days\u0026#34; , sum(case when (sr_returned_date_sk - ss_sold_date_sk \u0026gt; 90) and (sr_returned_date_sk - ss_sold_date_sk \u0026lt;= 120) then 1 else 0 end) as \u0026#34;91-120 days\u0026#34; , sum(case when (sr_returned_date_sk - ss_sold_date_sk \u0026gt; 120) then 1 else 0 end) as \u0026#34;\u0026gt;120 days\u0026#34; from store_sales , store_returns , store , date_dim d1 , date_dim d2 where d2.d_year = 2002 and d2.d_moy = 8 and ss_ticket_number = sr_ticket_number and ss_item_sk = sr_item_sk and ss_sold_date_sk = d1.d_date_sk and sr_returned_date_sk = d2.d_date_sk and ss_customer_sk = sr_customer_sk and ss_store_sk = s_store_sk group by s_store_name , s_company_id , s_street_number , s_street_name , s_street_type , s_suite_number , s_city , s_county , s_state , s_zip order by s_store_name , s_company_id , s_street_number , s_street_name , s_street_type , s_suite_number , s_city , s_county , s_state , s_zip LIMIT 100; -- end query 60 in stream 0 using template query50.tpl -- start query 61 in stream 0 using template query42.tpl select dt.d_year , item.i_category_id , item.i_category , sum(ss_ext_sales_price) from date_dim dt , store_sales , item where dt.d_date_sk = store_sales.ss_sold_date_sk and store_sales.ss_item_sk = item.i_item_sk and item.i_manager_id = 1 and dt.d_moy = 11 and dt.d_year = 1998 group by dt.d_year , item.i_category_id , item.i_category order by sum(ss_ext_sales_price) desc, dt.d_year , item.i_category_id , item.i_category LIMIT 100; -- end query 61 in stream 0 using template query42.tpl -- start query 62 in stream 0 using template query41.tpl select distinct(i_product_name) from item i1 where i_manufact_id between 668 and 668 + 40 and (select count(*) as item_cnt from item where (i_manufact = i1.i_manufact and ((i_category = \u0026#39;Women\u0026#39; and (i_color = \u0026#39;cream\u0026#39; or i_color = \u0026#39;ghost\u0026#39;) and (i_units = \u0026#39;Ton\u0026#39; or i_units = \u0026#39;Gross\u0026#39;) and (i_size = \u0026#39;economy\u0026#39; or i_size = \u0026#39;small\u0026#39;) ) or (i_category = \u0026#39;Women\u0026#39; and (i_color = \u0026#39;midnight\u0026#39; or i_color = \u0026#39;burlywood\u0026#39;) and (i_units = \u0026#39;Tsp\u0026#39; or i_units = \u0026#39;Bundle\u0026#39;) and (i_size = \u0026#39;medium\u0026#39; or i_size = \u0026#39;extra large\u0026#39;) ) or (i_category = \u0026#39;Men\u0026#39; and (i_color = \u0026#39;lavender\u0026#39; or i_color = \u0026#39;azure\u0026#39;) and (i_units = \u0026#39;Each\u0026#39; or i_units = \u0026#39;Lb\u0026#39;) and (i_size = \u0026#39;large\u0026#39; or i_size = \u0026#39;N/A\u0026#39;) ) or (i_category = \u0026#39;Men\u0026#39; and (i_color = \u0026#39;chocolate\u0026#39; or i_color = \u0026#39;steel\u0026#39;) and (i_units = \u0026#39;N/A\u0026#39; or i_units = \u0026#39;Dozen\u0026#39;) and (i_size = \u0026#39;economy\u0026#39; or i_size = \u0026#39;small\u0026#39;) ))) or (i_manufact = i1.i_manufact and ((i_category = \u0026#39;Women\u0026#39; and (i_color = \u0026#39;floral\u0026#39; or i_color = \u0026#39;royal\u0026#39;) and (i_units = \u0026#39;Unknown\u0026#39; or i_units = \u0026#39;Tbl\u0026#39;) and (i_size = \u0026#39;economy\u0026#39; or i_size = \u0026#39;small\u0026#39;) ) or (i_category = \u0026#39;Women\u0026#39; and (i_color = \u0026#39;navy\u0026#39; or i_color = \u0026#39;forest\u0026#39;) and (i_units = \u0026#39;Bunch\u0026#39; or i_units = \u0026#39;Dram\u0026#39;) and (i_size = \u0026#39;medium\u0026#39; or i_size = \u0026#39;extra large\u0026#39;) ) or (i_category = \u0026#39;Men\u0026#39; and (i_color = \u0026#39;cyan\u0026#39; or i_color = \u0026#39;indian\u0026#39;) and (i_units = \u0026#39;Carton\u0026#39; or i_units = \u0026#39;Cup\u0026#39;) and (i_size = \u0026#39;large\u0026#39; or i_size = \u0026#39;N/A\u0026#39;) ) or (i_category = \u0026#39;Men\u0026#39; and (i_color = \u0026#39;coral\u0026#39; or i_color = \u0026#39;pale\u0026#39;) and (i_units = \u0026#39;Pallet\u0026#39; or i_units = \u0026#39;Gram\u0026#39;) and (i_size = \u0026#39;economy\u0026#39; or i_size = \u0026#39;small\u0026#39;) )))) \u0026gt; 0 order by i_product_name LIMIT 100; -- end query 62 in stream 0 using template query41.tpl -- start query 63 in stream 0 using template query8.tpl select s_store_name , sum(ss_net_profit) from store_sales , date_dim , store , (select ca_zip from (SELECT substr(ca_zip, 1, 5) ca_zip FROM customer_address WHERE substr(ca_zip, 1, 5) IN ( \u0026#39;19100\u0026#39;, \u0026#39;41548\u0026#39;, \u0026#39;51640\u0026#39;, \u0026#39;49699\u0026#39;, \u0026#39;88329\u0026#39;, \u0026#39;55986\u0026#39;, \u0026#39;85119\u0026#39;, \u0026#39;19510\u0026#39;, \u0026#39;61020\u0026#39;, \u0026#39;95452\u0026#39;, \u0026#39;26235\u0026#39;, \u0026#39;51102\u0026#39;, \u0026#39;16733\u0026#39;, \u0026#39;42819\u0026#39;, \u0026#39;27823\u0026#39;, \u0026#39;90192\u0026#39;, \u0026#39;31905\u0026#39;, \u0026#39;28865\u0026#39;, \u0026#39;62197\u0026#39;, \u0026#39;23750\u0026#39;, \u0026#39;81398\u0026#39;, \u0026#39;95288\u0026#39;, \u0026#39;45114\u0026#39;, \u0026#39;82060\u0026#39;, \u0026#39;12313\u0026#39;, \u0026#39;25218\u0026#39;, \u0026#39;64386\u0026#39;, \u0026#39;46400\u0026#39;, \u0026#39;77230\u0026#39;, \u0026#39;69271\u0026#39;, \u0026#39;43672\u0026#39;, \u0026#39;36521\u0026#39;, \u0026#39;34217\u0026#39;, \u0026#39;13017\u0026#39;, \u0026#39;27936\u0026#39;, \u0026#39;42766\u0026#39;, \u0026#39;59233\u0026#39;, \u0026#39;26060\u0026#39;, \u0026#39;27477\u0026#39;, \u0026#39;39981\u0026#39;, \u0026#39;93402\u0026#39;, \u0026#39;74270\u0026#39;, \u0026#39;13932\u0026#39;, \u0026#39;51731\u0026#39;, \u0026#39;71642\u0026#39;, \u0026#39;17710\u0026#39;, \u0026#39;85156\u0026#39;, \u0026#39;21679\u0026#39;, \u0026#39;70840\u0026#39;, \u0026#39;67191\u0026#39;, \u0026#39;39214\u0026#39;, \u0026#39;35273\u0026#39;, \u0026#39;27293\u0026#39;, \u0026#39;17128\u0026#39;, \u0026#39;15458\u0026#39;, \u0026#39;31615\u0026#39;, \u0026#39;60706\u0026#39;, \u0026#39;67657\u0026#39;, \u0026#39;54092\u0026#39;, \u0026#39;32775\u0026#39;, \u0026#39;14683\u0026#39;, \u0026#39;32206\u0026#39;, \u0026#39;62543\u0026#39;, \u0026#39;43053\u0026#39;, \u0026#39;11297\u0026#39;, \u0026#39;58216\u0026#39;, \u0026#39;49410\u0026#39;, \u0026#39;14710\u0026#39;, \u0026#39;24501\u0026#39;, \u0026#39;79057\u0026#39;, \u0026#39;77038\u0026#39;, \u0026#39;91286\u0026#39;, \u0026#39;32334\u0026#39;, \u0026#39;46298\u0026#39;, \u0026#39;18326\u0026#39;, \u0026#39;67213\u0026#39;, \u0026#39;65382\u0026#39;, \u0026#39;40315\u0026#39;, \u0026#39;56115\u0026#39;, \u0026#39;80162\u0026#39;, \u0026#39;55956\u0026#39;, \u0026#39;81583\u0026#39;, \u0026#39;73588\u0026#39;, \u0026#39;32513\u0026#39;, \u0026#39;62880\u0026#39;, \u0026#39;12201\u0026#39;, \u0026#39;11592\u0026#39;, \u0026#39;17014\u0026#39;, \u0026#39;83832\u0026#39;, \u0026#39;61796\u0026#39;, \u0026#39;57872\u0026#39;, \u0026#39;78829\u0026#39;, \u0026#39;69912\u0026#39;, \u0026#39;48524\u0026#39;, \u0026#39;22016\u0026#39;, \u0026#39;26905\u0026#39;, \u0026#39;48511\u0026#39;, \u0026#39;92168\u0026#39;, \u0026#39;63051\u0026#39;, \u0026#39;25748\u0026#39;, \u0026#39;89786\u0026#39;, \u0026#39;98827\u0026#39;, \u0026#39;86404\u0026#39;, \u0026#39;53029\u0026#39;, \u0026#39;37524\u0026#39;, \u0026#39;14039\u0026#39;, \u0026#39;50078\u0026#39;, \u0026#39;34487\u0026#39;, \u0026#39;70142\u0026#39;, \u0026#39;18697\u0026#39;, \u0026#39;40129\u0026#39;, \u0026#39;60642\u0026#39;, \u0026#39;42810\u0026#39;, \u0026#39;62667\u0026#39;, \u0026#39;57183\u0026#39;, \u0026#39;46414\u0026#39;, \u0026#39;58463\u0026#39;, \u0026#39;71211\u0026#39;, \u0026#39;46364\u0026#39;, \u0026#39;34851\u0026#39;, \u0026#39;54884\u0026#39;, \u0026#39;25382\u0026#39;, \u0026#39;25239\u0026#39;, \u0026#39;74126\u0026#39;, \u0026#39;21568\u0026#39;, \u0026#39;84204\u0026#39;, \u0026#39;13607\u0026#39;, \u0026#39;82518\u0026#39;, \u0026#39;32982\u0026#39;, \u0026#39;36953\u0026#39;, \u0026#39;86001\u0026#39;, \u0026#39;79278\u0026#39;, \u0026#39;21745\u0026#39;, \u0026#39;64444\u0026#39;, \u0026#39;35199\u0026#39;, \u0026#39;83181\u0026#39;, \u0026#39;73255\u0026#39;, \u0026#39;86177\u0026#39;, \u0026#39;98043\u0026#39;, \u0026#39;90392\u0026#39;, \u0026#39;13882\u0026#39;, \u0026#39;47084\u0026#39;, \u0026#39;17859\u0026#39;, \u0026#39;89526\u0026#39;, \u0026#39;42072\u0026#39;, \u0026#39;20233\u0026#39;, \u0026#39;52745\u0026#39;, \u0026#39;75000\u0026#39;, \u0026#39;22044\u0026#39;, \u0026#39;77013\u0026#39;, \u0026#39;24182\u0026#39;, \u0026#39;52554\u0026#39;, \u0026#39;56138\u0026#39;, \u0026#39;43440\u0026#39;, \u0026#39;86100\u0026#39;, \u0026#39;48791\u0026#39;, \u0026#39;21883\u0026#39;, \u0026#39;17096\u0026#39;, \u0026#39;15965\u0026#39;, \u0026#39;31196\u0026#39;, \u0026#39;74903\u0026#39;, \u0026#39;19810\u0026#39;, \u0026#39;35763\u0026#39;, \u0026#39;92020\u0026#39;, \u0026#39;55176\u0026#39;, \u0026#39;54433\u0026#39;, \u0026#39;68063\u0026#39;, \u0026#39;71919\u0026#39;, \u0026#39;44384\u0026#39;, \u0026#39;16612\u0026#39;, \u0026#39;32109\u0026#39;, \u0026#39;28207\u0026#39;, \u0026#39;14762\u0026#39;, \u0026#39;89933\u0026#39;, \u0026#39;10930\u0026#39;, \u0026#39;27616\u0026#39;, \u0026#39;56809\u0026#39;, \u0026#39;14244\u0026#39;, \u0026#39;22733\u0026#39;, \u0026#39;33177\u0026#39;, \u0026#39;29784\u0026#39;, \u0026#39;74968\u0026#39;, \u0026#39;37887\u0026#39;, \u0026#39;11299\u0026#39;, \u0026#39;34692\u0026#39;, \u0026#39;85843\u0026#39;, \u0026#39;83663\u0026#39;, \u0026#39;95421\u0026#39;, \u0026#39;19323\u0026#39;, \u0026#39;17406\u0026#39;, \u0026#39;69264\u0026#39;, \u0026#39;28341\u0026#39;, \u0026#39;50150\u0026#39;, \u0026#39;79121\u0026#39;, \u0026#39;73974\u0026#39;, \u0026#39;92917\u0026#39;, \u0026#39;21229\u0026#39;, \u0026#39;32254\u0026#39;, \u0026#39;97408\u0026#39;, \u0026#39;46011\u0026#39;, \u0026#39;37169\u0026#39;, \u0026#39;18146\u0026#39;, \u0026#39;27296\u0026#39;, \u0026#39;62927\u0026#39;, \u0026#39;68812\u0026#39;, \u0026#39;47734\u0026#39;, \u0026#39;86572\u0026#39;, \u0026#39;12620\u0026#39;, \u0026#39;80252\u0026#39;, \u0026#39;50173\u0026#39;, \u0026#39;27261\u0026#39;, \u0026#39;29534\u0026#39;, \u0026#39;23488\u0026#39;, \u0026#39;42184\u0026#39;, \u0026#39;23695\u0026#39;, \u0026#39;45868\u0026#39;, \u0026#39;12910\u0026#39;, \u0026#39;23429\u0026#39;, \u0026#39;29052\u0026#39;, \u0026#39;63228\u0026#39;, \u0026#39;30731\u0026#39;, \u0026#39;15747\u0026#39;, \u0026#39;25827\u0026#39;, \u0026#39;22332\u0026#39;, \u0026#39;62349\u0026#39;, \u0026#39;56661\u0026#39;, \u0026#39;44652\u0026#39;, \u0026#39;51862\u0026#39;, \u0026#39;57007\u0026#39;, \u0026#39;22773\u0026#39;, \u0026#39;40361\u0026#39;, \u0026#39;65238\u0026#39;, \u0026#39;19327\u0026#39;, \u0026#39;17282\u0026#39;, \u0026#39;44708\u0026#39;, \u0026#39;35484\u0026#39;, \u0026#39;34064\u0026#39;, \u0026#39;11148\u0026#39;, \u0026#39;92729\u0026#39;, \u0026#39;22995\u0026#39;, \u0026#39;18833\u0026#39;, \u0026#39;77528\u0026#39;, \u0026#39;48917\u0026#39;, \u0026#39;17256\u0026#39;, \u0026#39;93166\u0026#39;, \u0026#39;68576\u0026#39;, \u0026#39;71096\u0026#39;, \u0026#39;56499\u0026#39;, \u0026#39;35096\u0026#39;, \u0026#39;80551\u0026#39;, \u0026#39;82424\u0026#39;, \u0026#39;17700\u0026#39;, \u0026#39;32748\u0026#39;, \u0026#39;78969\u0026#39;, \u0026#39;46820\u0026#39;, \u0026#39;57725\u0026#39;, \u0026#39;46179\u0026#39;, \u0026#39;54677\u0026#39;, \u0026#39;98097\u0026#39;, \u0026#39;62869\u0026#39;, \u0026#39;83959\u0026#39;, \u0026#39;66728\u0026#39;, \u0026#39;19716\u0026#39;, \u0026#39;48326\u0026#39;, \u0026#39;27420\u0026#39;, \u0026#39;53458\u0026#39;, \u0026#39;69056\u0026#39;, \u0026#39;84216\u0026#39;, \u0026#39;36688\u0026#39;, \u0026#39;63957\u0026#39;, \u0026#39;41469\u0026#39;, \u0026#39;66843\u0026#39;, \u0026#39;18024\u0026#39;, \u0026#39;81950\u0026#39;, \u0026#39;21911\u0026#39;, \u0026#39;58387\u0026#39;, \u0026#39;58103\u0026#39;, \u0026#39;19813\u0026#39;, \u0026#39;34581\u0026#39;, \u0026#39;55347\u0026#39;, \u0026#39;17171\u0026#39;, \u0026#39;35914\u0026#39;, \u0026#39;75043\u0026#39;, \u0026#39;75088\u0026#39;, \u0026#39;80541\u0026#39;, \u0026#39;26802\u0026#39;, \u0026#39;28849\u0026#39;, \u0026#39;22356\u0026#39;, \u0026#39;57721\u0026#39;, \u0026#39;77084\u0026#39;, \u0026#39;46385\u0026#39;, \u0026#39;59255\u0026#39;, \u0026#39;29308\u0026#39;, \u0026#39;65885\u0026#39;, \u0026#39;70673\u0026#39;, \u0026#39;13306\u0026#39;, \u0026#39;68788\u0026#39;, \u0026#39;87335\u0026#39;, \u0026#39;40987\u0026#39;, \u0026#39;31654\u0026#39;, \u0026#39;67560\u0026#39;, \u0026#39;92309\u0026#39;, \u0026#39;78116\u0026#39;, \u0026#39;65961\u0026#39;, \u0026#39;45018\u0026#39;, \u0026#39;16548\u0026#39;, \u0026#39;67092\u0026#39;, \u0026#39;21818\u0026#39;, \u0026#39;33716\u0026#39;, \u0026#39;49449\u0026#39;, \u0026#39;86150\u0026#39;, \u0026#39;12156\u0026#39;, \u0026#39;27574\u0026#39;, \u0026#39;43201\u0026#39;, \u0026#39;50977\u0026#39;, \u0026#39;52839\u0026#39;, \u0026#39;33234\u0026#39;, \u0026#39;86611\u0026#39;, \u0026#39;71494\u0026#39;, \u0026#39;17823\u0026#39;, \u0026#39;57172\u0026#39;, \u0026#39;59869\u0026#39;, \u0026#39;34086\u0026#39;, \u0026#39;51052\u0026#39;, \u0026#39;11320\u0026#39;, \u0026#39;39717\u0026#39;, \u0026#39;79604\u0026#39;, \u0026#39;24672\u0026#39;, \u0026#39;70555\u0026#39;, \u0026#39;38378\u0026#39;, \u0026#39;91135\u0026#39;, \u0026#39;15567\u0026#39;, \u0026#39;21606\u0026#39;, \u0026#39;74994\u0026#39;, \u0026#39;77168\u0026#39;, \u0026#39;38607\u0026#39;, \u0026#39;27384\u0026#39;, \u0026#39;68328\u0026#39;, \u0026#39;88944\u0026#39;, \u0026#39;40203\u0026#39;, \u0026#39;37893\u0026#39;, \u0026#39;42726\u0026#39;, \u0026#39;83549\u0026#39;, \u0026#39;48739\u0026#39;, \u0026#39;55652\u0026#39;, \u0026#39;27543\u0026#39;, \u0026#39;23109\u0026#39;, \u0026#39;98908\u0026#39;, \u0026#39;28831\u0026#39;, \u0026#39;45011\u0026#39;, \u0026#39;47525\u0026#39;, \u0026#39;43870\u0026#39;, \u0026#39;79404\u0026#39;, \u0026#39;35780\u0026#39;, \u0026#39;42136\u0026#39;, \u0026#39;49317\u0026#39;, \u0026#39;14574\u0026#39;, \u0026#39;99586\u0026#39;, \u0026#39;21107\u0026#39;, \u0026#39;14302\u0026#39;, \u0026#39;83882\u0026#39;, \u0026#39;81272\u0026#39;, \u0026#39;92552\u0026#39;, \u0026#39;14916\u0026#39;, \u0026#39;87533\u0026#39;, \u0026#39;86518\u0026#39;, \u0026#39;17862\u0026#39;, \u0026#39;30741\u0026#39;, \u0026#39;96288\u0026#39;, \u0026#39;57886\u0026#39;, \u0026#39;30304\u0026#39;, \u0026#39;24201\u0026#39;, \u0026#39;79457\u0026#39;, \u0026#39;36728\u0026#39;, \u0026#39;49833\u0026#39;, \u0026#39;35182\u0026#39;, \u0026#39;20108\u0026#39;, \u0026#39;39858\u0026#39;, \u0026#39;10804\u0026#39;, \u0026#39;47042\u0026#39;, \u0026#39;20439\u0026#39;, \u0026#39;54708\u0026#39;, \u0026#39;59027\u0026#39;, \u0026#39;82499\u0026#39;, \u0026#39;75311\u0026#39;, \u0026#39;26548\u0026#39;, \u0026#39;53406\u0026#39;, \u0026#39;92060\u0026#39;, \u0026#39;41152\u0026#39;, \u0026#39;60446\u0026#39;, \u0026#39;33129\u0026#39;, \u0026#39;43979\u0026#39;, \u0026#39;16903\u0026#39;, \u0026#39;60319\u0026#39;, \u0026#39;35550\u0026#39;, \u0026#39;33887\u0026#39;, \u0026#39;25463\u0026#39;, \u0026#39;40343\u0026#39;, \u0026#39;20726\u0026#39;, \u0026#39;44429\u0026#39;) intersect select ca_zip from (SELECT substr(ca_zip, 1, 5) ca_zip, count(*) cnt FROM customer_address, customer WHERE ca_address_sk = c_current_addr_sk and c_preferred_cust_flag = \u0026#39;Y\u0026#39; group by ca_zip having count(*) \u0026gt; 10) A1) A2) V1 where ss_store_sk = s_store_sk and ss_sold_date_sk = d_date_sk and d_qoy = 1 and d_year = 2000 and (substr(s_zip, 1, 2) = substr(V1.ca_zip, 1, 2)) group by s_store_name order by s_store_name LIMIT 100; -- end query 63 in stream 0 using template query8.tpl -- start query 64 in stream 0 using template query12.tpl select i_item_id , i_item_desc , i_category , i_class , i_current_price , sum(ws_ext_sales_price) as itemrevenue , sum(ws_ext_sales_price) * 100 / sum(sum(ws_ext_sales_price)) over (partition by i_class) as revenueratio from web_sales , item , date_dim where ws_item_sk = i_item_sk and i_category in (\u0026#39;Jewelry\u0026#39;, \u0026#39;Books\u0026#39;, \u0026#39;Women\u0026#39;) and ws_sold_date_sk = d_date_sk and d_date between cast(\u0026#39;2002-03-22\u0026#39; as date) and (cast(\u0026#39;2002-03-22\u0026#39; as date) + 30 days) group by i_item_id , i_item_desc , i_category , i_class , i_current_price order by i_category , i_class , i_item_id , i_item_desc , revenueratio LIMIT 100; -- end query 64 in stream 0 using template query12.tpl -- start query 65 in stream 0 using template query20.tpl select i_item_id , i_item_desc , i_category , i_class , i_current_price , sum(cs_ext_sales_price) as itemrevenue , sum(cs_ext_sales_price) * 100 / sum(sum(cs_ext_sales_price)) over (partition by i_class) as revenueratio from catalog_sales , item , date_dim where cs_item_sk = i_item_sk and i_category in (\u0026#39;Children\u0026#39;, \u0026#39;Sports\u0026#39;, \u0026#39;Music\u0026#39;) and cs_sold_date_sk = d_date_sk and d_date between cast(\u0026#39;2002-04-01\u0026#39; as date) and (cast(\u0026#39;2002-04-01\u0026#39; as date) + 30 days) group by i_item_id , i_item_desc , i_category , i_class , i_current_price order by i_category , i_class , i_item_id , i_item_desc , revenueratio LIMIT 100; -- end query 65 in stream 0 using template query20.tpl -- start query 66 in stream 0 using template query88.tpl select * from (select count(*) h8_30_to_9 from store_sales, household_demographics, time_dim, store where ss_sold_time_sk = time_dim.t_time_sk and ss_hdemo_sk = household_demographics.hd_demo_sk and ss_store_sk = s_store_sk and time_dim.t_hour = 8 and time_dim.t_minute \u0026gt;= 30 and ((household_demographics.hd_dep_count = 2 and household_demographics.hd_vehicle_count \u0026lt;= 2 + 2) or (household_demographics.hd_dep_count = 1 and household_demographics.hd_vehicle_count \u0026lt;= 1 + 2) or (household_demographics.hd_dep_count = 4 and household_demographics.hd_vehicle_count \u0026lt;= 4 + 2)) and store.s_store_name = \u0026#39;ese\u0026#39;) s1, (select count(*) h9_to_9_30 from store_sales, household_demographics, time_dim, store where ss_sold_time_sk = time_dim.t_time_sk and ss_hdemo_sk = household_demographics.hd_demo_sk and ss_store_sk = s_store_sk and time_dim.t_hour = 9 and time_dim.t_minute \u0026lt; 30 and ((household_demographics.hd_dep_count = 2 and household_demographics.hd_vehicle_count \u0026lt;= 2 + 2) or (household_demographics.hd_dep_count = 1 and household_demographics.hd_vehicle_count \u0026lt;= 1 + 2) or (household_demographics.hd_dep_count = 4 and household_demographics.hd_vehicle_count \u0026lt;= 4 + 2)) and store.s_store_name = \u0026#39;ese\u0026#39;) s2, (select count(*) h9_30_to_10 from store_sales, household_demographics, time_dim, store where ss_sold_time_sk = time_dim.t_time_sk and ss_hdemo_sk = household_demographics.hd_demo_sk and ss_store_sk = s_store_sk and time_dim.t_hour = 9 and time_dim.t_minute \u0026gt;= 30 and ((household_demographics.hd_dep_count = 2 and household_demographics.hd_vehicle_count \u0026lt;= 2 + 2) or (household_demographics.hd_dep_count = 1 and household_demographics.hd_vehicle_count \u0026lt;= 1 + 2) or (household_demographics.hd_dep_count = 4 and household_demographics.hd_vehicle_count \u0026lt;= 4 + 2)) and store.s_store_name = \u0026#39;ese\u0026#39;) s3, (select count(*) h10_to_10_30 from store_sales, household_demographics, time_dim, store where ss_sold_time_sk = time_dim.t_time_sk and ss_hdemo_sk = household_demographics.hd_demo_sk and ss_store_sk = s_store_sk and time_dim.t_hour = 10 and time_dim.t_minute \u0026lt; 30 and ((household_demographics.hd_dep_count = 2 and household_demographics.hd_vehicle_count \u0026lt;= 2 + 2) or (household_demographics.hd_dep_count = 1 and household_demographics.hd_vehicle_count \u0026lt;= 1 + 2) or (household_demographics.hd_dep_count = 4 and household_demographics.hd_vehicle_count \u0026lt;= 4 + 2)) and store.s_store_name = \u0026#39;ese\u0026#39;) s4, (select count(*) h10_30_to_11 from store_sales, household_demographics, time_dim, store where ss_sold_time_sk = time_dim.t_time_sk and ss_hdemo_sk = household_demographics.hd_demo_sk and ss_store_sk = s_store_sk and time_dim.t_hour = 10 and time_dim.t_minute \u0026gt;= 30 and ((household_demographics.hd_dep_count = 2 and household_demographics.hd_vehicle_count \u0026lt;= 2 + 2) or (household_demographics.hd_dep_count = 1 and household_demographics.hd_vehicle_count \u0026lt;= 1 + 2) or (household_demographics.hd_dep_count = 4 and household_demographics.hd_vehicle_count \u0026lt;= 4 + 2)) and store.s_store_name = \u0026#39;ese\u0026#39;) s5, (select count(*) h11_to_11_30 from store_sales, household_demographics, time_dim, store where ss_sold_time_sk = time_dim.t_time_sk and ss_hdemo_sk = household_demographics.hd_demo_sk and ss_store_sk = s_store_sk and time_dim.t_hour = 11 and time_dim.t_minute \u0026lt; 30 and ((household_demographics.hd_dep_count = 2 and household_demographics.hd_vehicle_count \u0026lt;= 2 + 2) or (household_demographics.hd_dep_count = 1 and household_demographics.hd_vehicle_count \u0026lt;= 1 + 2) or (household_demographics.hd_dep_count = 4 and household_demographics.hd_vehicle_count \u0026lt;= 4 + 2)) and store.s_store_name = \u0026#39;ese\u0026#39;) s6, (select count(*) h11_30_to_12 from store_sales, household_demographics, time_dim, store where ss_sold_time_sk = time_dim.t_time_sk and ss_hdemo_sk = household_demographics.hd_demo_sk and ss_store_sk = s_store_sk and time_dim.t_hour = 11 and time_dim.t_minute \u0026gt;= 30 and ((household_demographics.hd_dep_count = 2 and household_demographics.hd_vehicle_count \u0026lt;= 2 + 2) or (household_demographics.hd_dep_count = 1 and household_demographics.hd_vehicle_count \u0026lt;= 1 + 2) or (household_demographics.hd_dep_count = 4 and household_demographics.hd_vehicle_count \u0026lt;= 4 + 2)) and store.s_store_name = \u0026#39;ese\u0026#39;) s7, (select count(*) h12_to_12_30 from store_sales, household_demographics, time_dim, store where ss_sold_time_sk = time_dim.t_time_sk and ss_hdemo_sk = household_demographics.hd_demo_sk and ss_store_sk = s_store_sk and time_dim.t_hour = 12 and time_dim.t_minute \u0026lt; 30 and ((household_demographics.hd_dep_count = 2 and household_demographics.hd_vehicle_count \u0026lt;= 2 + 2) or (household_demographics.hd_dep_count = 1 and household_demographics.hd_vehicle_count \u0026lt;= 1 + 2) or (household_demographics.hd_dep_count = 4 and household_demographics.hd_vehicle_count \u0026lt;= 4 + 2)) and store.s_store_name = \u0026#39;ese\u0026#39;) s8 ; -- end query 66 in stream 0 using template query88.tpl -- start query 67 in stream 0 using template query82.tpl select i_item_id , i_item_desc , i_current_price from item, inventory, date_dim, store_sales where i_current_price between 69 and 69 + 30 and inv_item_sk = i_item_sk and d_date_sk = inv_date_sk and d_date between cast(\u0026#39;1998-06-06\u0026#39; as date) and (cast(\u0026#39;1998-06-06\u0026#39; as date) + 60 days) and i_manufact_id in (105, 513, 180, 137) and inv_quantity_on_hand between 100 and 500 and ss_item_sk = i_item_sk group by i_item_id, i_item_desc, i_current_price order by i_item_id LIMIT 100; -- end query 67 in stream 0 using template query82.tpl -- start query 68 in stream 0 using template query23.tpl with frequent_ss_items as (select substr(i_item_desc, 1, 30) itemdesc, i_item_sk item_sk, d_date solddate, count(*) cnt from store_sales , date_dim , item where ss_sold_date_sk = d_date_sk and ss_item_sk = i_item_sk and d_year in (2000, 2000 + 1, 2000 + 2, 2000 + 3) group by substr(i_item_desc, 1, 30), i_item_sk, d_date having count(*) \u0026gt; 4), max_store_sales as (select max(csales) tpcds_cmax from (select c_customer_sk, sum(ss_quantity * ss_sales_price) csales from store_sales , customer , date_dim where ss_customer_sk = c_customer_sk and ss_sold_date_sk = d_date_sk and d_year in (2000, 2000 + 1, 2000 + 2, 2000 + 3) group by c_customer_sk)), best_ss_customer as (select c_customer_sk, sum(ss_quantity * ss_sales_price) ssales from store_sales , customer where ss_customer_sk = c_customer_sk group by c_customer_sk having sum(ss_quantity * ss_sales_price) \u0026gt; (95 / 100.0) * (select * from max_store_sales)) select sum(sales) from (select cs_quantity * cs_list_price sales from catalog_sales , date_dim where d_year = 2000 and d_moy = 3 and cs_sold_date_sk = d_date_sk and cs_item_sk in (select item_sk from frequent_ss_items) and cs_bill_customer_sk in (select c_customer_sk from best_ss_customer) union all select ws_quantity * ws_list_price sales from web_sales , date_dim where d_year = 2000 and d_moy = 3 and ws_sold_date_sk = d_date_sk and ws_item_sk in (select item_sk from frequent_ss_items) and ws_bill_customer_sk in (select c_customer_sk from best_ss_customer)) LIMIT 100; with frequent_ss_items as (select substr(i_item_desc, 1, 30) itemdesc, i_item_sk item_sk, d_date solddate, count(*) cnt from store_sales , date_dim , item where ss_sold_date_sk = d_date_sk and ss_item_sk = i_item_sk and d_year in (2000, 2000 + 1, 2000 + 2, 2000 + 3) group by substr(i_item_desc, 1, 30), i_item_sk, d_date having count(*) \u0026gt; 4), max_store_sales as (select max(csales) tpcds_cmax from (select c_customer_sk, sum(ss_quantity * ss_sales_price) csales from store_sales , customer , date_dim where ss_customer_sk = c_customer_sk and ss_sold_date_sk = d_date_sk and d_year in (2000, 2000 + 1, 2000 + 2, 2000 + 3) group by c_customer_sk)), best_ss_customer as (select c_customer_sk, sum(ss_quantity * ss_sales_price) ssales from store_sales , customer where ss_customer_sk = c_customer_sk group by c_customer_sk having sum(ss_quantity * ss_sales_price) \u0026gt; (95 / 100.0) * (select * from max_store_sales)) select c_last_name, c_first_name, sales from (select c_last_name, c_first_name, sum(cs_quantity * cs_list_price) sales from catalog_sales , customer , date_dim where d_year = 2000 and d_moy = 3 and cs_sold_date_sk = d_date_sk and cs_item_sk in (select item_sk from frequent_ss_items) and cs_bill_customer_sk in (select c_customer_sk from best_ss_customer) and cs_bill_customer_sk = c_customer_sk group by c_last_name, c_first_name union all select c_last_name, c_first_name, sum(ws_quantity * ws_list_price) sales from web_sales , customer , date_dim where d_year = 2000 and d_moy = 3 and ws_sold_date_sk = d_date_sk and ws_item_sk in (select item_sk from frequent_ss_items) and ws_bill_customer_sk in (select c_customer_sk from best_ss_customer) and ws_bill_customer_sk = c_customer_sk group by c_last_name, c_first_name) order by c_last_name, c_first_name, sales LIMIT 100; -- end query 68 in stream 0 using template query23.tpl -- start query 69 in stream 0 using template query14.tpl with cross_items as (select i_item_sk ss_item_sk from item, (select iss.i_brand_id brand_id , iss.i_class_id class_id , iss.i_category_id category_id from store_sales , item iss , date_dim d1 where ss_item_sk = iss.i_item_sk and ss_sold_date_sk = d1.d_date_sk and d1.d_year between 1999 AND 1999 + 2 intersect select ics.i_brand_id , ics.i_class_id , ics.i_category_id from catalog_sales , item ics , date_dim d2 where cs_item_sk = ics.i_item_sk and cs_sold_date_sk = d2.d_date_sk and d2.d_year between 1999 AND 1999 + 2 intersect select iws.i_brand_id , iws.i_class_id , iws.i_category_id from web_sales , item iws , date_dim d3 where ws_item_sk = iws.i_item_sk and ws_sold_date_sk = d3.d_date_sk and d3.d_year between 1999 AND 1999 + 2) where i_brand_id = brand_id and i_class_id = class_id and i_category_id = category_id), avg_sales as (select avg(quantity * list_price) average_sales from (select ss_quantity quantity , ss_list_price list_price from store_sales , date_dim where ss_sold_date_sk = d_date_sk and d_year between 1999 and 1999 + 2 union all select cs_quantity quantity , cs_list_price list_price from catalog_sales , date_dim where cs_sold_date_sk = d_date_sk and d_year between 1999 and 1999 + 2 union all select ws_quantity quantity , ws_list_price list_price from web_sales , date_dim where ws_sold_date_sk = d_date_sk and d_year between 1999 and 1999 + 2) x) select channel, i_brand_id, i_class_id, i_category_id, sum(sales), sum(number_sales) from (select \u0026#39;store\u0026#39; channel , i_brand_id , i_class_id , i_category_id , sum(ss_quantity * ss_list_price) sales , count(*) number_sales from store_sales , item , date_dim where ss_item_sk in (select ss_item_sk from cross_items) and ss_item_sk = i_item_sk and ss_sold_date_sk = d_date_sk and d_year = 1999 + 2 and d_moy = 11 group by i_brand_id, i_class_id, i_category_id having sum(ss_quantity * ss_list_price) \u0026gt; (select average_sales from avg_sales) union all select \u0026#39;catalog\u0026#39; channel, i_brand_id, i_class_id, i_category_id, sum(cs_quantity * cs_list_price) sales, count(*) number_sales from catalog_sales , item , date_dim where cs_item_sk in (select ss_item_sk from cross_items) and cs_item_sk = i_item_sk and cs_sold_date_sk = d_date_sk and d_year = 1999 + 2 and d_moy = 11 group by i_brand_id, i_class_id, i_category_id having sum(cs_quantity * cs_list_price) \u0026gt; (select average_sales from avg_sales) union all select \u0026#39;web\u0026#39; channel, i_brand_id, i_class_id, i_category_id, sum(ws_quantity * ws_list_price) sales, count(*) number_sales from web_sales , item , date_dim where ws_item_sk in (select ss_item_sk from cross_items) and ws_item_sk = i_item_sk and ws_sold_date_sk = d_date_sk and d_year = 1999 + 2 and d_moy = 11 group by i_brand_id, i_class_id, i_category_id having sum(ws_quantity * ws_list_price) \u0026gt; (select average_sales from avg_sales)) y group by rollup (channel, i_brand_id, i_class_id, i_category_id) order by channel, i_brand_id, i_class_id, i_category_id LIMIT 100; with cross_items as (select i_item_sk ss_item_sk from item, (select iss.i_brand_id brand_id , iss.i_class_id class_id , iss.i_category_id category_id from store_sales , item iss , date_dim d1 where ss_item_sk = iss.i_item_sk and ss_sold_date_sk = d1.d_date_sk and d1.d_year between 1999 AND 1999 + 2 intersect select ics.i_brand_id , ics.i_class_id , ics.i_category_id from catalog_sales , item ics , date_dim d2 where cs_item_sk = ics.i_item_sk and cs_sold_date_sk = d2.d_date_sk and d2.d_year between 1999 AND 1999 + 2 intersect select iws.i_brand_id , iws.i_class_id , iws.i_category_id from web_sales , item iws , date_dim d3 where ws_item_sk = iws.i_item_sk and ws_sold_date_sk = d3.d_date_sk and d3.d_year between 1999 AND 1999 + 2) x where i_brand_id = brand_id and i_class_id = class_id and i_category_id = category_id), avg_sales as (select avg(quantity * list_price) average_sales from (select ss_quantity quantity , ss_list_price list_price from store_sales , date_dim where ss_sold_date_sk = d_date_sk and d_year between 1999 and 1999 + 2 union all select cs_quantity quantity , cs_list_price list_price from catalog_sales , date_dim where cs_sold_date_sk = d_date_sk and d_year between 1999 and 1999 + 2 union all select ws_quantity quantity , ws_list_price list_price from web_sales , date_dim where ws_sold_date_sk = d_date_sk and d_year between 1999 and 1999 + 2) x) select this_year.channel ty_channel , this_year.i_brand_id ty_brand , this_year.i_class_id ty_class , this_year.i_category_id ty_category , this_year.sales ty_sales , this_year.number_sales ty_number_sales , last_year.channel ly_channel , last_year.i_brand_id ly_brand , last_year.i_class_id ly_class , last_year.i_category_id ly_category , last_year.sales ly_sales , last_year.number_sales ly_number_sales from (select \u0026#39;store\u0026#39; channel , i_brand_id , i_class_id , i_category_id , sum(ss_quantity * ss_list_price) sales , count(*) number_sales from store_sales , item , date_dim where ss_item_sk in (select ss_item_sk from cross_items) and ss_item_sk = i_item_sk and ss_sold_date_sk = d_date_sk and d_week_seq = (select d_week_seq from date_dim where d_year = 1999 + 1 and d_moy = 12 and d_dom = 14) group by i_brand_id, i_class_id, i_category_id having sum(ss_quantity * ss_list_price) \u0026gt; (select average_sales from avg_sales)) this_year, (select \u0026#39;store\u0026#39; channel , i_brand_id , i_class_id , i_category_id , sum(ss_quantity * ss_list_price) sales , count(*) number_sales from store_sales , item , date_dim where ss_item_sk in (select ss_item_sk from cross_items) and ss_item_sk = i_item_sk and ss_sold_date_sk = d_date_sk and d_week_seq = (select d_week_seq from date_dim where d_year = 1999 and d_moy = 12 and d_dom = 14) group by i_brand_id, i_class_id, i_category_id having sum(ss_quantity * ss_list_price) \u0026gt; (select average_sales from avg_sales)) last_year where this_year.i_brand_id = last_year.i_brand_id and this_year.i_class_id = last_year.i_class_id and this_year.i_category_id = last_year.i_category_id order by this_year.channel, this_year.i_brand_id, this_year.i_class_id, this_year.i_category_id LIMIT 100; -- end query 69 in stream 0 using template query14.tpl -- start query 70 in stream 0 using template query57.tpl with v1 as (select i_category, i_brand, cc_name, d_year, d_moy, sum(cs_sales_price) sum_sales, avg(sum(cs_sales_price)) over (partition by i_category, i_brand, cc_name, d_year) avg_monthly_sales, rank() over (partition by i_category, i_brand, cc_name order by d_year, d_moy) rn from item, catalog_sales, date_dim, call_center where cs_item_sk = i_item_sk and cs_sold_date_sk = d_date_sk and cc_call_center_sk = cs_call_center_sk and ( d_year = 2000 or (d_year = 2000 - 1 and d_moy = 12) or (d_year = 2000 + 1 and d_moy = 1) ) group by i_category, i_brand, cc_name, d_year, d_moy), v2 as (select v1.cc_name , v1.d_year , v1.d_moy , v1.avg_monthly_sales , v1.sum_sales , v1_lag.sum_sales psum , v1_lead.sum_sales nsum from v1, v1 v1_lag, v1 v1_lead where v1.i_category = v1_lag.i_category and v1.i_category = v1_lead.i_category and v1.i_brand = v1_lag.i_brand and v1.i_brand = v1_lead.i_brand and v1.cc_name = v1_lag.cc_name and v1.cc_name = v1_lead.cc_name and v1.rn = v1_lag.rn + 1 and v1.rn = v1_lead.rn - 1) select * from v2 where d_year = 2000 and avg_monthly_sales \u0026gt; 0 and case when avg_monthly_sales \u0026gt; 0 then abs(sum_sales - avg_monthly_sales) / avg_monthly_sales else null end \u0026gt; 0.1 order by sum_sales - avg_monthly_sales, psum LIMIT 100; -- end query 70 in stream 0 using template query57.tpl -- start query 71 in stream 0 using template query65.tpl select s_store_name, i_item_desc, sc.revenue, i_current_price, i_wholesale_cost, i_brand from store, item, (select ss_store_sk, avg(revenue) as ave from (select ss_store_sk, ss_item_sk, sum(ss_sales_price) as revenue from store_sales, date_dim where ss_sold_date_sk = d_date_sk and d_month_seq between 1186 and 1186 + 11 group by ss_store_sk, ss_item_sk) sa group by ss_store_sk) sb, (select ss_store_sk, ss_item_sk, sum(ss_sales_price) as revenue from store_sales, date_dim where ss_sold_date_sk = d_date_sk and d_month_seq between 1186 and 1186 + 11 group by ss_store_sk, ss_item_sk) sc where sb.ss_store_sk = sc.ss_store_sk and sc.revenue \u0026lt;= 0.1 * sb.ave and s_store_sk = sc.ss_store_sk and i_item_sk = sc.ss_item_sk order by s_store_name, i_item_desc LIMIT 100; -- end query 71 in stream 0 using template query65.tpl -- start query 72 in stream 0 using template query71.tpl select i_brand_id brand_id, i_brand brand, t_hour, t_minute, sum(ext_price) ext_price from item, (select ws_ext_sales_price as ext_price, ws_sold_date_sk as sold_date_sk, ws_item_sk as sold_item_sk, ws_sold_time_sk as time_sk from web_sales, date_dim where d_date_sk = ws_sold_date_sk and d_moy = 11 and d_year = 2001 union all select cs_ext_sales_price as ext_price, cs_sold_date_sk as sold_date_sk, cs_item_sk as sold_item_sk, cs_sold_time_sk as time_sk from catalog_sales, date_dim where d_date_sk = cs_sold_date_sk and d_moy = 11 and d_year = 2001 union all select ss_ext_sales_price as ext_price, ss_sold_date_sk as sold_date_sk, ss_item_sk as sold_item_sk, ss_sold_time_sk as time_sk from store_sales, date_dim where d_date_sk = ss_sold_date_sk and d_moy = 11 and d_year = 2001) tmp, time_dim where sold_item_sk = i_item_sk and i_manager_id = 1 and time_sk = t_time_sk and (t_meal_time = \u0026#39;breakfast\u0026#39; or t_meal_time = \u0026#39;dinner\u0026#39;) group by i_brand, i_brand_id, t_hour, t_minute order by ext_price desc, i_brand_id ; -- end query 72 in stream 0 using template query71.tpl -- start query 73 in stream 0 using template query34.tpl select c_last_name , c_first_name , c_salutation , c_preferred_cust_flag , ss_ticket_number , cnt from (select ss_ticket_number , ss_customer_sk , count(*) cnt from store_sales, date_dim, store, household_demographics where store_sales.ss_sold_date_sk = date_dim.d_date_sk and store_sales.ss_store_sk = store.s_store_sk and store_sales.ss_hdemo_sk = household_demographics.hd_demo_sk and (date_dim.d_dom between 1 and 3 or date_dim.d_dom between 25 and 28) and (household_demographics.hd_buy_potential = \u0026#39;501-1000\u0026#39; or household_demographics.hd_buy_potential = \u0026#39;Unknown\u0026#39;) and household_demographics.hd_vehicle_count \u0026gt; 0 and (case when household_demographics.hd_vehicle_count \u0026gt; 0 then household_demographics.hd_dep_count / household_demographics.hd_vehicle_count else null end) \u0026gt; 1.2 and date_dim.d_year in (2000, 2000 + 1, 2000 + 2) and store.s_county in (\u0026#39;Williamson County\u0026#39;, \u0026#39;Williamson County\u0026#39;, \u0026#39;Williamson County\u0026#39;, \u0026#39;Williamson County\u0026#39;, \u0026#39;Williamson County\u0026#39;, \u0026#39;Williamson County\u0026#39;, \u0026#39;Williamson County\u0026#39;, \u0026#39;Williamson County\u0026#39;) group by ss_ticket_number, ss_customer_sk) dn, customer where ss_customer_sk = c_customer_sk and cnt between 15 and 20 order by c_last_name, c_first_name, c_salutation, c_preferred_cust_flag desc, ss_ticket_number; -- end query 73 in stream 0 using template query34.tpl -- start query 74 in stream 0 using template query48.tpl select sum(ss_quantity) from store_sales, store, customer_demographics, customer_address, date_dim where s_store_sk = ss_store_sk and ss_sold_date_sk = d_date_sk and d_year = 2001 and ( ( cd_demo_sk = ss_cdemo_sk and cd_marital_status = \u0026#39;W\u0026#39; and cd_education_status = \u0026#39;2 yr Degree\u0026#39; and ss_sales_price between 100.00 and 150.00 ) or ( cd_demo_sk = ss_cdemo_sk and cd_marital_status = \u0026#39;S\u0026#39; and cd_education_status = \u0026#39;Advanced Degree\u0026#39; and ss_sales_price between 50.00 and 100.00 ) or ( cd_demo_sk = ss_cdemo_sk and cd_marital_status = \u0026#39;D\u0026#39; and cd_education_status = \u0026#39;Primary\u0026#39; and ss_sales_price between 150.00 and 200.00 ) ) and ( ( ss_addr_sk = ca_address_sk and ca_country = \u0026#39;United States\u0026#39; and ca_state in (\u0026#39;IL\u0026#39;, \u0026#39;KY\u0026#39;, \u0026#39;OR\u0026#39;) and ss_net_profit between 0 and 2000 ) or (ss_addr_sk = ca_address_sk and ca_country = \u0026#39;United States\u0026#39; and ca_state in (\u0026#39;VA\u0026#39;, \u0026#39;FL\u0026#39;, \u0026#39;AL\u0026#39;) and ss_net_profit between 150 and 3000 ) or (ss_addr_sk = ca_address_sk and ca_country = \u0026#39;United States\u0026#39; and ca_state in (\u0026#39;OK\u0026#39;, \u0026#39;IA\u0026#39;, \u0026#39;TX\u0026#39;) and ss_net_profit between 50 and 25000 ) ) ; -- end query 74 in stream 0 using template query48.tpl -- start query 75 in stream 0 using template query30.tpl with customer_total_return as (select wr_returning_customer_sk as ctr_customer_sk , ca_state as ctr_state, sum(wr_return_amt) as ctr_total_return from web_returns , date_dim , customer_address where wr_returned_date_sk = d_date_sk and d_year = 2000 and wr_returning_addr_sk = ca_address_sk group by wr_returning_customer_sk , ca_state) select c_customer_id , c_salutation , c_first_name , c_last_name , c_preferred_cust_flag , c_birth_day , c_birth_month , c_birth_year , c_birth_country , c_login , c_email_address , c_last_review_date_sk , ctr_total_return from customer_total_return ctr1 , customer_address , customer where ctr1.ctr_total_return \u0026gt; (select avg(ctr_total_return) * 1.2 from customer_total_return ctr2 where ctr1.ctr_state = ctr2.ctr_state) and ca_address_sk = c_current_addr_sk and ca_state = \u0026#39;KS\u0026#39; and ctr1.ctr_customer_sk = c_customer_sk order by c_customer_id, c_salutation, c_first_name, c_last_name, c_preferred_cust_flag , c_birth_day, c_birth_month, c_birth_year, c_birth_country, c_login, c_email_address , c_last_review_date_sk, ctr_total_return LIMIT 100; -- end query 75 in stream 0 using template query30.tpl -- start query 76 in stream 0 using template query74.tpl with year_total as (select c_customer_id customer_id , c_first_name customer_first_name , c_last_name customer_last_name , d_year as year , stddev_samp(ss_net_paid) year_total , \u0026#39;s\u0026#39; sale_type from customer , store_sales , date_dim where c_customer_sk = ss_customer_sk and ss_sold_date_sk = d_date_sk and d_year in (2001 , 2001+1) group by c_customer_id , c_first_name , c_last_name , d_year union all select c_customer_id customer_id , c_first_name customer_first_name , c_last_name customer_last_name , d_year as year ,stddev_samp(ws_net_paid) year_total ,\u0026#39;w\u0026#39; sale_type from customer , web_sales , date_dim where c_customer_sk = ws_bill_customer_sk and ws_sold_date_sk = d_date_sk and d_year in (2001 , 2001+1) group by c_customer_id , c_first_name , c_last_name , d_year ) select t_s_secyear.customer_id, t_s_secyear.customer_first_name, t_s_secyear.customer_last_name from year_total t_s_firstyear , year_total t_s_secyear , year_total t_w_firstyear , year_total t_w_secyear where t_s_secyear.customer_id = t_s_firstyear.customer_id and t_s_firstyear.customer_id = t_w_secyear.customer_id and t_s_firstyear.customer_id = t_w_firstyear.customer_id and t_s_firstyear.sale_type = \u0026#39;s\u0026#39; and t_w_firstyear.sale_type = \u0026#39;w\u0026#39; and t_s_secyear.sale_type = \u0026#39;s\u0026#39; and t_w_secyear.sale_type = \u0026#39;w\u0026#39; and t_s_firstyear.year = 2001 and t_s_secyear.year = 2001 + 1 and t_w_firstyear.year = 2001 and t_w_secyear.year = 2001 + 1 and t_s_firstyear.year_total \u0026gt; 0 and t_w_firstyear.year_total \u0026gt; 0 and case when t_w_firstyear.year_total \u0026gt; 0 then t_w_secyear.year_total / t_w_firstyear.year_total else null end \u0026gt; case when t_s_firstyear.year_total \u0026gt; 0 then t_s_secyear.year_total / t_s_firstyear.year_total else null end order by 3, 2, 1 LIMIT 100; -- end query 76 in stream 0 using template query74.tpl -- start query 77 in stream 0 using template query87.tpl select count(*) from ((select distinct c_last_name, c_first_name, d_date from store_sales, date_dim, customer where store_sales.ss_sold_date_sk = date_dim.d_date_sk and store_sales.ss_customer_sk = customer.c_customer_sk and d_month_seq between 1189 and 1189 + 11) except (select distinct c_last_name, c_first_name, d_date from catalog_sales, date_dim, customer where catalog_sales.cs_sold_date_sk = date_dim.d_date_sk and catalog_sales.cs_bill_customer_sk = customer.c_customer_sk and d_month_seq between 1189 and 1189 + 11) except (select distinct c_last_name, c_first_name, d_date from web_sales, date_dim, customer where web_sales.ws_sold_date_sk = date_dim.d_date_sk and web_sales.ws_bill_customer_sk = customer.c_customer_sk and d_month_seq between 1189 and 1189 + 11)) cool_cust ; -- end query 77 in stream 0 using template query87.tpl -- start query 78 in stream 0 using template query77.tpl with ss as (select s_store_sk, sum(ss_ext_sales_price) as sales, sum(ss_net_profit) as profit from store_sales, date_dim, store where ss_sold_date_sk = d_date_sk and d_date between cast(\u0026#39;2001-08-11\u0026#39; as date) and (cast(\u0026#39;2001-08-11\u0026#39; as date) + 30 days) and ss_store_sk = s_store_sk group by s_store_sk) , sr as (select s_store_sk, sum(sr_return_amt) as returns, sum(sr_net_loss) as profit_loss from store_returns, date_dim, store where sr_returned_date_sk = d_date_sk and d_date between cast(\u0026#39;2001-08-11\u0026#39; as date) and (cast(\u0026#39;2001-08-11\u0026#39; as date) + 30 days) and sr_store_sk = s_store_sk group by s_store_sk), cs as (select cs_call_center_sk, sum(cs_ext_sales_price) as sales, sum(cs_net_profit) as profit from catalog_sales, date_dim where cs_sold_date_sk = d_date_sk and d_date between cast(\u0026#39;2001-08-11\u0026#39; as date) and (cast(\u0026#39;2001-08-11\u0026#39; as date) + 30 days) group by cs_call_center_sk), cr as (select cr_call_center_sk, sum(cr_return_amount) as returns, sum(cr_net_loss) as profit_loss from catalog_returns, date_dim where cr_returned_date_sk = d_date_sk and d_date between cast(\u0026#39;2001-08-11\u0026#39; as date) and (cast(\u0026#39;2001-08-11\u0026#39; as date) + 30 days) group by cr_call_center_sk), ws as (select wp_web_page_sk, sum(ws_ext_sales_price) as sales, sum(ws_net_profit) as profit from web_sales, date_dim, web_page where ws_sold_date_sk = d_date_sk and d_date between cast(\u0026#39;2001-08-11\u0026#39; as date) and (cast(\u0026#39;2001-08-11\u0026#39; as date) + 30 days) and ws_web_page_sk = wp_web_page_sk group by wp_web_page_sk), wr as (select wp_web_page_sk, sum(wr_return_amt) as returns, sum(wr_net_loss) as profit_loss from web_returns, date_dim, web_page where wr_returned_date_sk = d_date_sk and d_date between cast(\u0026#39;2001-08-11\u0026#39; as date) and (cast(\u0026#39;2001-08-11\u0026#39; as date) + 30 days) and wr_web_page_sk = wp_web_page_sk group by wp_web_page_sk) select channel , id , sum(sales) as sales , sum(returns) as returns , sum(profit) as profit from (select \u0026#39;store channel\u0026#39; as channel , ss.s_store_sk as id , sales , coalesce(returns, 0) as returns , (profit - coalesce(profit_loss, 0)) as profit from ss left join sr on ss.s_store_sk = sr.s_store_sk union all select \u0026#39;catalog channel\u0026#39; as channel , cs_call_center_sk as id , sales , returns , (profit - profit_loss) as profit from cs , cr union all select \u0026#39;web channel\u0026#39; as channel , ws.wp_web_page_sk as id , sales , coalesce(returns, 0) returns , (profit - coalesce(profit_loss, 0)) as profit from ws left join wr on ws.wp_web_page_sk = wr.wp_web_page_sk) x group by rollup (channel, id) order by channel , id LIMIT 100; -- end query 78 in stream 0 using template query77.tpl -- start query 79 in stream 0 using template query73.tpl select c_last_name , c_first_name , c_salutation , c_preferred_cust_flag , ss_ticket_number , cnt from (select ss_ticket_number , ss_customer_sk , count(*) cnt from store_sales, date_dim, store, household_demographics where store_sales.ss_sold_date_sk = date_dim.d_date_sk and store_sales.ss_store_sk = store.s_store_sk and store_sales.ss_hdemo_sk = household_demographics.hd_demo_sk and date_dim.d_dom between 1 and 2 and (household_demographics.hd_buy_potential = \u0026#39;1001-5000\u0026#39; or household_demographics.hd_buy_potential = \u0026#39;5001-10000\u0026#39;) and household_demographics.hd_vehicle_count \u0026gt; 0 and case when household_demographics.hd_vehicle_count \u0026gt; 0 then household_demographics.hd_dep_count / household_demographics.hd_vehicle_count else null end \u0026gt; 1 and date_dim.d_year in (1999, 1999 + 1, 1999 + 2) and store.s_county in (\u0026#39;Williamson County\u0026#39;, \u0026#39;Williamson County\u0026#39;, \u0026#39;Williamson County\u0026#39;, \u0026#39;Williamson County\u0026#39;) group by ss_ticket_number, ss_customer_sk) dj, customer where ss_customer_sk = c_customer_sk and cnt between 1 and 5 order by cnt desc, c_last_name asc; -- end query 79 in stream 0 using template query73.tpl -- start query 80 in stream 0 using template query84.tpl select c_customer_id as customer_id , coalesce(c_last_name, \u0026#39;\u0026#39;) || \u0026#39;, \u0026#39; || coalesce(c_first_name, \u0026#39;\u0026#39;) as customername from customer , customer_address , customer_demographics , household_demographics , income_band , store_returns where ca_city = \u0026#39;White Oak\u0026#39; and c_current_addr_sk = ca_address_sk and ib_lower_bound \u0026gt;= 45626 and ib_upper_bound \u0026lt;= 45626 + 50000 and ib_income_band_sk = hd_income_band_sk and cd_demo_sk = c_current_cdemo_sk and hd_demo_sk = c_current_hdemo_sk and sr_cdemo_sk = cd_demo_sk order by c_customer_id LIMIT 100; -- end query 80 in stream 0 using template query84.tpl -- start query 81 in stream 0 using template query54.tpl with my_customers as (select distinct c_customer_sk , c_current_addr_sk from (select cs_sold_date_sk sold_date_sk, cs_bill_customer_sk customer_sk, cs_item_sk item_sk from catalog_sales union all select ws_sold_date_sk sold_date_sk, ws_bill_customer_sk customer_sk, ws_item_sk item_sk from web_sales) cs_or_ws_sales, item, date_dim, customer where sold_date_sk = d_date_sk and item_sk = i_item_sk and i_category = \u0026#39;Men\u0026#39; and i_class = \u0026#39;shirts\u0026#39; and c_customer_sk = cs_or_ws_sales.customer_sk and d_moy = 4 and d_year = 1998) , my_revenue as (select c_customer_sk, sum(ss_ext_sales_price) as revenue from my_customers, store_sales, customer_address, store, date_dim where c_current_addr_sk = ca_address_sk and ca_county = s_county and ca_state = s_state and ss_sold_date_sk = d_date_sk and c_customer_sk = ss_customer_sk and d_month_seq between (select distinct d_month_seq + 1 from date_dim where d_year = 1998 and d_moy = 4) and (select distinct d_month_seq + 3 from date_dim where d_year = 1998 and d_moy = 4) group by c_customer_sk) , segments as (select cast((revenue / 50) as int) as segment from my_revenue) select segment, count(*) as num_customers, segment * 50 as segment_base from segments group by segment order by segment, num_customers LIMIT 100; -- end query 81 in stream 0 using template query54.tpl -- start query 82 in stream 0 using template query55.tpl select i_brand_id brand_id, i_brand brand, sum(ss_ext_sales_price) ext_price from date_dim, store_sales, item where d_date_sk = ss_sold_date_sk and ss_item_sk = i_item_sk and i_manager_id = 20 and d_moy = 12 and d_year = 1998 group by i_brand, i_brand_id order by ext_price desc, i_brand_id LIMIT 100; -- end query 82 in stream 0 using template query55.tpl -- start query 83 in stream 0 using template query56.tpl with ss as (select i_item_id, sum(ss_ext_sales_price) total_sales from store_sales, date_dim, customer_address, item where i_item_id in (select i_item_id from item where i_color in (\u0026#39;powder\u0026#39;, \u0026#39;goldenrod\u0026#39;, \u0026#39;bisque\u0026#39;)) and ss_item_sk = i_item_sk and ss_sold_date_sk = d_date_sk and d_year = 1998 and d_moy = 5 and ss_addr_sk = ca_address_sk and ca_gmt_offset = -5 group by i_item_id), cs as (select i_item_id, sum(cs_ext_sales_price) total_sales from catalog_sales, date_dim, customer_address, item where i_item_id in (select i_item_id from item where i_color in (\u0026#39;powder\u0026#39;, \u0026#39;goldenrod\u0026#39;, \u0026#39;bisque\u0026#39;)) and cs_item_sk = i_item_sk and cs_sold_date_sk = d_date_sk and d_year = 1998 and d_moy = 5 and cs_bill_addr_sk = ca_address_sk and ca_gmt_offset = -5 group by i_item_id), ws as (select i_item_id, sum(ws_ext_sales_price) total_sales from web_sales, date_dim, customer_address, item where i_item_id in (select i_item_id from item where i_color in (\u0026#39;powder\u0026#39;, \u0026#39;goldenrod\u0026#39;, \u0026#39;bisque\u0026#39;)) and ws_item_sk = i_item_sk and ws_sold_date_sk = d_date_sk and d_year = 1998 and d_moy = 5 and ws_bill_addr_sk = ca_address_sk and ca_gmt_offset = -5 group by i_item_id) select i_item_id, sum(total_sales) total_sales from (select * from ss union all select * from cs union all select * from ws) tmp1 group by i_item_id order by total_sales, i_item_id LIMIT 100; -- end query 83 in stream 0 using template query56.tpl -- start query 84 in stream 0 using template query2.tpl with wscs as (select sold_date_sk , sales_price from (select ws_sold_date_sk sold_date_sk , ws_ext_sales_price sales_price from web_sales union all select cs_sold_date_sk sold_date_sk , cs_ext_sales_price sales_price from catalog_sales)), wswscs as (select d_week_seq, sum(case when (d_day_name = \u0026#39;Sunday\u0026#39;) then sales_price else null end) sun_sales, sum(case when (d_day_name = \u0026#39;Monday\u0026#39;) then sales_price else null end) mon_sales, sum(case when (d_day_name = \u0026#39;Tuesday\u0026#39;) then sales_price else null end) tue_sales, sum(case when (d_day_name = \u0026#39;Wednesday\u0026#39;) then sales_price else null end) wed_sales, sum(case when (d_day_name = \u0026#39;Thursday\u0026#39;) then sales_price else null end) thu_sales, sum(case when (d_day_name = \u0026#39;Friday\u0026#39;) then sales_price else null end) fri_sales, sum(case when (d_day_name = \u0026#39;Saturday\u0026#39;) then sales_price else null end) sat_sales from wscs , date_dim where d_date_sk = sold_date_sk group by d_week_seq) select d_week_seq1 , round(sun_sales1 / sun_sales2, 2) , round(mon_sales1 / mon_sales2, 2) , round(tue_sales1 / tue_sales2, 2) , round(wed_sales1 / wed_sales2, 2) , round(thu_sales1 / thu_sales2, 2) , round(fri_sales1 / fri_sales2, 2) , round(sat_sales1 / sat_sales2, 2) from (select wswscs.d_week_seq d_week_seq1 , sun_sales sun_sales1 , mon_sales mon_sales1 , tue_sales tue_sales1 , wed_sales wed_sales1 , thu_sales thu_sales1 , fri_sales fri_sales1 , sat_sales sat_sales1 from wswscs, date_dim where date_dim.d_week_seq = wswscs.d_week_seq and d_year = 2000) y, (select wswscs.d_week_seq d_week_seq2 , sun_sales sun_sales2 , mon_sales mon_sales2 , tue_sales tue_sales2 , wed_sales wed_sales2 , thu_sales thu_sales2 , fri_sales fri_sales2 , sat_sales sat_sales2 from wswscs , date_dim where date_dim.d_week_seq = wswscs.d_week_seq and d_year = 2000 + 1) z where d_week_seq1 = d_week_seq2 - 53 order by d_week_seq1; -- end query 84 in stream 0 using template query2.tpl -- start query 85 in stream 0 using template query26.tpl select i_item_id, avg(cs_quantity) agg1, avg(cs_list_price) agg2, avg(cs_coupon_amt) agg3, avg(cs_sales_price) agg4 from catalog_sales, customer_demographics, date_dim, item, promotion where cs_sold_date_sk = d_date_sk and cs_item_sk = i_item_sk and cs_bill_cdemo_sk = cd_demo_sk and cs_promo_sk = p_promo_sk and cd_gender = \u0026#39;F\u0026#39; and cd_marital_status = \u0026#39;M\u0026#39; and cd_education_status = \u0026#39;4 yr Degree\u0026#39; and (p_channel_email = \u0026#39;N\u0026#39; or p_channel_event = \u0026#39;N\u0026#39;) and d_year = 2000 group by i_item_id order by i_item_id LIMIT 100; -- end query 85 in stream 0 using template query26.tpl -- start query 86 in stream 0 using template query40.tpl select w_state , i_item_id , sum(case when (cast(d_date as date) \u0026lt; cast(\u0026#39;2002-05-18\u0026#39; as date)) then cs_sales_price - coalesce(cr_refunded_cash, 0) else 0 end) as sales_before , sum(case when (cast(d_date as date) \u0026gt;= cast(\u0026#39;2002-05-18\u0026#39; as date)) then cs_sales_price - coalesce(cr_refunded_cash, 0) else 0 end) as sales_after from catalog_sales left outer join catalog_returns on (cs_order_number = cr_order_number and cs_item_sk = cr_item_sk) , warehouse , item , date_dim where i_current_price between 0.99 and 1.49 and i_item_sk = cs_item_sk and cs_warehouse_sk = w_warehouse_sk and cs_sold_date_sk = d_date_sk and d_date between (cast(\u0026#39;2002-05-18\u0026#39; as date) - 30 days) and (cast(\u0026#39;2002-05-18\u0026#39; as date) + 30 days) group by w_state, i_item_id order by w_state, i_item_id LIMIT 100; -- end query 86 in stream 0 using template query40.tpl -- start query 87 in stream 0 using template query72.tpl select i_item_desc , w_warehouse_name , d1.d_week_seq , sum(case when p_promo_sk is null then 1 else 0 end) no_promo , sum(case when p_promo_sk is not null then 1 else 0 end) promo , count(*) total_cnt from catalog_sales join inventory on (cs_item_sk = inv_item_sk) join warehouse on (w_warehouse_sk = inv_warehouse_sk) join item on (i_item_sk = cs_item_sk) join customer_demographics on (cs_bill_cdemo_sk = cd_demo_sk) join household_demographics on (cs_bill_hdemo_sk = hd_demo_sk) join date_dim d1 on (cs_sold_date_sk = d1.d_date_sk) join date_dim d2 on (inv_date_sk = d2.d_date_sk) join date_dim d3 on (cs_ship_date_sk = d3.d_date_sk) left outer join promotion on (cs_promo_sk = p_promo_sk) left outer join catalog_returns on (cr_item_sk = cs_item_sk and cr_order_number = cs_order_number) where d1.d_week_seq = d2.d_week_seq and inv_quantity_on_hand \u0026lt; cs_quantity and d3.d_date \u0026gt; d1.d_date + 5 and hd_buy_potential = \u0026#39;501-1000\u0026#39; and d1.d_year = 1999 and cd_marital_status = \u0026#39;S\u0026#39; group by i_item_desc, w_warehouse_name, d1.d_week_seq order by total_cnt desc, i_item_desc, w_warehouse_name, d_week_seq LIMIT 100; -- end query 87 in stream 0 using template query72.tpl -- start query 88 in stream 0 using template query53.tpl select * from (select i_manufact_id, sum(ss_sales_price) sum_sales, avg(sum(ss_sales_price)) over (partition by i_manufact_id) avg_quarterly_sales from item, store_sales, date_dim, store where ss_item_sk = i_item_sk and ss_sold_date_sk = d_date_sk and ss_store_sk = s_store_sk and d_month_seq in (1197, 1197 + 1, 1197 + 2, 1197 + 3, 1197 + 4, 1197 + 5, 1197 + 6, 1197 + 7, 1197 + 8, 1197 + 9, 1197 + 10, 1197 + 11) and ((i_category in (\u0026#39;Books\u0026#39;, \u0026#39;Children\u0026#39;, \u0026#39;Electronics\u0026#39;) and i_class in (\u0026#39;personal\u0026#39;, \u0026#39;portable\u0026#39;, \u0026#39;reference\u0026#39;, \u0026#39;self-help\u0026#39;) and i_brand in (\u0026#39;scholaramalgamalg #14\u0026#39;, \u0026#39;scholaramalgamalg #7\u0026#39;, \u0026#39;exportiunivamalg #9\u0026#39;, \u0026#39;scholaramalgamalg #9\u0026#39;)) or (i_category in (\u0026#39;Women\u0026#39;, \u0026#39;Music\u0026#39;, \u0026#39;Men\u0026#39;) and i_class in (\u0026#39;accessories\u0026#39;, \u0026#39;classical\u0026#39;, \u0026#39;fragrances\u0026#39;, \u0026#39;pants\u0026#39;) and i_brand in (\u0026#39;amalgimporto #1\u0026#39;, \u0026#39;edu packscholar #1\u0026#39;, \u0026#39;exportiimporto #1\u0026#39;, \u0026#39;importoamalg #1\u0026#39;))) group by i_manufact_id, d_qoy) tmp1 where case when avg_quarterly_sales \u0026gt; 0 then abs(sum_sales - avg_quarterly_sales) / avg_quarterly_sales else null end \u0026gt; 0.1 order by avg_quarterly_sales, sum_sales, i_manufact_id LIMIT 100; -- end query 88 in stream 0 using template query53.tpl -- start query 89 in stream 0 using template query79.tpl select c_last_name, c_first_name, substr(s_city, 1, 30), ss_ticket_number, amt, profit from (select ss_ticket_number , ss_customer_sk , store.s_city , sum(ss_coupon_amt) amt , sum(ss_net_profit) profit from store_sales, date_dim, store, household_demographics where store_sales.ss_sold_date_sk = date_dim.d_date_sk and store_sales.ss_store_sk = store.s_store_sk and store_sales.ss_hdemo_sk = household_demographics.hd_demo_sk and (household_demographics.hd_dep_count = 0 or household_demographics.hd_vehicle_count \u0026gt; 4) and date_dim.d_dow = 1 and date_dim.d_year in (1999, 1999 + 1, 1999 + 2) and store.s_number_employees between 200 and 295 group by ss_ticket_number, ss_customer_sk, ss_addr_sk, store.s_city) ms, customer where ss_customer_sk = c_customer_sk order by c_last_name, c_first_name, substr(s_city, 1, 30), profit LIMIT 100; -- end query 89 in stream 0 using template query79.tpl -- start query 90 in stream 0 using template query18.tpl select i_item_id, ca_country, ca_state, ca_county, avg(cast(cs_quantity as decimal(12, 2))) agg1, avg(cast(cs_list_price as decimal(12, 2))) agg2, avg(cast(cs_coupon_amt as decimal(12, 2))) agg3, avg(cast(cs_sales_price as decimal(12, 2))) agg4, avg(cast(cs_net_profit as decimal(12, 2))) agg5, avg(cast(c_birth_year as decimal(12, 2))) agg6, avg(cast(cd1.cd_dep_count as decimal(12, 2))) agg7 from catalog_sales, customer_demographics cd1, customer_demographics cd2, customer, customer_address, date_dim, item where cs_sold_date_sk = d_date_sk and cs_item_sk = i_item_sk and cs_bill_cdemo_sk = cd1.cd_demo_sk and cs_bill_customer_sk = c_customer_sk and cd1.cd_gender = \u0026#39;M\u0026#39; and cd1.cd_education_status = \u0026#39;Primary\u0026#39; and c_current_cdemo_sk = cd2.cd_demo_sk and c_current_addr_sk = ca_address_sk and c_birth_month in (1, 2, 9, 5, 11, 3) and d_year = 1998 and ca_state in (\u0026#39;MS\u0026#39;, \u0026#39;NE\u0026#39;, \u0026#39;IA\u0026#39;, \u0026#39;MI\u0026#39;, \u0026#39;GA\u0026#39;, \u0026#39;NY\u0026#39;, \u0026#39;CO\u0026#39;) group by rollup (i_item_id, ca_country, ca_state, ca_county) order by ca_country, ca_state, ca_county, i_item_id LIMIT 100; -- end query 90 in stream 0 using template query18.tpl -- start query 91 in stream 0 using template query13.tpl select avg(ss_quantity) , avg(ss_ext_sales_price) , avg(ss_ext_wholesale_cost) , sum(ss_ext_wholesale_cost) from store_sales , store , customer_demographics , household_demographics , customer_address , date_dim where s_store_sk = ss_store_sk and ss_sold_date_sk = d_date_sk and d_year = 2001 and ((ss_hdemo_sk = hd_demo_sk and cd_demo_sk = ss_cdemo_sk and cd_marital_status = \u0026#39;U\u0026#39; and cd_education_status = \u0026#39;4 yr Degree\u0026#39; and ss_sales_price between 100.00 and 150.00 and hd_dep_count = 3 ) or (ss_hdemo_sk = hd_demo_sk and cd_demo_sk = ss_cdemo_sk and cd_marital_status = \u0026#39;S\u0026#39; and cd_education_status = \u0026#39;Unknown\u0026#39; and ss_sales_price between 50.00 and 100.00 and hd_dep_count = 1 ) or (ss_hdemo_sk = hd_demo_sk and cd_demo_sk = ss_cdemo_sk and cd_marital_status = \u0026#39;D\u0026#39; and cd_education_status = \u0026#39;2 yr Degree\u0026#39; and ss_sales_price between 150.00 and 200.00 and hd_dep_count = 1 )) and ((ss_addr_sk = ca_address_sk and ca_country = \u0026#39;United States\u0026#39; and ca_state in (\u0026#39;CO\u0026#39;, \u0026#39;MI\u0026#39;, \u0026#39;MN\u0026#39;) and ss_net_profit between 100 and 200 ) or (ss_addr_sk = ca_address_sk and ca_country = \u0026#39;United States\u0026#39; and ca_state in (\u0026#39;NC\u0026#39;, \u0026#39;NY\u0026#39;, \u0026#39;TX\u0026#39;) and ss_net_profit between 150 and 300 ) or (ss_addr_sk = ca_address_sk and ca_country = \u0026#39;United States\u0026#39; and ca_state in (\u0026#39;CA\u0026#39;, \u0026#39;NE\u0026#39;, \u0026#39;TN\u0026#39;) and ss_net_profit between 50 and 250 )) ; -- end query 91 in stream 0 using template query13.tpl -- start query 92 in stream 0 using template query24.tpl with ssales as (select c_last_name , c_first_name , s_store_name , ca_state , s_state , i_color , i_current_price , i_manager_id , i_units , i_size , sum(ss_net_profit) netpaid from store_sales , store_returns , store , item , customer , customer_address where ss_ticket_number = sr_ticket_number and ss_item_sk = sr_item_sk and ss_customer_sk = c_customer_sk and ss_item_sk = i_item_sk and ss_store_sk = s_store_sk and c_current_addr_sk = ca_address_sk and c_birth_country \u0026lt;\u0026gt; upper(ca_country) and s_zip = ca_zip and s_market_id = 10 group by c_last_name , c_first_name , s_store_name , ca_state , s_state , i_color , i_current_price , i_manager_id , i_units , i_size) select c_last_name , c_first_name , s_store_name , sum(netpaid) paid from ssales where i_color = \u0026#39;orchid\u0026#39; group by c_last_name , c_first_name , s_store_name having sum(netpaid) \u0026gt; (select 0.05 * avg(netpaid) from ssales) order by c_last_name , c_first_name , s_store_name ; with ssales as (select c_last_name , c_first_name , s_store_name , ca_state , s_state , i_color , i_current_price , i_manager_id , i_units , i_size , sum(ss_net_profit) netpaid from store_sales , store_returns , store , item , customer , customer_address where ss_ticket_number = sr_ticket_number and ss_item_sk = sr_item_sk and ss_customer_sk = c_customer_sk and ss_item_sk = i_item_sk and ss_store_sk = s_store_sk and c_current_addr_sk = ca_address_sk and c_birth_country \u0026lt;\u0026gt; upper(ca_country) and s_zip = ca_zip and s_market_id = 10 group by c_last_name , c_first_name , s_store_name , ca_state , s_state , i_color , i_current_price , i_manager_id , i_units , i_size) select c_last_name , c_first_name , s_store_name , sum(netpaid) paid from ssales where i_color = \u0026#39;green\u0026#39; group by c_last_name , c_first_name , s_store_name having sum(netpaid) \u0026gt; (select 0.05 * avg(netpaid) from ssales) order by c_last_name , c_first_name , s_store_name ; -- end query 92 in stream 0 using template query24.tpl -- start query 93 in stream 0 using template query4.tpl with year_total as (select c_customer_id customer_id , c_first_name customer_first_name , c_last_name customer_last_name , c_preferred_cust_flag customer_preferred_cust_flag , c_birth_country customer_birth_country , c_login customer_login , c_email_address customer_email_address , d_year dyear , sum( ((ss_ext_list_price - ss_ext_wholesale_cost - ss_ext_discount_amt) + ss_ext_sales_price) / 2) year_total , \u0026#39;s\u0026#39; sale_type from customer , store_sales , date_dim where c_customer_sk = ss_customer_sk and ss_sold_date_sk = d_date_sk group by c_customer_id , c_first_name , c_last_name , c_preferred_cust_flag , c_birth_country , c_login , c_email_address , d_year union all select c_customer_id customer_id , c_first_name customer_first_name , c_last_name customer_last_name , c_preferred_cust_flag customer_preferred_cust_flag , c_birth_country customer_birth_country , c_login customer_login , c_email_address customer_email_address , d_year dyear , sum(( ((cs_ext_list_price - cs_ext_wholesale_cost - cs_ext_discount_amt) + cs_ext_sales_price) / 2)) year_total , \u0026#39;c\u0026#39; sale_type from customer , catalog_sales , date_dim where c_customer_sk = cs_bill_customer_sk and cs_sold_date_sk = d_date_sk group by c_customer_id , c_first_name , c_last_name , c_preferred_cust_flag , c_birth_country , c_login , c_email_address , d_year union all select c_customer_id customer_id , c_first_name customer_first_name , c_last_name customer_last_name , c_preferred_cust_flag customer_preferred_cust_flag , c_birth_country customer_birth_country , c_login customer_login , c_email_address customer_email_address , d_year dyear , sum(( ((ws_ext_list_price - ws_ext_wholesale_cost - ws_ext_discount_amt) + ws_ext_sales_price) / 2)) year_total , \u0026#39;w\u0026#39; sale_type from customer , web_sales , date_dim where c_customer_sk = ws_bill_customer_sk and ws_sold_date_sk = d_date_sk group by c_customer_id , c_first_name , c_last_name , c_preferred_cust_flag , c_birth_country , c_login , c_email_address , d_year) select t_s_secyear.customer_id , t_s_secyear.customer_first_name , t_s_secyear.customer_last_name , t_s_secyear.customer_email_address from year_total t_s_firstyear , year_total t_s_secyear , year_total t_c_firstyear , year_total t_c_secyear , year_total t_w_firstyear , year_total t_w_secyear where t_s_secyear.customer_id = t_s_firstyear.customer_id and t_s_firstyear.customer_id = t_c_secyear.customer_id and t_s_firstyear.customer_id = t_c_firstyear.customer_id and t_s_firstyear.customer_id = t_w_firstyear.customer_id and t_s_firstyear.customer_id = t_w_secyear.customer_id and t_s_firstyear.sale_type = \u0026#39;s\u0026#39; and t_c_firstyear.sale_type = \u0026#39;c\u0026#39; and t_w_firstyear.sale_type = \u0026#39;w\u0026#39; and t_s_secyear.sale_type = \u0026#39;s\u0026#39; and t_c_secyear.sale_type = \u0026#39;c\u0026#39; and t_w_secyear.sale_type = \u0026#39;w\u0026#39; and t_s_firstyear.dyear = 2001 and t_s_secyear.dyear = 2001 + 1 and t_c_firstyear.dyear = 2001 and t_c_secyear.dyear = 2001 + 1 and t_w_firstyear.dyear = 2001 and t_w_secyear.dyear = 2001 + 1 and t_s_firstyear.year_total \u0026gt; 0 and t_c_firstyear.year_total \u0026gt; 0 and t_w_firstyear.year_total \u0026gt; 0 and case when t_c_firstyear.year_total \u0026gt; 0 then t_c_secyear.year_total / t_c_firstyear.year_total else null end \u0026gt; case when t_s_firstyear.year_total \u0026gt; 0 then t_s_secyear.year_total / t_s_firstyear.year_total else null end and case when t_c_firstyear.year_total \u0026gt; 0 then t_c_secyear.year_total / t_c_firstyear.year_total else null end \u0026gt; case when t_w_firstyear.year_total \u0026gt; 0 then t_w_secyear.year_total / t_w_firstyear.year_total else null end order by t_s_secyear.customer_id , t_s_secyear.customer_first_name , t_s_secyear.customer_last_name , t_s_secyear.customer_email_address LIMIT 100; -- end query 93 in stream 0 using template query4.tpl -- start query 94 in stream 0 using template query99.tpl select substr(w_warehouse_name, 1, 20) , sm_type , cc_name , sum(case when (cs_ship_date_sk - cs_sold_date_sk \u0026lt;= 30) then 1 else 0 end) as \u0026#34;30 days\u0026#34; , sum(case when (cs_ship_date_sk - cs_sold_date_sk \u0026gt; 30) and (cs_ship_date_sk - cs_sold_date_sk \u0026lt;= 60) then 1 else 0 end) as \u0026#34;31-60 days\u0026#34; , sum(case when (cs_ship_date_sk - cs_sold_date_sk \u0026gt; 60) and (cs_ship_date_sk - cs_sold_date_sk \u0026lt;= 90) then 1 else 0 end) as \u0026#34;61-90 days\u0026#34; , sum(case when (cs_ship_date_sk - cs_sold_date_sk \u0026gt; 90) and (cs_ship_date_sk - cs_sold_date_sk \u0026lt;= 120) then 1 else 0 end) as \u0026#34;91-120 days\u0026#34; , sum(case when (cs_ship_date_sk - cs_sold_date_sk \u0026gt; 120) then 1 else 0 end) as \u0026#34;\u0026gt;120 days\u0026#34; from catalog_sales , warehouse , ship_mode , call_center , date_dim where d_month_seq between 1188 and 1188 + 11 and cs_ship_date_sk = d_date_sk and cs_warehouse_sk = w_warehouse_sk and cs_ship_mode_sk = sm_ship_mode_sk and cs_call_center_sk = cc_call_center_sk group by substr(w_warehouse_name, 1, 20) , sm_type , cc_name order by substr(w_warehouse_name, 1, 20) , sm_type , cc_name LIMIT 100; -- end query 94 in stream 0 using template query99.tpl -- start query 95 in stream 0 using template query68.tpl select c_last_name , c_first_name , ca_city , bought_city , ss_ticket_number , extended_price , extended_tax , list_price from (select ss_ticket_number , ss_customer_sk , ca_city bought_city , sum(ss_ext_sales_price) extended_price , sum(ss_ext_list_price) list_price , sum(ss_ext_tax) extended_tax from store_sales , date_dim , store , household_demographics , customer_address where store_sales.ss_sold_date_sk = date_dim.d_date_sk and store_sales.ss_store_sk = store.s_store_sk and store_sales.ss_hdemo_sk = household_demographics.hd_demo_sk and store_sales.ss_addr_sk = customer_address.ca_address_sk and date_dim.d_dom between 1 and 2 and (household_demographics.hd_dep_count = 8 or household_demographics.hd_vehicle_count = 3) and date_dim.d_year in (2000, 2000 + 1, 2000 + 2) and store.s_city in (\u0026#39;Midway\u0026#39;, \u0026#39;Fairview\u0026#39;) group by ss_ticket_number , ss_customer_sk , ss_addr_sk, ca_city) dn , customer , customer_address current_addr where ss_customer_sk = c_customer_sk and customer.c_current_addr_sk = current_addr.ca_address_sk and current_addr.ca_city \u0026lt;\u0026gt; bought_city order by c_last_name , ss_ticket_number LIMIT 100; -- end query 95 in stream 0 using template query68.tpl -- start query 96 in stream 0 using template query83.tpl with sr_items as (select i_item_id item_id, sum(sr_return_quantity) sr_item_qty from store_returns, item, date_dim where sr_item_sk = i_item_sk and d_date in (select d_date from date_dim where d_week_seq in (select d_week_seq from date_dim where d_date in (\u0026#39;2000-04-29\u0026#39;, \u0026#39;2000-09-09\u0026#39;, \u0026#39;2000-11-02\u0026#39;))) and sr_returned_date_sk = d_date_sk group by i_item_id), cr_items as (select i_item_id item_id, sum(cr_return_quantity) cr_item_qty from catalog_returns, item, date_dim where cr_item_sk = i_item_sk and d_date in (select d_date from date_dim where d_week_seq in (select d_week_seq from date_dim where d_date in (\u0026#39;2000-04-29\u0026#39;, \u0026#39;2000-09-09\u0026#39;, \u0026#39;2000-11-02\u0026#39;))) and cr_returned_date_sk = d_date_sk group by i_item_id), wr_items as (select i_item_id item_id, sum(wr_return_quantity) wr_item_qty from web_returns, item, date_dim where wr_item_sk = i_item_sk and d_date in (select d_date from date_dim where d_week_seq in (select d_week_seq from date_dim where d_date in (\u0026#39;2000-04-29\u0026#39;, \u0026#39;2000-09-09\u0026#39;, \u0026#39;2000-11-02\u0026#39;))) and wr_returned_date_sk = d_date_sk group by i_item_id) select sr_items.item_id , sr_item_qty , sr_item_qty / (sr_item_qty + cr_item_qty + wr_item_qty) / 3.0 * 100 sr_dev , cr_item_qty , cr_item_qty / (sr_item_qty + cr_item_qty + wr_item_qty) / 3.0 * 100 cr_dev , wr_item_qty , wr_item_qty / (sr_item_qty + cr_item_qty + wr_item_qty) / 3.0 * 100 wr_dev , (sr_item_qty + cr_item_qty + wr_item_qty) / 3.0 average from sr_items , cr_items , wr_items where sr_items.item_id = cr_items.item_id and sr_items.item_id = wr_items.item_id order by sr_items.item_id , sr_item_qty LIMIT 100; -- end query 96 in stream 0 using template query83.tpl -- start query 97 in stream 0 using template query61.tpl select promotions, total, cast(promotions as decimal(15, 4)) / cast(total as decimal(15, 4)) * 100 from (select sum(ss_ext_sales_price) promotions from store_sales , store , promotion , date_dim , customer , customer_address , item where ss_sold_date_sk = d_date_sk and ss_store_sk = s_store_sk and ss_promo_sk = p_promo_sk and ss_customer_sk = c_customer_sk and ca_address_sk = c_current_addr_sk and ss_item_sk = i_item_sk and ca_gmt_offset = -6 and i_category = \u0026#39;Sports\u0026#39; and (p_channel_dmail = \u0026#39;Y\u0026#39; or p_channel_email = \u0026#39;Y\u0026#39; or p_channel_tv = \u0026#39;Y\u0026#39;) and s_gmt_offset = -6 and d_year = 2002 and d_moy = 11) promotional_sales, (select sum(ss_ext_sales_price) total from store_sales , store , date_dim , customer , customer_address , item where ss_sold_date_sk = d_date_sk and ss_store_sk = s_store_sk and ss_customer_sk = c_customer_sk and ca_address_sk = c_current_addr_sk and ss_item_sk = i_item_sk and ca_gmt_offset = -6 and i_category = \u0026#39;Sports\u0026#39; and s_gmt_offset = -6 and d_year = 2002 and d_moy = 11) all_sales order by promotions, total LIMIT 100; -- end query 97 in stream 0 using template query61.tpl -- start query 98 in stream 0 using template query5.tpl with ssr as (select s_store_id, sum(sales_price) as sales, sum(profit) as profit, sum(return_amt) as returns, sum(net_loss) as profit_loss from (select ss_store_sk as store_sk, ss_sold_date_sk as date_sk, ss_ext_sales_price as sales_price, ss_net_profit as profit, cast(0 as decimal(7, 2)) as return_amt, cast(0 as decimal(7, 2)) as net_loss from store_sales union all select sr_store_sk as store_sk, sr_returned_date_sk as date_sk, cast(0 as decimal(7, 2)) as sales_price, cast(0 as decimal(7, 2)) as profit, sr_return_amt as return_amt, sr_net_loss as net_loss from store_returns) salesreturns, date_dim, store where date_sk = d_date_sk and d_date between cast(\u0026#39;2001-08-04\u0026#39; as date) and (cast(\u0026#39;2001-08-04\u0026#39; as date) + 14 days) and store_sk = s_store_sk group by s_store_id) , csr as (select cp_catalog_page_id, sum(sales_price) as sales, sum(profit) as profit, sum(return_amt) as returns, sum(net_loss) as profit_loss from (select cs_catalog_page_sk as page_sk, cs_sold_date_sk as date_sk, cs_ext_sales_price as sales_price, cs_net_profit as profit, cast(0 as decimal(7, 2)) as return_amt, cast(0 as decimal(7, 2)) as net_loss from catalog_sales union all select cr_catalog_page_sk as page_sk, cr_returned_date_sk as date_sk, cast(0 as decimal(7, 2)) as sales_price, cast(0 as decimal(7, 2)) as profit, cr_return_amount as return_amt, cr_net_loss as net_loss from catalog_returns) salesreturns, date_dim, catalog_page where date_sk = d_date_sk and d_date between cast(\u0026#39;2001-08-04\u0026#39; as date) and (cast(\u0026#39;2001-08-04\u0026#39; as date) + 14 days) and page_sk = cp_catalog_page_sk group by cp_catalog_page_id) , wsr as (select web_site_id, sum(sales_price) as sales, sum(profit) as profit, sum(return_amt) as returns, sum(net_loss) as profit_loss from (select ws_web_site_sk as wsr_web_site_sk, ws_sold_date_sk as date_sk, ws_ext_sales_price as sales_price, ws_net_profit as profit, cast(0 as decimal(7, 2)) as return_amt, cast(0 as decimal(7, 2)) as net_loss from web_sales union all select ws_web_site_sk as wsr_web_site_sk, wr_returned_date_sk as date_sk, cast(0 as decimal(7, 2)) as sales_price, cast(0 as decimal(7, 2)) as profit, wr_return_amt as return_amt, wr_net_loss as net_loss from web_returns left outer join web_sales on (wr_item_sk = ws_item_sk and wr_order_number = ws_order_number)) salesreturns, date_dim, web_site where date_sk = d_date_sk and d_date between cast(\u0026#39;2001-08-04\u0026#39; as date) and (cast(\u0026#39;2001-08-04\u0026#39; as date) + 14 days) and wsr_web_site_sk = web_site_sk group by web_site_id) select channel , id , sum(sales) as sales , sum(returns) as returns , sum(profit) as profit from (select \u0026#39;store channel\u0026#39; as channel , \u0026#39;store\u0026#39; || s_store_id as id , sales , returns , (profit - profit_loss) as profit from ssr union all select \u0026#39;catalog channel\u0026#39; as channel , \u0026#39;catalog_page\u0026#39; || cp_catalog_page_id as id , sales , returns , (profit - profit_loss) as profit from csr union all select \u0026#39;web channel\u0026#39; as channel , \u0026#39;web_site\u0026#39; || web_site_id as id , sales , returns , (profit - profit_loss) as profit from wsr) x group by rollup (channel, id) order by channel , id LIMIT 100; -- end query 98 in stream 0 using template query5.tpl -- start query 99 in stream 0 using template query76.tpl select channel, col_name, d_year, d_qoy, i_category, COUNT(*) sales_cnt, SUM(ext_sales_price) sales_amt FROM (SELECT \u0026#39;store\u0026#39; as channel, \u0026#39;ss_customer_sk\u0026#39; col_name, d_year, d_qoy, i_category, ss_ext_sales_price ext_sales_price FROM store_sales, item, date_dim WHERE ss_customer_sk IS NULL AND ss_sold_date_sk = d_date_sk AND ss_item_sk = i_item_sk UNION ALL SELECT \u0026#39;web\u0026#39; as channel, \u0026#39;ws_ship_hdemo_sk\u0026#39; col_name, d_year, d_qoy, i_category, ws_ext_sales_price ext_sales_price FROM web_sales, item, date_dim WHERE ws_ship_hdemo_sk IS NULL AND ws_sold_date_sk = d_date_sk AND ws_item_sk = i_item_sk UNION ALL SELECT \u0026#39;catalog\u0026#39; as channel, \u0026#39;cs_bill_customer_sk\u0026#39; col_name, d_year, d_qoy, i_category, cs_ext_sales_price ext_sales_price FROM catalog_sales, item, date_dim WHERE cs_bill_customer_sk IS NULL AND cs_sold_date_sk = d_date_sk AND cs_item_sk = i_item_sk) foo GROUP BY channel, col_name, d_year, d_qoy, i_category ORDER BY channel, col_name, d_year, d_qoy, i_category LIMIT 100; -- end query 99 in stream 0 using template query76.tpl \\timing off ","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/tpcc/","summary":"\u003ch1 id=\"2-安装数据库\"\u003e2 安装数据库\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003escp shenkun@172.16.100.134:/home/shenkun/g100/pkg-5-19.tar.gz ./\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evast@123\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003ePATH\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$PATH\u003c/span\u003e:\u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/bin\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e LD_\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ealias\u003c/span\u003e \u003cspan class=\"nv\"\u003evinit\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;vb_initdb -D $GAUSSHOME/data -w vb.12345 --nodename=db1\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ealias\u003c/span\u003e \u003cspan class=\"nv\"\u003evstart\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;vb_ctl start -D $GAUSSHOME/data\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ealias\u003c/span\u003e \u003cspan class=\"nv\"\u003evrestart\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;vb_ctl restart -D $GAUSSHOME/data\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"3-安装benchmarksql\"\u003e3 安装benchmarksql\u003c/h1\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e一、下载benchmarksql\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 1.安装java openjdk\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eyum install java\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eyum install java-1.8.0-openjdk-devel\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 2.下载benchmark安装包\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ehttps://sourceforge.net/projects/benchmarksql/files/latest/download\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 3.下载ant安装包\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ehttps://dlcdn.apache.org//ant/binaries/apache-ant-1.10.15-bin.tar.gz\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 4.解压benchmark与ant安装包\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# 建议git初始化benchmark安装包，如果改错了可以回退\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e二、配置环境变量\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 1.生成环境变量脚本\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etouch envbm\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 在envbm中添加一下内容\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eBMROOT\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eBMCODE\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$BMROOT\u003c/span\u003e/benchmarksql-5.0\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003ePATH\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$PATH\u003c/span\u003e:\u003cspan class=\"nv\"\u003e$BMROOT\u003c/span\u003e/apache-ant-1.10.15/bin\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eDBIP\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e127.0.0.1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eDBPORT\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"m\"\u003e5432\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 2.配置环境变量\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003esource\u003c/span\u003e envbm\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e三、配置benchmarksql配置文件\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 1.生成配置文件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir cfg\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp \u003cspan class=\"nv\"\u003e$BMCODE\u003c/span\u003e/run/props.pg \u003cspan class=\"nv\"\u003e$BMROOT\u003c/span\u003e/cfg/props.pg\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 2.编辑配置文件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esed -i \u003cspan class=\"s1\"\u003e\u0026#39;/^user=/s/=.*/=u1/\u0026#39;\u003c/span\u003e f1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# user=bmuser\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# password=bmuser@123\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# warehouses=10\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# loadWorkers=10\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# terminals=10\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# runMins=5\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"c1\"\u003e# limitTxnsPerMin=0\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 3. 设置表的fillfictor=80\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp \u003cspan class=\"nv\"\u003e$BMCODE\u003c/span\u003e/run/sql.common/tableCreates.sql \u003cspan class=\"nv\"\u003e$BMCODE\u003c/span\u003e/run/sql.common/_tableCreates.sql\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esed -i \u003cspan class=\"s1\"\u003e\u0026#39;/^);/s/);.*/) with (fillfactor=80);/\u0026#39;\u003c/span\u003e \u003cspan class=\"nv\"\u003e$BMCODE\u003c/span\u003e/run/sql.common/tableCreates.sql\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e四、生成便捷使用benchmarksql的脚本\u003c/p\u003e","title":"工具 使用benchmarksql测试tpcc"},{"content":"1 审计的背景 1.1 审计的原理 在使用数据库存取数据的大部分场景中，数据库具有以下特点：\n对象多：一个数据库集群中有多个database对象，1个database对象中有多个schema对象，1个schema对象中有多个table、index等对象 用户多：一个数据库中，有多个用户，每个用户可访问的数据库对象不同 应用多：多个应用将数据存储在同一数据库集群中，并同时访问数据库集群 操作多：数据库提供丰富的功能，包括DDL、DML、DCL、运维等 运行久：一个数据库集群，可能会保持数十年运行 审计的主要目的，使记录数据运行过程中发生了哪些事件。审计的3要素是：\n主体：一般指数据库用户 客体：一般指数据库对象，包括：集群、数据对象（database、schema、table、index、function等）、用户等 操作：主体对客体的操作，比如某个用户访问了某个表 1.2 审计的目的 审计具有以下重要意义：\n合法合规：《网络安全法》等法律法规与表中中，要求应用通过《等保测评》等标准，标准中要求应用具备审计功能 故障检测：当数据库出现故障时，协助快速定位问题 攻击检测：通过检查审计日志，可判断是否发生网络安全攻击事件 例行维护：通过检查审计日志，可跟踪对某个对象的访问信息 … 等保测评要求标准（GB/T 28448）中，对审计的要求如下：\n审计范围 全面性 细粒度：登录、访问、修改、删除等 审计内容 用户行为：登录、登出、权限变更 数据访问：敏感数据查询、插入、更新、删除等 异常行为：登录失败、非法访问 审计记录 详细性：时间戳、用户标识、操作类型、操作结果、IP地址等 不可篡改：真实性、完整性 存储安全：未经授权的访问和修改 审计管理 审计策略：审计的目标、范围、内容和频率 审计分析：定期分析审计记录 审计报告 1.3 审计的功能 审计功能包含以下3个部分：\n配置审计功能：日志存储策略等 设置审计范围：设置哪类操作、哪类对象、..需要给设计 生成审计日志：运行时，生成审计日志 管理审计日志：查询，删除，归档审计日志 1.4 oracle审计 oracle审计的发展：\noracle 8i及更早：支持传统审计 oracle 12c：新增支持统一审计 oracle 23ai：不支持传统审计，仅支持统一审计 oracle统一审计的使用：\n-- 1 设置审计范围：创建审计策略 CREATE AUDIT POLICY ap1 PRIVILEGES CREATE TABLE, ALTER USER -- privilege 子句，记录所有使用CreateTable, AlterUser权限的操作，oracle 12c中，支持256种权限 ACTIONS SELECT,INSERT,UPDATE ON t1 -- aciton 子句，记录所有对表t1执行SELECT,INSERT,UPDATE的操作 ROLES r1; -- role 子句，记录所有使用r1角色的操作 -- 2 启用审计策略 AUDIT POLICY ap1; -- 3 查看审计日志（完整日志） SELECT * FROM UNIFIED_AUDIT_TRAIL; -- 查看关键日志 SELECT * FROM DBA_AUDIT_TRAIL; -- 其他：DBA_COMMON_AUDIT_TRAIL, DBA_AUDIT_SESSION, DBA_AUDIT_OBJECT, DBA_FGA_AUDIT_TRAIL os_username | username | userhost | terminal | timestamp | owner | obj_name | action | action_name | ------------+----------+----------+----------+-----------+-------+----------+--------+-------------+ | new_owner | new_name | obj_privilege | sys_privilege | admin_option | grantee | audit_option | ses_actions | +----------+----------+---------------+---------------+--------------+---------+--------------+-------------+ logoff_time | logoff_lread | logoff_pwrite | logoff_dlock | comment_text | sessionid | entryid | statementid | returncode | +-----------+--------------+---------------+--------------+--------------+-----------+---------+-------------+------------+ | priv_used | client_id | econtext_id | session_cpu | extended_timestamp | proxy_sessionid | global_uid | instance_number | +-----------+-----------+-------------+-------------+--------------------+-----------------+------------+-----------------+ os_process | transactionid | scn | sql_bind | sql_text | obj_edition_name | dbid | rls_info | current_user | +----------+---------------+-----+----------+----------+------------------+------+----------+--------------+ 其中，可设置的权限、操作等范围如下：\n-- 所有的 PRIVILEGES SELECT NAME FROM SYSTEM_PRIVILEGE_MAP; -- 所有的 ACTION object | actions ---------------------+-------------------------------------------------------------------------------------------------- Directory | AUDIT, GRANT, READ Function | AUDIT, EXECUTE, GRANT Java schema objects | AUDIT, EXECUTE, GRANT Library | EXECUTE, GRANT Materialized views | ALTER, AUDIT, COMMENT, DELETE, INDEX, INSERT, LOCK, SELECT, UPDATE Mining Model | AUDIT, COMMENT, GRANT, RENAME, SELECT Object type | ALTER, AUDIT, GRANT Package | AUDIT, EXECUTE, GRANT Procedure, triggers | AUDIT, EXECUTE, GRANT Sequence | ALTER, AUDIT, GRANT, SELECT Table | ALTER, AUDIT, COMMENT, DELETE, FLASHBACK, GRANT, INDEX, INSERT, LOCK, MERGE, RENAME, SELECT, UPDATE Table or view column | ALL, ALTER, AUDIT, COMMENT, DELETE, GRANT, INDEX, INSERT, SELECT, UPDATE View | AUDIT, COMMENT, DELETE, FLASHBACK, GRANT, INSERT, LOCK, MERGE, RENAME, SELECT, UPDATE -- 完整的 CREATE AUDIT POLICY 语法 CREATE AUDIT POLICY policy_name { {privilege_audit_clause [action_audit_clause ] [role_audit_clause ]} | { action_audit_clause [role_audit_clause ] } | { role_audit_clause } } [WHEN audit_condition EVALUATE PER {STATEMENT|SESSION|INSTANCE}] [ONLY TOPLEVEL] [CONTAINER = {CURRENT | ALL}]; 参考：\noracle 23官方文档审计功能: https://docs.oracle.com/en/database/oracle/oracle-database/23/dbseg/introduction-to-auditing.html#GUID-94381464-53A3-421B-8F13-BD171C867405 oracle 23中审计日志：https://docs.oracle.com/en/database/oracle/oracle-database/23/refrn/UNIFIED_AUDIT_TRAIL.html 1.5 openGauss审计 在opengauss中，审计也分为2个独立的子特性：\n传统审计：在GUC参数中，配置是否对某类客体、某类操作进行审计（例如：是否审计所有TABLE，是否审计所有DML操作） 统一审计：通过SQL语法，定义是否对某个客体、某个主体进行审计（例如：是否审计表t1，是否审计角色rolo1） opengauss传统审计：\n# 1 设置审计范围 gs_guc SET .. -c \u0026#34;audit_login_logout=7\u0026#34; gs_guc SET .. -c \u0026#34;audit_system_object=67121159\u0026#34; # 审计database, schema, table, ..等对象的create, alter, drop操作 gs_guc SET .. -c \u0026#34;audit_dml_state=1\u0026#34; # 审计insert, update, delete操作 # 设置审计范围的guc参数有20+ -- 2 查询审计日志(存储于：guc audit_directory) SELECT pg_query_audit(\u0026#39;2024-07-12 08:00:00\u0026#39;,\u0026#39;2024-07-12 17:00:00\u0026#39;); opengauss统一审计：\n-- 0 前提：创建资源标签 CREATE TABLE t1 (c1 INT, c2 TEXT); CREATE RESOURCE LABEL rl1 ADD TABLE(t1); -- 支持 SCHEMA, TABLE, COLUMN, VIEW, FUNCITON -- 1 设置审计范围 CREATE AUDIT POLICY ap1 ACCESS ALL ON LABEL(rl1); -- 支持 ACCESS ALL, ACCESS {SELECT、COPY、DEALLOCATE、DELETE、EXECUTE、INSERT、PREPARE、REINDEX、TRUNCATE、UPDATE} CREATE AUDIT POLICY ap2 PRIVILEGES ALL ON LABEL(rl1) FILTER ON ROLES (r1); -- 支持 PRIVILEGES ALL, PRIVILEGES {CREATE、ALTER、DROP、ANALYZE、COMMENT、GRANT、REVOKE、SET、SHOW} -- 2 查询审计日志 (存储于：/var/log/localmessage) -- {timestamp} {host} {event type}, user_name: {user_name}, app_name: {app_name}, client_ip: {client_ip}, access type: {access_type}, policy id: {policy_id}, table: {table}, result: {result} 参考\nopengauss audit policy语法：https://docs.opengauss.org/zh/docs/latest/docs/SQLReference/CREATE-AUDIT-POLICY.html opengauss audit：https://docs.opengauss.org/zh/docs/latest/docs/DatabaseAdministrationGuide/%E8%AE%BE%E7%BD%AE%E6%95%B0%E6%8D%AE%E5%BA%93%E5%AE%A1%E8%AE%A1.html ","permalink":"https://my-blog.j8465383071.workers.dev/posts/security/vastbase-audit-refactor/","summary":"\u003ch1 id=\"1-审计的背景\"\u003e1 审计的背景\u003c/h1\u003e\n\u003ch2 id=\"11-审计的原理\"\u003e1.1 审计的原理\u003c/h2\u003e\n\u003cp\u003e在使用数据库存取数据的大部分场景中，数据库具有以下特点：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e对象多：一个数据库集群中有多个database对象，1个database对象中有多个schema对象，1个schema对象中有多个table、index等对象\u003c/li\u003e\n\u003cli\u003e用户多：一个数据库中，有多个用户，每个用户可访问的数据库对象不同\u003c/li\u003e\n\u003cli\u003e应用多：多个应用将数据存储在同一数据库集群中，并同时访问数据库集群\u003c/li\u003e\n\u003cli\u003e操作多：数据库提供丰富的功能，包括DDL、DML、DCL、运维等\u003c/li\u003e\n\u003cli\u003e运行久：一个数据库集群，可能会保持数十年运行\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e审计的主要目的，使记录数据运行过程中发生了哪些事件。审计的3要素是：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e主体：一般指数据库用户\u003c/li\u003e\n\u003cli\u003e客体：一般指数据库对象，包括：集群、数据对象（database、schema、table、index、function等）、用户等\u003c/li\u003e\n\u003cli\u003e操作：主体对客体的操作，比如某个用户访问了某个表\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"12-审计的目的\"\u003e1.2 审计的目的\u003c/h2\u003e\n\u003cp\u003e审计具有以下重要意义：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e合法合规：《网络安全法》等法律法规与表中中，要求应用通过《等保测评》等标准，标准中要求应用具备审计功能\u003c/li\u003e\n\u003cli\u003e故障检测：当数据库出现故障时，协助快速定位问题\u003c/li\u003e\n\u003cli\u003e攻击检测：通过检查审计日志，可判断是否发生网络安全攻击事件\u003c/li\u003e\n\u003cli\u003e例行维护：通过检查审计日志，可跟踪对某个对象的访问信息\u003c/li\u003e\n\u003cli\u003e…\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e等保测评要求标准（GB/T 28448）中，对审计的要求如下：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e审计范围\n\u003cul\u003e\n\u003cli\u003e全面性\u003c/li\u003e\n\u003cli\u003e细粒度：登录、访问、修改、删除等\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e审计内容\n\u003cul\u003e\n\u003cli\u003e用户行为：登录、登出、权限变更\u003c/li\u003e\n\u003cli\u003e数据访问：敏感数据查询、插入、更新、删除等\u003c/li\u003e\n\u003cli\u003e异常行为：登录失败、非法访问\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e审计记录\n\u003cul\u003e\n\u003cli\u003e详细性：时间戳、用户标识、操作类型、操作结果、IP地址等\u003c/li\u003e\n\u003cli\u003e不可篡改：真实性、完整性\u003c/li\u003e\n\u003cli\u003e存储安全：未经授权的访问和修改\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e审计管理\n\u003cul\u003e\n\u003cli\u003e审计策略：审计的目标、范围、内容和频率\u003c/li\u003e\n\u003cli\u003e审计分析：定期分析审计记录\u003c/li\u003e\n\u003cli\u003e审计报告\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"13-审计的功能\"\u003e1.3 审计的功能\u003c/h2\u003e\n\u003cp\u003e审计功能包含以下3个部分：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e配置审计功能：日志存储策略等\u003c/li\u003e\n\u003cli\u003e设置审计范围：设置哪类操作、哪类对象、..需要给设计\u003c/li\u003e\n\u003cli\u003e生成审计日志：运行时，生成审计日志\u003c/li\u003e\n\u003cli\u003e管理审计日志：查询，删除，归档审计日志\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"14-oracle审计\"\u003e1.4 oracle审计\u003c/h2\u003e\n\u003cp\u003eoracle审计的发展：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eoracle 8i及更早：支持传统审计\u003c/li\u003e\n\u003cli\u003eoracle 12c：新增支持统一审计\u003c/li\u003e\n\u003cli\u003eoracle 23ai：不支持传统审计，仅支持统一审计\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eoracle统一审计的使用：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 1 设置审计范围：创建审计策略\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eAUDIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePOLICY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eap1\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"k\"\u003ePRIVILEGES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- privilege 子句，记录所有使用CreateTable, AlterUser权限的操作，oracle 12c中，支持256种权限\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eACTIONS\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"k\"\u003eUPDATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- aciton 子句，记录所有对表t1执行SELECT,INSERT,UPDATE的操作\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"n\"\u003eROLES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003er1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- role 子句，记录所有使用r1角色的操作\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2 启用审计策略\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eAUDIT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePOLICY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eap1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 查看审计日志（完整日志）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eUNIFIED_AUDIT_TRAIL\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 查看关键日志\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDBA_AUDIT_TRAIL\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 其他：DBA_COMMON_AUDIT_TRAIL, DBA_AUDIT_SESSION, DBA_AUDIT_OBJECT, DBA_FGA_AUDIT_TRAIL\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eos_username\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eusername\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003euserhost\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eterminal\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etimestamp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eowner\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eobj_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eaction\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eaction_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e------------+----------+----------+----------+-----------+-------+----------+--------+-------------+\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003enew_owner\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003enew_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eobj_privilege\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esys_privilege\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eadmin_option\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003egrantee\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eaudit_option\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eses_actions\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"c1\"\u003e----------+----------+---------------+---------------+--------------+---------+--------------+-------------+\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003elogoff_time\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003elogoff_lread\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003elogoff_pwrite\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003elogoff_dlock\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecomment_text\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esessionid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eentryid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estatementid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ereturncode\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"c1\"\u003e-----------+--------------+---------------+--------------+--------------+-----------+---------+-------------+------------+\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epriv_used\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eclient_id\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eecontext_id\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esession_cpu\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eextended_timestamp\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eproxy_sessionid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eglobal_uid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003einstance_number\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"c1\"\u003e-----------+-----------+-------------+-------------+--------------------+-----------------+------------+-----------------+\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eos_process\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etransactionid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003escn\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_bind\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esql_text\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eobj_edition_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edbid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erls_info\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecurrent_user\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"c1\"\u003e----------+---------------+-----+----------+----------+------------------+------+----------+--------------+\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e其中，可设置的权限、操作等范围如下：\u003c/p\u003e","title":"数据库安全 重构审计"},{"content":"virtCCA\n1 升级的流程 升级分类：\n就地升级：暂停业务 灰度升级：不暂停业务，一次升级所有节点 节点升级：基于灰度升级，可升级部分节点 升级流程：（此处的命令是简化版命令，不能直接执行）\n准备升级：检查安装包\n开始升级：停止、启动集群，修改系统表\nmkdir new_pkg gs_preinstall -X config.xml gs_upgradectl -t auto-upgrade -X config.xml --grey 验证升级\ngsql -V gaussdb -V gsql -d postgres -p 5432 -c \u0026#39;select working_version_num();\u0026#39; # 旧版本 提交升级\ngs_upgradectl -t commit-upgrade -X config.xml --grey 回滚升级\ngs_upgradectl -t auto-rollback -X config.xml 2 升级的原理 安装包 |-- install |-- share |-- postgresql |-- postgresql.conf.sample |-- postgres.bki |-- system_views.sql |-- extension |-- ... main parseCommandLine checkParameter initGlobalInfos initClusterInfo UpgradeImplOLAP run Upgrade.run UpgradeImpl.run # UpgradeImpl.py initGlobalInfos commonCheck if \u0026#39;auto_upgrade\u0026#39; doGreyBinaryUpgrade distributeXml checkUpgrade # 检查环境变量 \u0026#39;Local_Check_Upgrade -t action -R oldapppath -l locallog -N newapppath -X config.xml\u0026#39; doHealthCheck checkClusterStatus checkConnection chooseUpgradeNodes prepareGreyUpgrade createBakPath \u0026#39;mkdir upgradeBackupPath\u0026#39; initNodeStepInCsv \u0026#39;touch upgrade_step.csv_bak\u0026#39; initUpgradeProcessStatus recordNodeStepInplace recordDirFile \u0026#39;touch record_app_directory\u0026#39; writeFile(\u0026#39;oldClusterAppPath\u0026#39;) copyBakVersion \u0026#39;cp oldapppath/bin/upgrade_version upgradeBackupPath/upgrade_version\u0026#39; installNewBin \u0026#39;Local_Install -t install_cluster -U user:group -R newapppath -P tmpdir -c clustername -l locallog -X config.cml -T -u\u0026#39; cpDolphinUpgradeScript \u0026#39;cp oldapppath/share/postgresql/extension/dolphin* newapppath/share/postgresql/extension/\u0026#39; prepareUpgradeSqlFolder # catalog upgrade_sql.tar.gz, including guc \u0026#39;Local_Upgrade_Utility -t prepare_upgrade_sql_folder -U user --upgrade_bak_path upgradeBackupPath -X config.xml -l locallog\u0026#39; updateCatalog \u0026#39;cp upgradeBackupPath/upgrade_sql/ {upgrade-post, upgrade, rollback-post, rollback}\u0026#39; doUpgradeCatalog setUpgradeFromParam \u0026#39;gs_guc set -Z cmagent -N all -I all -c upgrade_from=working_grand_version\u0026#39; reload_cm_proc setUpgradeMode(2) reloadCmAgent killKernalSnapshotThread execRollbackUpgradedCatalog(\u0026#39;rollback\u0026#39;) execRollbackUpgradedCatalog(\u0026#39;upgrade\u0026#39;) pgxcNodeUpdateLocalhost(\u0026#34;upgrade\u0026#34;) rebuild_pg_proc_proname_args_nsp_new_index upgradeAgain greySyncGuc \u0026#39;Local_Upgrade_Utility -t grey_sync_guc -U user --upgrade_bak_path=upgradeBackupPath -l logcallog\u0026#39; greySyncGuc # script/local/UpgradeUtility.py readDeleteGuc greySyncInstanceGuc greyUpgradeSyncOldConfigToNew \u0026#39;Local_Upgrade_Utility -t grey_upgrade_config_sync -U user -V oldversionnumber --old_cluster_app_path=oldapppath --new_cluster_app_path=newapppath -l locallog\u0026#39; greyUpgradeSyncConfig # 适配点, 参考 setUpradeModeGuc( getOneDNInst switchBin \u0026#39;Local_Upgrade_Utility -t switch_bin -U user -l localog -R new?oldapppath\u0026#39; restore_origin_disaster_user_file setNewVersionGuc switchExistsProcess _check_and_start_cluster \u0026#39;gs_om -t start\u0026#39; createCheckpoint switchDn waitClusterNormalDegrade doHealthCheck waitClusterForNormal backupGlobalRelmapFile printPrecommitBannervstart elif \u0026#39;commit\u0026#39;: doGreyCommitUpgrade 参考 opengauss om源码：https://gitee.com/opengauss/openGauss-OM opengauss升级：https://docs.opengauss.org/zh/docs/latest/docs/DatabaseOMGuide/upgrade.html ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/opengauss-upgrade/","summary":"\u003cp\u003evirtCCA\u003c/p\u003e\n\u003ch1 id=\"1-升级的流程\"\u003e1 升级的流程\u003c/h1\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e升级分类：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e就地升级：暂停业务\u003c/li\u003e\n\u003cli\u003e灰度升级：不暂停业务，一次升级所有节点\u003c/li\u003e\n\u003cli\u003e节点升级：基于灰度升级，可升级部分节点\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e升级流程：（此处的命令是简化版命令，不能直接执行）\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e准备升级：检查安装包\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e开始升级：停止、启动集群，修改系统表\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir new_pkg\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_preinstall -X config.xml\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_upgradectl -t auto-upgrade -X config.xml --grey\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e验证升级\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsql -V\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egaussdb -V\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egsql -d postgres -p \u003cspan class=\"m\"\u003e5432\u003c/span\u003e -c \u003cspan class=\"s1\"\u003e\u0026#39;select working_version_num();\u0026#39;\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 旧版本\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e提交升级\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_upgradectl -t commit-upgrade -X config.xml --grey\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e回滚升级\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_upgradectl -t auto-rollback -X config.xml\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-升级的原理\"\u003e2 升级的原理\u003c/h1\u003e\n\u003ch2 id=\"安装包\"\u003e安装包\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- install\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- share\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e        \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- postgresql\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e            \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"c1\"\u003e--  postgresql.conf.sample\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e            \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"c1\"\u003e--  postgres.bki\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e            \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- system_views.sql\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e            \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- extension\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e            \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- ...\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eparseCommandLine\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003echeckParameter\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003einitGlobalInfos\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003einitClusterInfo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003eUpgradeImplOLAP\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003erun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eUpgrade\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003erun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eUpgradeImpl\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003erun\u003c/span\u003e \u003cspan class=\"c1\"\u003e# UpgradeImpl.py\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003einitGlobalInfos\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003ecommonCheck\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;auto_upgrade\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003edoGreyBinaryUpgrade\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003edistributeXml\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003echeckUpgrade\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"c1\"\u003e# 检查环境变量\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"s1\"\u003e\u0026#39;Local_Check_Upgrade -t action -R oldapppath -l locallog -N newapppath -X config.xml\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003edoHealthCheck\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003echeckClusterStatus\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003echeckConnection\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003echooseUpgradeNodes\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eprepareGreyUpgrade\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003ecreateBakPath\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"s1\"\u003e\u0026#39;mkdir upgradeBackupPath\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003einitNodeStepInCsv\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"s1\"\u003e\u0026#39;touch upgrade_step.csv_bak\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003einitUpgradeProcessStatus\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003erecordNodeStepInplace\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003erecordDirFile\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"s1\"\u003e\u0026#39;touch record_app_directory\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003ewriteFile\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;oldClusterAppPath\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003ecopyBakVersion\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"s1\"\u003e\u0026#39;cp oldapppath/bin/upgrade_version upgradeBackupPath/upgrade_version\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003einstallNewBin\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"s1\"\u003e\u0026#39;Local_Install -t install_cluster -U user:group -R newapppath -P tmpdir -c clustername -l locallog -X config.cml -T -u\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003ecpDolphinUpgradeScript\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"s1\"\u003e\u0026#39;cp oldapppath/share/postgresql/extension/dolphin* newapppath/share/postgresql/extension/\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eprepareUpgradeSqlFolder\u003c/span\u003e \u003cspan class=\"c1\"\u003e# catalog upgrade_sql.tar.gz, including guc\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"s1\"\u003e\u0026#39;Local_Upgrade_Utility -t prepare_upgrade_sql_folder -U user --upgrade_bak_path upgradeBackupPath -X config.xml -l locallog\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eupdateCatalog\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"s1\"\u003e\u0026#39;cp upgradeBackupPath/upgrade_sql/ {upgrade-post, upgrade, rollback-post, rollback}\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003edoUpgradeCatalog\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003esetUpgradeFromParam\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"s1\"\u003e\u0026#39;gs_guc set -Z cmagent -N all -I all -c upgrade_from=working_grand_version\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003ereload_cm_proc\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003esetUpgradeMode\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003ereloadCmAgent\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003ekillKernalSnapshotThread\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eexecRollbackUpgradedCatalog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;rollback\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eexecRollbackUpgradedCatalog\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;upgrade\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003epgxcNodeUpdateLocalhost\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;upgrade\u0026#34;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003erebuild_pg_proc_proname_args_nsp_new_index\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eupgradeAgain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003egreySyncGuc\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"s1\"\u003e\u0026#39;Local_Upgrade_Utility -t grey_sync_guc -U user --upgrade_bak_path=upgradeBackupPath -l logcallog\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003egreySyncGuc\u003c/span\u003e \u003cspan class=\"c1\"\u003e# script/local/UpgradeUtility.py\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003ereadDeleteGuc\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"n\"\u003egreySyncInstanceGuc\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003egreyUpgradeSyncOldConfigToNew\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"s1\"\u003e\u0026#39;Local_Upgrade_Utility -t grey_upgrade_config_sync -U user -V oldversionnumber --old_cluster_app_path=oldapppath --new_cluster_app_path=newapppath -l locallog\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003egreyUpgradeSyncConfig\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 适配点, 参考 setUpradeModeGuc(\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003egetOneDNInst\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eswitchBin\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"s1\"\u003e\u0026#39;Local_Upgrade_Utility -t switch_bin -U user -l localog -R new?oldapppath\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003erestore_origin_disaster_user_file\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003esetNewVersionGuc\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eswitchExistsProcess\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003e_check_and_start_cluster\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"s1\"\u003e\u0026#39;gs_om -t start\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003ecreateCheckpoint\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eswitchDn\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003ewaitClusterNormalDegrade\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003edoHealthCheck\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003ewaitClusterForNormal\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003ebackupGlobalRelmapFile\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eprintPrecommitBannervstart\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003eelif\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;commit\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003edoGreyCommitUpgrade\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"参考\"\u003e参考\u003c/h1\u003e\n\u003cul\u003e\n\u003cli\u003eopengauss om源码：\u003ca href=\"https://gitee.com/opengauss/openGauss-OM\"\u003ehttps://gitee.com/opengauss/openGauss-OM\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eopengauss升级：\u003ca href=\"https://docs.opengauss.org/zh/docs/latest/docs/DatabaseOMGuide/upgrade.html\"\u003ehttps://docs.opengauss.org/zh/docs/latest/docs/DatabaseOMGuide/upgrade.html\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e","title":"openGauss 升级"},{"content":"1 身份认证 身份认证\n大部分数据库都支持基于口令的身份认证，以vastbase为例，身份认证的流程如下：\n高权限用户创建新用户\nCREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; 数据库在pg_authid系统表中存储用户以及密码的哈希\nSELECT oid, rolname, rolvalidbegin, rolpassword FROM pg_authid WHERE rolname = \u0026#39;u1\u0026#39;; oid | rolname | rolvalidbegin | rolpassword -------+---------+---------------+-------------------------------------------------------------------------- 24576 | u1 | | sha2565e3b533ca5db32acdffdb6aea03395af163ac3cfdc9ddb....... 数据库在pg_auth_history系统表中存储密码创建时间\nSELECT roloid, passwordtime FROM pg_auth_history; oid | passwordtime -------+------------------------------- 24576 | 2025-02-11 12:17:02.969642+08 新用户登录数据库\ngsql -d postgres -U u1 -W \u0026#39;u1.pass1\u0026#39; -r 数据库校验新用户信息：数据库接收用户建立连接的请求时，会进行一系列身份鉴别操作，包括：检查用户提供的密码与pg_authid中的值是否匹配，检查pg_auth_history中记录的密码生成日期与当前日期是否间隔较久等\n身份认证配置参数\n大部分数据库都支持配置密码有效期等与密码有关的参数。比如，oracle中，控制密码有效期的参数为PASSWORD_LIFE_TIME，vastbase中，控制密码有效期的参数为password_effect_time。\n数据库配置参数\n在vastbase中，数据库的配置参数称为GUC参数，password_effect_time是用于控制密码有效期的GUC参数，包括password_effect_time等大部分GUC参数的作用范围是整个集群，即所有用户的密码有效期都由1个GUC参数控制。\n在oracle中，针对密码有效期等少部分参数，支持按用户级配置参数，即每个用户都可以配置独立的PASSWORD_LIFE_TIME参数，该功能称为profile。本文主要讨论的内容，只包含用户级配置参数。\n2 GUC参数的使用方法 在opengauss中，有6个GUC参数与profile中的参数一致。\nSELECT name, setting, vartype, context FROM pg_settings WHERE name in ( \u0026#39;failed_login_attempts\u0026#39;, \u0026#39;password_effect_time\u0026#39;, \u0026#39;password_reuse_time\u0026#39;, \u0026#39;password_reuse_max\u0026#39;, \u0026#39;password_lock_time\u0026#39;, \u0026#39;session_timeout\u0026#39;); name | setting | vartype | context ----------------------+---------+---------+--------- failed_login_attempts | 3 | integer | sighup password_effect_time | 90 | real | sighup password_lock_time | 0.0001 | real | sighup password_reuse_max | 0 | integer | sighup password_reuse_time | 0.0001 | real | sighup session_timeout | 600 | integer | user 此处，先介绍各参数的功能，以及如何验证参数的功能。\n一、failed_login_attempts 用户使用账号和密码登录数据库时，如果密码连续失败多次，则账号将被锁定一段时间。\nfailed_login_attempts用于设置出发锁定的连续失败次数的阈值。\n设置参数\nexport DATADIR=$GAUSSHOME/data1 gs_guc reload -D $DATADIR -c \u0026#34;failed_login_attempts=3\u0026#34; 创建用户\nCREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; 连续失败登录\ngsql -d postgresql -U u1 -W \u0026#39;1.wrong_pass\u0026#39; gsql -d postgresql -U u1 -W \u0026#39;2.wrong_pass\u0026#39; gsql -d postgresql -U u1 -W \u0026#39;3.wrong_pass\u0026#39; 查看失败次数\n从系统表中，查看用户的失败登录次数\ngsql -d postgres -c \u0026#34; SELECT * FROM pg_user_status WHERE roloid = (SELECT oid FROM pg_authid WHERE rolname = \u0026#39;u1\u0026#39;);\u0026#34; roloid | failcount | locktime | rolstatus | permspace | tempspace | passwordexpired -------+-----------+-------------------------------+-----------+-----------+-----------+----------------- 16411 | 3 | 2025-02-21 12:05:10.199257+08 | 0 | 0 | 0 | 0 由于密码错误次数达到限制，接下来，账号将被锁定\ngsql -d postgres -U u1 -W \u0026#39;u1.pass1\u0026#39; -r -- 预期输出 FATAL: The account has been locked. -- 解锁方法 gsql -d postgres -c \u0026#34;ALTER USER u1 ACCOUNT UNLOCK;\u0026#34; 清理环境\nDROP USER u1; 二、password_lock_time 用户使用账号和密码登录数据库时，如果密码连续失败多次，则账号将被锁定一段时间\npassword_lock_time用于设置账号锁定时间\n该参数与failed_login_attempts结合使用，只能用来解锁自动锁定场景，即触发密码错误次数导致的锁定，不能解锁主动锁定场景ALTER USER .. ACCOUNT LOCK\n账号被锁定后，自动解锁的时间\n# 1天 = 24 * 60 * 60 = 86400秒，0.0001天是 8.64秒 export DATADIR=$GAUSSHOME/data1 gs_guc reload -D $DATADIR -c \u0026#34;password_lock_time=0.0001d\u0026#34; gs_guc reload -D $DATADIR -c \u0026#34;failed_login_attempts=3\u0026#34; 创建用户\nCREATE USER u1 PASSWORD \u0026#39;u1@pass1\u0026#39;; 锁定用户\ngsql -d postgres -c \u0026#34; SELECT * FROM pg_user_status WHERE roloid = (SELECT oid FROM pg_authid WHERE rolname = \u0026#39;u1\u0026#39;);\u0026#34; gsql -d postgres -r -U u1 -W \u0026#39;u1@error\u0026#39; -c \u0026#34;SELECT 1\u0026#34; gsql -d postgres -r -U u1 -W \u0026#39;u1@error\u0026#39; -c \u0026#34;SELECT 1\u0026#34; gsql -d postgres -r -U u1 -W \u0026#39;u1@error\u0026#39; -c \u0026#34;SELECT 1\u0026#34; # 连续失败3次，账号被短暂锁定，无法登录 gsql -d postgres -r -U u1 -W \u0026#39;u1@pass1\u0026#39; -c \u0026#34;SELECT 1\u0026#34; # 预期输出 FATAL: The account has been locked. gsql -d postgres -c \u0026#34; SELECT * FROM pg_user_status WHERE roloid = (SELECT oid FROM pg_authid WHERE rolname = \u0026#39;u1\u0026#39;);\u0026#34; # 预期输出 roloid | failcount | locktime | rolstatus | permspace | tempspace | passwordexpired --------+-----------+-------------------------------+-----------+-----------+-----------+----------------- 16477 | 3 | 2025-02-21 16:57:21.263935+08 | 1 | 0 | 0 | 0 # 等几秒钟，超过8.64秒 # 系统表中的锁定状态被自动清理 gsql -d postgres -c \u0026#34; SELECT * FROM pg_user_status WHERE roloid = (SELECT oid FROM pg_authid WHERE rolname = \u0026#39;u1\u0026#39;);\u0026#34; # 预期输出 roloid | failcount | locktime | rolstatus | permspace | tempspace | passwordexpired --------+-----------+-------------------------------+-----------+-----------+-----------+----------------- 16477 | 0 | 2025-02-21 16:57:21.263935+08 | 0 | 0 | 0 | 0 # 现在可以连接成功了 gsql -d postgres -r -U u1 -W \u0026#39;u1@pass1\u0026#39; -c \u0026#34;SELECT 1\u0026#34; # 预期输出 连接成功 三、password_effect_time 为用户设置密码时，密码都有有效期。\npassword_effect_time用于设置有效期的时间。但是，在vastbaes和opengauss中，密码达到有效期之后，即密码过期后，密码仍然可以正常使用，没有任何功能上的影响。\n创建用户\nCREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; 查看密码创建日期\nSELECT roloid, passwordtime FROM pg_auth_history; oid | passwordtime ----------+------------------------------- 24576 | 2025-02-11 12:17:02.969642+08 查看密码有效期\n用户主动调用函数，查看当前用户的密码过期剩余天数\nSELECT gs_password_deadline(); 密码过期的表现\n每次使用gsql连接数据库时，gsql会自动执行gs_password_deadline()函数，获取密码有效期。如果密钥过期，则打印一条提醒\n除此之外，没有其他地方使用password_effect_time参数，即使密码过期，相关账号依然可以正常使用，而且也只是gsql会打印提醒，libpq/JDBC/ODBC等都不会打印\n主动让密码过期\n在vastase中，主动让密码过期，与password_effect_time这个GUC参数无任何关系\n用户可主动执行ALTER USER .. EXPIRED设置密码过期，此时，系统表pg_user_status中，用户对应的passwordexpired列的值将由0变为1，即代表用户密码过期\nALTER USER u1 PASSWORD EXPIRED; -- 主动让密码过期后，用户无法连接数据库，也无法执行gs_password_deadline函数 gsql -d postgres -U u1 -W \u0026#39;u1.pass1\u0026#39; -c \u0026#34;SELECT gs_password_deadline()\u0026#34; -- 输出 ERROR: Please use \u0026#34;ALTER ROLE user_name IDENTIFIED BY \u0026#39;password\u0026#39; REPLACE \u0026#39;old password\u0026#39;;\u0026#34; to modify the expired password of user u1 before operation! 清理环境\nDROP USER u1; 四、 password_reuse_max 创建用户\nCREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; 设置GUC参数，不能重复使用最近3次使用的密码\nexport DATADIR=$GAUSSHOME/data1 gs_guc reload -D $DATADIR -c \u0026#34;password_reuse_max=3\u0026#34; 修改密码\nALTER USER u1 PASSWORD \u0026#39;u1.pass2\u0026#39;; ALTER USER u1 PASSWORD \u0026#39;u1.pass3\u0026#39;; -- 重复倒数第3次使用的密码 ALTER USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; -- 预期输出 ERROR: The password cannot be reused. -- 再修改1次密码 ALTER USER u1 PASSWORD \u0026#39;u1.pass4\u0026#39;; -- 重读倒是读4次使用的密码 ALTER USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; -- 预期输出 修改密码成功 五、password_reuse_time 确保其他GUC参数不影响测试\nexport DATADIR=$GAUSSHOME/data1 gs_guc reload -D $DATADIR -c \u0026#34;password_reuse_max=0\u0026#34; 设置集群级GUC参数\n# 1天 = 24 * 60 * 60 = 86400秒，0.0001天是 8.64秒 gs_guc reload -D $DATADIR -c \u0026#34;password_reuse_time=0.0001\u0026#34; 创建用户\nCREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; ALTER USER u1 PASSWORD \u0026#39;u1.pass2\u0026#39;; 查看用户曾使用过的密码\nSELECT * FROM pg_auth_history WHERE roloid = (SELECT oid FROM pg_authid WHERE rolname = \u0026#39;u1\u0026#39;); roloid | passwordtime | rolpassword --------+-------------------------------+------------------------------------ 16419 | 2025-02-21 15:20:50.308879+08 | sha256c84795e1631bbb8bf1ecf923... 16419 | 2025-02-21 15:22:06.754397+08 | sha2562939db0b3ffc71ee3115e010... 使用旧密码\n-- 使用不太古老的密码（确保不要超过8.64秒） ALTER USER u1 PASSWORD \u0026#39;u1.pass3\u0026#39;; ALTER USER u1 PASSWORD \u0026#39;u1.pass4\u0026#39;; ALTER USER u1 PASSWORD \u0026#39;u1.pass3\u0026#39;; -- 8.64秒内快速改回pass3 -- 预期输出 ERROR: The password cannot be reused. -- 使用更古老一点的密码（确保已超过8.64秒） ALTER USER u1 PASSWORD \u0026#39;u1.pass3\u0026#39;; -- 预期输出 修改成功 清理环境\nDROP USER u1; 六、session_timeout 设置回话过期时间\nexport DATADIR=$GAUSSHOME/data1 gs_guc reload -D $DATADIR -c \u0026#34;session_timeout=8s\u0026#34; 创建用户\nCREATE USER u1 PASSWORD \u0026#39;u1.pass1\u0026#39;; 连接数据库\ngsql -d postgres -U u1 -W \u0026#39;u1.pass1\u0026#39; -r SELECT 1; -- 睡10秒，保证睡眠充足 SELECT 1; -- 预期输出 WARNING: Session unused timeout. opengauss与vastbase中，当用户的密码过期时，只有2个表现：\ngsql：每次使用gsql连接数据库时，gsql会自动执行gs_password_deadline()函数，获取密码有效期。如果密钥过期，则打印一条提醒。 内置函数：主动调用SELECT gs_password_deadline()函数会显示密码过期\n除此之外，没有其他地方使用password_effect_time参数，即使密码过期，相关账号依然可以正常使用，只是gsql会打印一条提醒。 对照组：验证集群级guc参数password_effect_time\n请参考上述2个guc参数验证方式，为节约篇幅，此处不再继续给示例\n查看密码创建日期的语法如下：\nSELECT roloid, passwordtime FROM pg_auth_history; oid | passwordtime -------+------------------------------- opengauss和vastbase中，密码的另一种强制过期，是通过是否主动执行ALTER USER .. EXPIRED设置的，此时，系统表pg_user_status中，用户对应的passwordexpired列的值将由0变为1，即代表用户密码过期。密码创建时间、密码有效期天数设置等，并不会导致密码真的过期。\nALTER USER u1 PASSWORD EXPIRED; -- 主动让密码过期后，用户无法连接数据库，也无法执行gs_password_deadline函数 gsql -d postgres -U u1 -W \u0026#39;u1.pass1\u0026#39; -c \u0026#34;SELECT gs_password_deadline()\u0026#34; -- 输出 ERROR: Please use \u0026#34;ALTER ROLE user_name IDENTIFIED BY \u0026#39;password\u0026#39; REPLACE \u0026#39;old password\u0026#39;;\u0026#34; to modify the expired password of user u1 before operation! 3 pg md5 ClientAuthentication hba_getauthmethod case uaMD5: CheckPWChallengeAuth case uaPassword: CheckPasswordAuth sendAuthRequest recv_password_packet get_role_password plain_crypt_verify pg_md5_encrypt ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/opengauss-auth-guc/","summary":"\u003ch1 id=\"1-身份认证\"\u003e1 身份认证\u003c/h1\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e身份认证\u003cbr\u003e\n大部分数据库都支持基于口令的身份认证，以vastbase为例，身份认证的流程如下：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e高权限用户创建新用户\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePASSWORD\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e数据库在\u003ccode\u003epg_authid\u003c/code\u003e系统表中存储用户以及密码的哈希\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eoid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erolname\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erolvalidbegin\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erolpassword\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_authid\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erolname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"n\"\u003eoid\u003c/span\u003e\u003cspan class=\"w\"\u003e   \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erolname\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erolvalidbegin\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"n\"\u003erolpassword\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-------+---------+---------------+--------------------------------------------------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"mi\"\u003e24576\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e               \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003esha2565e3b533ca5db32acdffdb6aea03395af163ac3cfdc9ddb\u003c/span\u003e\u003cspan class=\"p\"\u003e.......\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e数据库在\u003ccode\u003epg_auth_history\u003c/code\u003e系统表中存储密码创建时间\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eroloid\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epasswordtime\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epg_auth_history\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e      \u003c/span\u003e\u003cspan class=\"n\"\u003eoid\u003c/span\u003e\u003cspan class=\"w\"\u003e  \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e         \u003c/span\u003e\u003cspan class=\"n\"\u003epasswordtime\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"c1\"\u003e-------+-------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"w\"\u003e     \u003c/span\u003e\u003cspan class=\"mi\"\u003e24576\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e|\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2025\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e02\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"mi\"\u003e11\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e12\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"mi\"\u003e17\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\u003cspan class=\"mi\"\u003e02\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"mi\"\u003e969642\u003c/span\u003e\u003cspan class=\"o\"\u003e+\u003c/span\u003e\u003cspan class=\"mi\"\u003e08\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e新用户登录数据库\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003egsql\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ed\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epostgres\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eU\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eu1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003eW\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;u1.pass1\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003er\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e数据库校验新用户信息：数据库接收用户建立连接的请求时，会进行一系列身份鉴别操作，包括：检查用户提供的密码与pg_authid中的值是否匹配，检查pg_auth_history中记录的密码生成日期与当前日期是否间隔较久等\u003c/p\u003e","title":"openGauss 身份认证 GUC参数"},{"content":"1 安装mysql # root yum -y install wget cmake gcc gcc-c++ ncurses ncurses-devel libaio-devel openssl openssl-devel yum -y install cmake3 # 普通用户 cd ~ mkdir mysql \u0026amp;\u0026amp; cd mysql wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-boost-8.0.17.tar.gz tar -zxvf mysql-boost-8.0.17.tar.gz mkdir backup \u0026amp;\u0026amp; mv *.tar.gz backup mkdir install data boost cd mysql-boost* cmake3 . -DCMAKE_INSTALL_PREFIX=`pwd`/../install -DMYSQL_DATADIR=`pwd`/../data -DSYSCONFDIR=`pwd`/../data -DMYSQL_TCP_PORT=3306 -DWITH_BOOST=`pwd`/../boost \\ -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DENABLED_LOCAL_INFILE=ON -DWITH_INNODB_MEMCACHED=ON -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_FEDERATED_STORAGE_ENGINE=1 -DWITH_BLACKHOLE_STORAGE_ENGINE=1 -DWITH_ARCHIVE_STORAGE_ENGINE=1 -DWITHOUT_EXAMPLE_STORAGE_ENGINE=1 -DWITH_PERFSCHEMA_STORAGE_ENGINE=1 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/mysql-install/","summary":"\u003ch1 id=\"1-安装mysql\"\u003e1 安装mysql\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# root\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eyum -y install wget cmake gcc gcc-c++ ncurses ncurses-devel libaio-devel openssl openssl-devel\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eyum -y install cmake3\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 普通用户\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e ~\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir mysql \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"nb\"\u003ecd\u003c/span\u003e mysql\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ewget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-boost-8.0.17.tar.gz\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etar -zxvf mysql-boost-8.0.17.tar.gz\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir backup \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e mv *.tar.gz backup\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir install data boost\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e mysql-boost*\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecmake3 . -DCMAKE_INSTALL_PREFIX\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e/../install -DMYSQL_DATADIR\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e/../data -DSYSCONFDIR\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e/../data -DMYSQL_TCP_PORT\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"m\"\u003e3306\u003c/span\u003e -DWITH_BOOST\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e/../boost \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"se\"\u003e\u003c/span\u003e-DDEFAULT_CHARSET\u003cspan class=\"o\"\u003e=\u003c/span\u003eutf8 -DDEFAULT_COLLATION\u003cspan class=\"o\"\u003e=\u003c/span\u003eutf8_general_ci -DENABLED_LOCAL_INFILE\u003cspan class=\"o\"\u003e=\u003c/span\u003eON -DWITH_INNODB_MEMCACHED\u003cspan class=\"o\"\u003e=\u003c/span\u003eON -DWITH_INNOBASE_STORAGE_ENGINE\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e -DWITH_FEDERATED_STORAGE_ENGINE\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e -DWITH_BLACKHOLE_STORAGE_ENGINE\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e -DWITH_ARCHIVE_STORAGE_ENGINE\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e -DWITHOUT_EXAMPLE_STORAGE_ENGINE\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e  -DWITH_PERFSCHEMA_STORAGE_ENGINE\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"m\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"mysql 1 安装mysql"},{"content":"1 安装wsl 请自行在网上了解wsl是什么，以及如何在wsl中安装centos 7：\n在windows 11中，启用wsl 下载centos 7的wsl 安装包 在wsl中，安装centos 7 进入centos 7，创建普通用户，建议使用mobaxterm直接登录wsl中的centos系统 配置centos 7的yum源 2 准备环境 下载opengauss源码\ngit clone -b master git@gitee.com:opengauss/openGauss-server.git 下载第三方库\nwget https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/binarylibs/gcc10.3/openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz 解压第三方库\n# 解压压缩包 tar -zxvf openGauss-third* # 归档压缩包 mkdir tmp mv *.tar.gz tmp # 重命名压缩包 mv openGauss-third* third 下载依赖库\nyum install -y libaio-devel flex bison ncurses-devel patch readline-devel # 单独安装 glibc-devel yum install glibc-devel # 如果报错，提示安装了.i686版本的glibc-devel，则修改yum配置文件： # echo \u0026#34;exclude=*.i686\u0026#34; \u0026gt;\u0026gt; /etc/yum.conf # 如果报错，提示glibc-devel与glibc-common不匹配，则降级glibc和glibc-common # yum downgrade glibc glibc-devel glibc-common glibc-headers # 降级后，再重新安装 glibc-devel 即可 # yum install glibc-devel 设置环境变量\n首先，请确保目录结构如下：\n|-- 父目录 |-- openGauss-server |-- third 在父目录下，生产环境变量脚本：\necho \u0026#34; export CODE_BASE=`pwd`/openGauss-sever export BINARYLIBS=`pwd`/third export GAUSSHOME=`pwd`/install export GCC_PATH=$BINARYLIBS/buildtools/gcc10.3 export CC=$GCC_PATH/gcc/bin/gcc export CXX=$GCC_PATH/gcc/bin/g++ export LD_LIBRARY_PATH=$GAUSSHOME/lib:$GCC_PATH/gcc/lib64:$GCC_PATH/isl/lib:$GCC_PATH/mpc/lib/:$GCC_PATH/mpfr/lib/:$GCC_PATH/gmp/lib/:$LD_LIBRARY_PATH export PATH=$GAUSSHOME/bin:$GCC_PATH/gcc/bin:$PATH \u0026#34; \u0026gt; oenv 3 编译openGauss 设置环境变量\nsource oenv 配置编译选项\ncd openGauss-server ./configure --gcc-version=10.3.0 CC=g++ CFLAGS=\u0026#39;-O0\u0026#39; --prefix=$GAUSSHOME --3rd=$BINARYLIBS --enable-debug --enable-cassert --enable-thread-safety --with-readline --without-zlib 编译数据库\n# 以下命令中，参数j表示，并发编译数据库，10表示并发数，如果不设置数字10，则默认并发数为CPU核数，即所有CPU核都参与编译，这样可能会导致系统卡住，因此最好将并发数设置为小于CPU核数的数字。我的CPU是20核，因此，将并发数设置为10 make -sj 10 收集编译结果\n# 将上一步生产的编译结果，统一收集到环境变量$GAUSSHOME目录下 # 社区的编译脚本有点问题，建议make install命令中，不要加参数j make install -s 4 安装openGauss 初始化数据库\ngs_initdb -D $GAUSSHOME/data1 -w \u0026#34;gauss@123\u0026#34; --nodename=\u0026#39;node1\u0026#39; 启动数据库\ngs_ctl start -D $GAUSSHOME/data1 -Z single_node 连接数据库\ngsql -d postgres 停止数据库\ngs_ctl stop -D $GAUSSHOME/data1 alias gcode=\u0026#39;cd /home/shenkun/openGauss-server\u0026#39; alias genv=\u0026#39;gcode \u0026amp;\u0026amp; cd .. \u0026amp;\u0026amp; source ./oenv\u0026#39; alias ginstall=\u0026#39;cd $GAUSSHOME\u0026#39; alias gcfg=\u0026#39;gcode \u0026amp;\u0026amp; git clean -xdf \u0026amp;\u0026amp; ./configure --gcc-version=10.3.0 CC=g++ CFLAGS=\u0026#39;-O0\u0026#39; --prefix=$GAUSSHOME --3rd=$BINARYLIBS --enable-debug --enable-cassert --enable-thread-safety --with-readline --without-zlib\u0026#39; alias gmake=\u0026#39;gcode \u0026amp;\u0026amp; make -sj 10 \u0026amp;\u0026amp; make install -s\u0026#39; alias ginit=\u0026#39;rm -rf $GAUSSHOME/data \u0026amp;\u0026amp; gs_initdb -D $GAUSSHOME/data -w \u0026#34;gauss@123\u0026#34; --nodename=\u0026#39;node1\u0026#39;\u0026#39; alias gstart=\u0026#39;gs_ctl start -D $GAUSSHOME/data\u0026#39; alias gstop=\u0026#39;gs_ctl start -D $GAUSSHOME/data\u0026#39; alias grestart=\u0026#39;gs_ctl restart -D $GAUSSHOME/data\u0026#39; alias ggdb=\u0026#39;gdb attach `pidof gaussdb`\u0026#39; alias gcore=\u0026#39;ll /core\u0026#39; ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/opengauss-1-install/","summary":"\u003ch1 id=\"1-安装wsl\"\u003e1 安装wsl\u003c/h1\u003e\n\u003cp\u003e请自行在网上了解wsl是什么，以及如何在wsl中安装centos 7：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e在windows 11中，启用wsl\u003c/li\u003e\n\u003cli\u003e下载centos 7的wsl 安装包\u003c/li\u003e\n\u003cli\u003e在wsl中，安装centos 7\u003c/li\u003e\n\u003cli\u003e进入centos 7，创建普通用户，建议使用mobaxterm直接登录wsl中的centos系统\u003c/li\u003e\n\u003cli\u003e配置centos 7的yum源\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"2-准备环境\"\u003e2 准备环境\u003c/h1\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e下载opengauss源码\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit clone -b master git@gitee.com:opengauss/openGauss-server.git\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e下载第三方库\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ewget https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/binarylibs/gcc10.3/openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e解压第三方库\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 解压压缩包\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etar -zxvf openGauss-third*\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 归档压缩包\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir tmp\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emv *.tar.gz tmp\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 重命名压缩包\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emv openGauss-third* third\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e下载依赖库\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eyum install -y libaio-devel flex bison ncurses-devel patch readline-devel\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 单独安装 glibc-devel\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eyum install glibc-devel\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 如果报错，提示安装了.i686版本的glibc-devel，则修改yum配置文件：\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#   echo \u0026#34;exclude=*.i686\u0026#34; \u0026gt;\u0026gt; /etc/yum.conf\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 如果报错，提示glibc-devel与glibc-common不匹配，则降级glibc和glibc-common\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#   yum downgrade glibc glibc-devel glibc-common glibc-headers\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 降级后，再重新安装 glibc-devel 即可\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#   yum install glibc-devel\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e设置环境变量\u003cbr\u003e\n首先，请确保目录结构如下：\u003c/p\u003e","title":"openGauss 1 安装openGauss"},{"content":"1 Oracle 集群管理 1.2 登录数据库 sqlplus / as sysdba 2 Oracle 语法 2.1 数据类型 仅列举常见数据类型：\n大类 类型 解释 数值 INT or INTGER 整数 - NUMBESR(p, s) p: 精度，整数和小数总位数，s: 小数位数 - SMALLINT 等于 NUMBESR(38) - FLOAT(p) 浮点数，p: 二进制精度，最大126 字符 CHAR(n) 固定长度字符，n: 长度，不足n用空格填充 - VARCHAR2(n) 可变长度字符，n: 最大长度，最大4000 时间 DATE 日期 - TIMESTAMP 日期和时间 二进制 CLOB 长文本数据 2.2 常用SQL 常见语法\n-- 1 创建表 CREATE TABLE t1 (c1 INT, c2 VARCHAR2(10)); -- 2 插入数据 INSERT INTO t1 VALUES (1, \u0026#39;abcc\u0026#39;); INSERT INTO t1 VALUES (2, \u0026#39;ddee\u0026#39;); -- 3 查询数据 SELECT * FROM t1 WHERE c1 \u0026gt; 0; -- 4 更新数据 UPDATE t1 SET c2 = \u0026#39;abbc\u0026#39; WHERE c1 = 1; -- 5 删除数据 DELETE FROM t1 WHERE c1 = 2; -- 6 删除表 DROP TABLE t1; 内置函数\nCREATE TABLE t1 (c1 INT, c2 VARCHAR2(10)); INSERT INTO t1 VALUES (1, upper(\u0026#39;abcc\u0026#39;)); SELECT c1,c2,lower(c2) FROM t1; 2.3 常用系统表 -- 查看所有表 SELECT * FROM user_tables; -- 查看lorand用户有权访问的表 SELECT owner,table_name FROM all_tables WHERE owner = \u0026#39;lorand\u0026#39;; -- 查看t1表的列信息 SELECT column_name,data_type FROM user_tab_columns WHERE table_name = \u0026#39;t1\u0026#39;; -- 查看所有索引 SELECT * FROM user_indexes; -- 查看所有用户 SELECT * FROM dba_users; -- 查看数据库信息 SELECT * FROM v$database; -- 查看实例信息 SELECT * FROM v$instance; 常用设置 SET LINESIZE 200 SET PAGESIZE 100 SET COLSEP \u0026#39; | \u0026#39; SET NUMWIDTH 15 SET HEADING ON SET FEEDBACK OFF 查看表的所有列\nSELECT column_name,data_type,data_length,nullable FROM all_tab_columns WHERE table_name = UPPER(\u0026#39;dba_profiles\u0026#39;); ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/oracle-2-sql/","summary":"\u003ch1 id=\"1-oracle-集群管理\"\u003e1 Oracle 集群管理\u003c/h1\u003e\n\u003ch2 id=\"12-登录数据库\"\u003e1.2 登录数据库\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esqlplus / as sysdba\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"2-oracle-语法\"\u003e2 Oracle 语法\u003c/h1\u003e\n\u003ch2 id=\"21-数据类型\"\u003e2.1 数据类型\u003c/h2\u003e\n\u003cp\u003e仅列举常见数据类型：\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e大类\u003c/th\u003e\n          \u003cth\u003e类型\u003c/th\u003e\n          \u003cth\u003e解释\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e数值\u003c/td\u003e\n          \u003ctd\u003eINT or INTGER\u003c/td\u003e\n          \u003ctd\u003e整数\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eNUMBESR(p, s)\u003c/td\u003e\n          \u003ctd\u003ep: 精度，整数和小数总位数，s: 小数位数\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eSMALLINT\u003c/td\u003e\n          \u003ctd\u003e等于 NUMBESR(38)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eFLOAT(p)\u003c/td\u003e\n          \u003ctd\u003e浮点数，p: 二进制精度，最大126\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e字符\u003c/td\u003e\n          \u003ctd\u003eCHAR(n)\u003c/td\u003e\n          \u003ctd\u003e固定长度字符，n: 长度，不足n用空格填充\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eVARCHAR2(n)\u003c/td\u003e\n          \u003ctd\u003e可变长度字符，n: 最大长度，最大4000\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e时间\u003c/td\u003e\n          \u003ctd\u003eDATE\u003c/td\u003e\n          \u003ctd\u003e日期\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eTIMESTAMP\u003c/td\u003e\n          \u003ctd\u003e日期和时间\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e二进制\u003c/td\u003e\n          \u003ctd\u003eCLOB\u003c/td\u003e\n          \u003ctd\u003e长文本数据\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"22-常用sql\"\u003e2.2 常用SQL\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e常见语法\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 1 创建表\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eVARCHAR2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2 插入数据\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;abcc\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;ddee\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 查询数据\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 4 更新数据\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eUPDATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSET\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;abbc\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 5 删除数据\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDELETE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 6 删除表\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e内置函数\u003c/p\u003e","title":"Oracle 1 SQL"},{"content":"1 准备开发环境 1.1 登录远程windows 连接vpn\n下载vpn软件，使用入职时他人帮忙申请的vpn账号登录 登录远程windows电脑\n使用入职时他人帮忙申请的远程windows账号 登录gitlab\n入职时，有人已帮忙申请gutlab账号。http://172.16.19.246 查看vastbase代码\nhttp://172.16.19.246/VastbaseG100/src 默认无权限，可能搜不到，请找小组领导开通权限 1.2 准备vastbase编译环境 在远程windows中，登录远程centos\n配置git\n生成rsa密钥，配置到gitlab中\n下载vastbase源码\nmkdir g100 cd g100 git clone -b master git@172.16.19.246:VastbaseG100/src.git 下载vastbase依赖的二进制文件\n需要自行通过svn下载，然后，上传到vastbase源码同级目录\nip: 172.16.19.4 用户名: clouder 密码: 自行询问 目录: /Database/Vastbase/third_party 配置用于编译vastbase的环境变量\ncd g100 touch venv 请确保此时的目录结构如下：\nls g100 |-- g100 |-- src |-- binarylibs |-- venv 设置环境变量，在venv文件中，输入以下内容：\nexport CODE_BASE=`pwd` export BINARYLIBS=`pwd`/binarylibs # 安装目录在源码里写死了，改不了 export GAUSSHOME=`pwd`/src/mppdb_temp_install export GCC_PATH=$BINARYLIBS/buildtools/gcc7.3 export CC=$GCC_PATH/gcc/bin/gcc export CXX=$GCC_PATH/gcc/bin/g++ export LD_LIBRARY_PATH=$GAUSSHOME/lib:$GCC_PATH/gcc/lib64:$GCC_PATH/isl/lib:$GCC_PATH/mpc/lib/:$GCC_PATH/mpfr/lib/:$GCC_PATH/gmp/lib/:$LD_LIBRARY_PATH export PATH=$GAUSSHOME/bin:$GCC_PATH/gcc/bin:$PATH # 以下是vastbase增加的 export PATH=$BINARYLIBS/buildtools/cmake/bin:$PATH 配置快捷命令\n# 配置环境变量 source venv # 在~/.bash中，输入快捷编译命令： alias vcode=\u0026#39;cd /home/shenkun/g100\u0026#39; alias venv=\u0026#39;vcode \u0026amp;\u0026amp; source ./venv\u0026#39; alias vinstall=\u0026#39;vcode \u0026amp;\u0026amp; cd src/mppdb_temp_install\u0026#39; alias vmake=\u0026#39;vcode \u0026amp;\u0026amp; cd src \u0026amp;\u0026amp; sh build.sh -m debug -3rd $BINARYLIBS -svn 11\u0026#39; alias vcmake=\u0026#39;vcode \u0026amp;\u0026amp; cd src \u0026amp;\u0026amp; sh build.sh -m debug -3rd $BINARYLIBS -svn 11 -cmake\u0026#39; alias vrecmake=\u0026#39;vcode \u0026amp;\u0026amp; cd src/tmp_build \u0026amp;\u0026amp; make -sj \u0026amp;\u0026amp; make install -sj\u0026#39; alias vinit=\u0026#39;vb_initdb -D $GAUSSHOME/data --nodename=db1\u0026#39; alias vstart=\u0026#39;vb_ctl start -D $GAUSSHOME/data\u0026#39; alias vrestart=\u0026#39;vb_ctl restart -D $GAUSSHOME/data\u0026#39; # 然后，重新source以下 source ~/.bashrc 安装其他依赖工具\n# 切换到root用户 yum install -y libaio-devel flex bison ncureses-devel patch readline-devel python3 # 修改系统默认python版本 rm -f /usr/bin/python ln -s /usr/bin/python3.6 /usr/bin/python 1.3 准备vastbase开发环境 scp shenkun@172.16.100.134:~/vscode/allpkg.tar.gz # 密码 vg@123 tar -zxvf allpkg.tar.gz cd allpkg mv ./.local/share/code-server ~/.local/share cd code-server ./code-server # 1 安装数据库 1.1 编译 由于已配置快捷命令，此处直接用快捷命令\n# 设置环境变量 venv # 编译代码 vcmake # 进入安装目录 vinstall # 增量变量 vrecmake 不用快捷命令的话：\n# 设置环境变量 cd /home/shenkun/g100 source venv # 编译代码 cd src sh build.sh -m debug -3rd $BINARYLIBS -svn 11 -cmake # 进入安装目录 cd $GAUSSHOME 1.2 安装 初始化数据库\nvb_initdb -D $GAUSS/data --nodename=db1 启动数据库\nvb_ctl start -D $GAUSS/data 重启数据库\nvb_ctl restart -D $GAUSS/data 1.3 连接数据库 vsql -p 5432 -d postgres -r -c \u0026#34;ALTER USER $USER PASSWORD \u0026#39;vast@123\u0026#39;\u0026#34; vsql -p 5432 -d postgres -r 2 加解密函数 一、desencrypt函数 vastbase旧函数 格式\n-- 参数 dbms_obfunction_toolkit.desencrypt(plian, key) -\u0026gt; cipher -- 参数类型 -- raw: 16进制编码，约等于bytea，只是无\\x前缀 -- text: 密文自动转换为 base64编码 desencrypt(text, text) -\u0026gt; text desencrypt(bytea, bytea) -\u0026gt; bytea desencrypt(raw, raw) -\u0026gt; raw 输出\nCREATE EXTENSION pgcrypto; SELECT dbms_obfuscation_toolkit.desencrypt(\u0026#39;11111111\u0026#39;, \u0026#39;11111111\u0026#39;)::bytea::raw; -- 输出 5A56366D4B4D396957463845572B4B732F67447777513D3D SELECT dbms_obfuscation_toolkit.desencrypt(\u0026#39;11111111\u0026#39;::bytea::raw, \u0026#39;11111111\u0026#39;::bytea::raw); -- 输出 5A56366D4B4D396957463845572B4B732F67447777513D3D SELECT dbms_obfuscation_toolkit.desencrypt(\u0026#39;11111111\u0026#39;::bytea, \u0026#39;11111111\u0026#39;::bytea)::raw; -- 输出 5A56366D4B4D396957463845572B4B732F67447777513D3D SELECT dbms_obfuscation_toolkit.desencrypt(\u0026#39;1111111111111111\u0026#39;, \u0026#39;11111111\u0026#39;)::bytea::raw; -- 输出 5A56366D4B4D3969574638673037696D356C654861387A616167394370743236 oracle函数 格式\n-- 参数 dbms_obfuscation_toolkit.desdecrypt(plain, key, OUT cipher) -- 参数类型 desdecrypt(varchar2, varchar2, varchar2) desdecrypt(raw, raw, raw) 输出\nraw 类型\nCREATE OR REPLACE FUNCTION desencrypt(plain VARCHAR2, key VARCHAR2) RETURN VARCHAR2 IS cipher RAW(100); BEGIN dbms_obfuscation_toolkit.desencrypt(utl_raw.cast_to_raw(plain), utl_raw.cast_to_raw(key), encrypted_data=\u0026gt;cipher); RETURN rawtohex(cipher); END; / SELECT desencrypt(\u0026#39;11111111\u0026#39;, \u0026#39;11111111\u0026#39;) FROM dual; SELECT utl_raw.cast_to_raw(dbms_obfuscation_toolkit.desencrypt(input_string=\u0026gt;\u0026#39;11111111\u0026#39;, key_string=\u0026gt;\u0026#39;11111111\u0026#39;)) FROM dual; -- 输出 655EA628CF62585F SELECT utl_raw.cast_to_raw(dbms_obfuscation_toolkit.desencrypt(input_string=\u0026gt;\u0026#39;1111111111111111\u0026#39;, key_string=\u0026gt;\u0026#39;11111111\u0026#39;)) FROM dual; SELECT desencrypt(\u0026#39;1111111111111111\u0026#39;, \u0026#39;11111111\u0026#39;) FROM dual; -- 输出 655EA628CF62585F20D3B8A6E657876B varchar 类型\nCREATE OR REPLACE FUNCTION desencrypt(plain VARCHAR2, key VARCHAR2) RETURN VARCHAR2 IS cipher VARCHAR2(100); BEGIN dbms_obfuscation_toolkit.desencrypt(plain, key, encrypted_string=\u0026gt;cipher); RETURN cipher; END; / SELECT utl_raw.cast_to_raw(desencrypt(\u0026#39;11111111\u0026#39;, \u0026#39;11111111\u0026#39;)) FROM dual; -- 输出 655EA628CF62585F -- 换个格式 DECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.desencrypt(\u0026#39;11111111\u0026#39;, \u0026#39;11111111\u0026#39;, encrypted_string=\u0026gt;cipher); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / 二、des3encrypt函数 vastbase旧函数 格式\n-- (一) 参数 dbms_obfuscation_toolkit.des3encrypt(plain, key, iv) -\u0026gt; cipher -- input_string key_string encrypted_string / encrypted_data -- key为16字节，超过16字节的未被使用 -- 参数类型 des3encrypt(text, text, text) -\u0026gt; raw des3encrypt(bytea, bytea, bytea) -\u0026gt; bytea des3encrypt(raw, raw, raw) -\u0026gt; raw -- (二) 参数 dbms_obfuscation_toolkit.des3encrypt(plain, key, keymode = 0) -\u0026gt; cipher -- 参数类型 des3encrypt(text, text, int = 0) -\u0026gt; raw des3encrypt(bytea, bytea, int = 0) -\u0026gt; bytea des3encrypt(raw, raw, int = 0) -\u0026gt; raw -- （三）参数 dbms_obfuscation_toolkit.des3encrypt(plain, key, keymode, iv) -\u0026gt; cipher des3encrypt(text, text, int, text) -\u0026gt; raw des3encrypt(bytea, bytea, int, bytea) -\u0026gt; bytea des3encrypt(raw, raw, int, raw) -\u0026gt; raw 输出\n-- (一) SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, \u0026#39;11111111\u0026#39;)::bytea::raw; -- ERROR: wrong key SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111122222222\u0026#39;, \u0026#39;11111111\u0026#39;)::bytea::raw; SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;::bytea, \u0026#39;1111111122222222\u0026#39;::bytea, \u0026#39;11111111\u0026#39;::bytea)::raw; SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;::bytea::raw, \u0026#39;1111111122222222\u0026#39;::bytea::raw, \u0026#39;11111111\u0026#39;::bytea::raw); -- 输出 4F7A536633345072325939536B547A776c334C6278513D3D -- （二） SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111122222222\u0026#39;)::bytea::raw; SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111122222222\u0026#39;, 0)::bytea::raw; -- 输出 5465744A2B552B384E73504B7671372B2B36424D38413D3D SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;111111112222222211111111\u0026#39;, 1)::bytea::raw; -- ERROR: wrong key SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;111111112222222233333333\u0026#39;, 1)::bytea::raw; -- 输出 5A56366D4B4D3966957463845572B4B732F67447777513D3D -- (三) SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111122222222\u0026#39;, 0, \u0026#39;11111111\u0026#39;)::bytea::raw; -- 输出 4F7A536633345072325939536B547A776c334C6278513D3D SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;111111112222222233333333\u0026#39;, 1, \u0026#39;11111111\u0026#39;)::bytea::raw; -- 输出 51494A71574142676A49635143695859617366464C413D3D oracle函数 格式\n-- (一) 参数 dbms_obfuscation_toolkit.des3encrypt(plain, key, OUT cipher, keymode = 0, iv = NULL) -- input_string key_sgring encrypted_string which iv_string -- input key encrypted_data which iv -- 参数类型 des3encrypt(varchar2, varchar2, varchar2, int = 0, varchar2 = NULL) des3encrypt(raw, raw, raw, int = 0, raw = NULL) 输出\nDECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, encrypted_string=\u0026gt;cipher); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / -- 输出 C7E61EC9A68F8C02 DECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, encrypted_string=\u0026gt;cipher, which=\u0026gt;0, iv_string=\u0026gt;NULL); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / -- 输出 C7E61EC9A68F8C02 DECLARE cipher RAW(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(\u0026#39;3131313131313131\u0026#39;, \u0026#39;31313131313131313131313131313131\u0026#39;, encrypted_data=\u0026gt;cipher, which=\u0026gt;0, iv=\u0026gt;\u0026#39;0123456789abcdef\u0026#39;); dbms_output.put_line(cipher); END; / -- 输出 C7E61EC9A68F8C02 DECLARE cipher RAW(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(hextoraw(\u0026#39;3131313131313131\u0026#39;), hextoraw(\u0026#39;31313131313131313131313131313131\u0026#39;), encrypted_data=\u0026gt;cipher, which=\u0026gt;0, iv=\u0026gt;hextoraw(\u0026#39;0123456789abcdef\u0026#39;)); dbms_output.put_line(cipher); END; / -- 输出 C7E61EC9A68F8C02 DECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(hextoraw(\u0026#39;11111111\u0026#39;), \u0026#39;1111111111111111\u0026#39;, encrypted_string=\u0026gt;cipher, which=\u0026gt;0, iv_string=\u0026gt;NULL); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / -- 输出 C7E61EC9A68F8C02 DECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, encrypted_string=\u0026gt;cipher, which=\u0026gt;0, iv_string=\u0026gt;hextoraw(\u0026#39;0123456789abcdef\u0026#39;)); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / -- 输出 6FFB37B42D9EB72E DECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, encrypted_string=\u0026gt;cipher, which=\u0026gt;0, iv_string=\u0026gt;\u0026#39;11111111\u0026#39;); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / -- 输出 40826A5800607C87 DECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;111111112222222233333333\u0026#39;, encrypted_string=\u0026gt;cipher, which=\u0026gt;1, iv_string=\u0026gt;\u0026#39;11111111\u0026#39;); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / -- 输出 40826A5800608C8 DECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(\u0026#39;1111111111111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, encrypted_string=\u0026gt;cipher); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / -- 输出 C7E61EC9A68F8C02165CEC3E75635F5D 问题单\nselect utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;1111111111111111\u0026#39;, key_string=\u0026gt;010199010401050110974949, which=\u0026gt;0)) from dual; -- 输出 E7E14DFD9E0DED3B D80084E1EDD76DF1 select utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;1111111111111111\u0026#39;, key_string=\u0026gt;\u0026#39;101990104010501109749490\u0026#39;, which=\u0026gt;0)) from dual; -- 输出 E7E14DFD9E0DED3B D80084E1EDD76DF1 select utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;1111111111111111\u0026#39;, key_string=\u0026gt;\u0026#39;010199010401050110974949\u0026#39;, which=\u0026gt;0)) from dual; -- 输出 6BD3D44F21050468F90eD91712B47B4C DECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(\u0026#39;1111111111111111\u0026#39;, \u0026#39;101990104010501109749490\u0026#39;, encrypted_string=\u0026gt;cipher, which=\u0026gt;0, iv_string=\u0026gt;NULL); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / -- 输出 7E14DFD9E0DED3B D80084E1EDD76DF1 http://172.16.19.246/VastbaseG100/src/-/merge_requests/13079/diffs\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/vastbase/","summary":"\u003ch1 id=\"1-准备开发环境\"\u003e1 准备开发环境\u003c/h1\u003e\n\u003ch2 id=\"11-登录远程windows\"\u003e1.1 登录远程windows\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e连接vpn\u003cbr\u003e\n下载vpn软件，使用入职时他人帮忙申请的vpn账号登录\u003c/li\u003e\n\u003cli\u003e登录远程windows电脑\u003cbr\u003e\n使用入职时他人帮忙申请的远程windows账号\u003c/li\u003e\n\u003cli\u003e登录gitlab\u003cbr\u003e\n入职时，有人已帮忙申请gutlab账号。\u003ca href=\"http://172.16.19.246/\"\u003ehttp://172.16.19.246\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e查看vastbase代码\u003cbr\u003e\n\u003ca href=\"http://172.16.19.246/VastbaseG100/src\"\u003ehttp://172.16.19.246/VastbaseG100/src\u003c/a\u003e\n\u003cul\u003e\n\u003cli\u003e默认无权限，可能搜不到，请找小组领导开通权限\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"12-准备vastbase编译环境\"\u003e1.2 准备vastbase编译环境\u003c/h2\u003e\n\u003cp\u003e在远程windows中，登录远程centos\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e配置git\u003cbr\u003e\n生成rsa密钥，配置到gitlab中\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e下载vastbase源码\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir g100\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e g100\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit clone -b master git@172.16.19.246:VastbaseG100/src.git\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e下载vastbase依赖的二进制文件\u003cbr\u003e\n需要自行通过svn下载，然后，上传到vastbase源码同级目录\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eip: 172.16.19.4\u003c/li\u003e\n\u003cli\u003e用户名: clouder\u003c/li\u003e\n\u003cli\u003e密码: 自行询问\u003c/li\u003e\n\u003cli\u003e目录: /Database/Vastbase/third_party\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e配置用于编译vastbase的环境变量\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e g100\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etouch venv\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e请确保此时的目录结构如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003els g100\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e-- g100\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e|\u003c/span\u003e-- src\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e|\u003c/span\u003e-- binarylibs\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e|\u003c/span\u003e-- venv\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e设置环境变量，在venv文件中，输入以下内容：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCODE_BASE\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eBINARYLIBS\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e/binarylibs\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 安装目录在源码里写死了，改不了\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e/src/mppdb_temp_install\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eGCC_PATH\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$BINARYLIBS\u003c/span\u003e/buildtools/gcc7.3\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCC\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$GCC_PATH\u003c/span\u003e/gcc/bin/gcc\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCXX\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$GCC_PATH\u003c/span\u003e/gcc/bin/g++\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eLD_LIBRARY_PATH\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/lib:\u003cspan class=\"nv\"\u003e$GCC_PATH\u003c/span\u003e/gcc/lib64:\u003cspan class=\"nv\"\u003e$GCC_PATH\u003c/span\u003e/isl/lib:\u003cspan class=\"nv\"\u003e$GCC_PATH\u003c/span\u003e/mpc/lib/:\u003cspan class=\"nv\"\u003e$GCC_PATH\u003c/span\u003e/mpfr/lib/:\u003cspan class=\"nv\"\u003e$GCC_PATH\u003c/span\u003e/gmp/lib/:\u003cspan class=\"nv\"\u003e$LD_LIBRARY_PATH\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003ePATH\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/bin:\u003cspan class=\"nv\"\u003e$GCC_PATH\u003c/span\u003e/gcc/bin:\u003cspan class=\"nv\"\u003e$PATH\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 以下是vastbase增加的\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003ePATH\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$BINARYLIBS\u003c/span\u003e/buildtools/cmake/bin:\u003cspan class=\"nv\"\u003e$PATH\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e配置快捷命令\u003c/p\u003e","title":"Vastbase"},{"content":"国策用例 4、配置客户端认证方式 hostssl all all 0.0.0.0/0 cert 1、生成国密证书 创建 CA 目录 cadir 并进入 mkdir cadir cd cadir copy 配置文件 openssl.cnf 到当前目录（不同环境，配置文件路径可能不一样） cp /etc/pki/tls/openssl.cnf . 开始搭建CA环境 mkdir ./demoCA ./demoCA/newcerts ./demoCA/private chmod 777 ./demoCA/private 创建serial文件,写入01 echo \u0026#39;01\u0026#39;\u0026gt;./demoCA/serial 创建文件index.txt touch ./demoCA/index.txt 修改openssl.cnf配置文件中CA_default的参数 dir = ./demoCA default_md = sha256 至此CA环境搭建完成 生成CA私钥 openssl ecparam -out demoCA/private/cakey.pem -name SM2 -genkey 生成根证书请求文件 openssl req -config openssl.cnf -key demoCA/private/cakey.pem -new -out cacert.req -subj /C=CN/ST=BJ/L=HaiDian/O=VAST/OU=SEC/CN=CLIENT 生成自签发根证书 生成根证书时，需要修改openssl.cnf文件，设置basicConstraints=CA:TRUE vi openssl.cnf 生成CA自签发根证书 openssl ca -config openssl.cnf -in cacert.req -keyfile demoCA/private/cakey.pem -selfsign -out demoCA/cacert.pem 生成服务器私钥文件server.key openssl ecparam -out server.key -name SM2 -genkey 生成服务器证书请求文件server.req openssl req -config openssl.cnf -key server.key -new -out server.req -subj /C=CN/ST=BJ/L=HaiDian/O=VAST/OU=SEC/CN=server 生成服务端/客户端证书时，修改openssl.cnf文件，设置basicConstraints=CA:FALSE vi openssl.cnf 对生成的服务器证书请求文件进行签发，签发后将生成正式的服务器证书server.crt openssl ca -config openssl.cnf -in server.req -out server.crt -days 3650 生成客户端私钥 openssl ecparam -out client.key -name SM2 -genkey 生成客户端证书请求文件 openssl req -config openssl.cnf -new -key client.key -out client.req -subj /C=CN/ST=BJ/L=HaiDian/O=VAST/OU=SEC/CN=client 对生成的客户端证书请求文件进行签发，签发后将生成正式的客户端证书client.crt openssl ca -config openssl.cnf -in client.req -out client.crt -days 3650 注：中间会产生交互，按照以下内容进行填写（需注意每个交互的common name填不一样的内容，如分别写：test1,test2,test3）： Country Name (2 letter code) [AU]:CN State or Province Name (full name) [Some-State]:shanxi Locality Name (eg, city) []:xian Organization Name (eg, company) [Internet Widgits Pty Ltd]:Abc Organizational Unit Name (eg, section) []:hello --Common Name可以随意命名 Common Name (eg, YOUR name) []:world --Email可以选择性填写 Email Address []: Please enter the following \u0026#39;extra\u0026#39; attributes to be sent with your certificate request A challenge password []: 1qaz!QAZ An optional company name []:world # --------------------------------------- https://gitee.com/opengauss/openGauss-server/pulls/3254 mkdir certs cp ../../tassl/tassl_demo/cert/openssl.cnf certs/ cd certs #CA openssl ecparam -genkey -name SM2 -out CA.key openssl req -config openssl.cnf -new -subj /C=CN/ST=BJ/L=HaiDian/O=YUNHEENMO/OU=MogDB/CN=FooCA -key CA.key -out CA.csr openssl x509 -sm3 -req -days 1500 -in CA.csr -extfile openssl.cnf -extensions v3_ca -signkey CA.key -out CA.crt #server openssl ecparam -genkey -name SM2 -out server.key openssl req -config openssl.cnf -new -subj /C=CN/ST=BJ/L=HaiDian/O=YUNHEENMO/OU=MogDB/CN=server -key server.key -out server.csr openssl x509 -sm3 -req -days 1500 -in server.csr -CA CA.crt -CAkey CA.key -extfile openssl.cnf -out server.crt -CAcreateserial #server_enc openssl ecparam -genkey -name SM2 -out server_enc.key openssl req -config openssl.cnf -new -subj /C=CN/ST=BJ/L=HaiDian/O=YUNHEENMO/OU=MogDB/CN=server -key server_enc.key -out server_enc.csr openssl x509 -sm3 -req -days 1500 -in server_enc.csr -CA CA.crt -CAkey CA.key -extfile openssl.cnf -out server_enc.crt -CAcreateserial #client openssl ecparam -genkey -name SM2 -out client.key openssl req -config openssl.cnf -new -subj /C=CN/ST=BJ/L=HaiDian/O=YUNHEENMO/OU=MogDB/CN=client -key client.key -out client.csr openssl x509 -sm3 -req -days 1500 -in client.csr -CA CA.crt -CAkey CA.key -extfile openssl.cnf -out client.crt -CAcreateserial #client_enc openssl ecparam -genkey -name SM2 -out client_enc.key openssl req -config openssl.cnf -new -subj /C=CN/ST=BJ/L=HaiDian/O=YUNHEENMO/OU=MogDB/CN=client -key client_enc.key -out client_enc.csr openssl x509 -sm3 -req -days 1500 -in client_enc.csr -CA CA.crt -CAkey CA.key -extfile openssl.cnf -out client_enc.crt -CAcreateserial #修改权限 chmod 0600 * #增加密码保护 openssl ec -sm4 -in server.key -out server.key -passout pass:123qweQWE gs_guc generate -S 123qweQWE -D ./ -o server openssl ec -sm4 -in server_enc.key -out server_enc.key -passout pass:234werWER gs_guc generate -S 234werWER -D ./ -o server_enc openssl ec -sm4 -in client.key -out client.key -passout pass:345ertERT gs_guc generate -S 345ertERT -D ./ -o client openssl ec -sm4 -in client_enc.key -out client_enc.key -passout pass:456rtyRTY gs_guc generate -S 456rtyRTY -D ./ -o client_enc chmod 0600 * #客户端： export CERT=`pwd` echo \u0026#39; export CERT=`pwd` export PGSSLMODE=verify-ca export PGSSLTLCP=1 export PGSSLROOTCERT=$CERT/CA.crt export PGSSLKEY=$CERT/client.key export PGSSLCERT=$CERT/client.crt export PGSSLENCKEY=$CERT/client_enc.key export PGSSLENCCERT=$CERT/client_enc.crt \u0026#39; \u0026gt; client_env source client_env #服务器： gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl=on\u0026#34; gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl_ciphers = \u0026#39;ALL\u0026#39;\u0026#34; gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl_use_tlcp=on\u0026#34; gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl_ca_file = \u0026#39;$CERT/CA.crt\u0026#39;\u0026#34; gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl_key_file=\u0026#39;$CERT/server.key\u0026#39;\u0026#34; gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl_cert_file=\u0026#39;$CERT/server.crt\u0026#39;\u0026#34; gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl_enc_key_file=\u0026#39;$CERT/server_enc.key\u0026#39;\u0026#34; gs_guc set -D $GAUSSHOME/data -c \u0026#34;ssl_enc_cert_file=\u0026#39;$CERT/server_enc.crt\u0026#39;\u0026#34; 1、生成国密证书 # 创建 CA 目录 cadir 并进入 # copy 配置文件 openssl.cnf 到当前目录（不同环境，配置文件路径可能不一样） cp /etc/pki/tls/openssl.cnf . # 开始搭建CA环境 mkdir ./demoCA ./demoCA/newcerts ./demoCA/private chmod 777 ./demoCA/private # 创建serial文件,写入01 echo \u0026#39;01\u0026#39;\u0026gt;./demoCA/serial # 创建文件index.txt touch ./demoCA/index.txt # 至此CA环境搭建完成 # 生成CA私钥 openssl ecparam -out demoCA/private/cakey.pem -name SM2 -genkey # 生成根证书请求文件 openssl req -config openssl.cnf -key demoCA/private/cakey.pem -new -out cacert.req # 生成自签发根证书 # 生成根证书时，需要修改openssl.cnf文件，设置basicConstraints=CA:TRUE vi openssl.cnf # 生成CA自签发根证书 openssl ca -config openssl.cnf -in cacert.req -keyfile demoCA/private/cakey.pem -selfsign -out demoCA/cacert.pem # 生成服务器私钥文件server.key openssl ecparam -out server.key -name SM2 -genkey # 生成服务器证书请求文件server.req openssl req -config openssl.cnf -key server.key -new -out server.req # 生成服务端/客户端证书时，修改openssl.cnf文件，设置basicConstraints=CA:FALSE vi openssl.cnf # 对生成的服务器证书请求文件进行签发，签发后将生成正式的服务器证书server.crt openssl ca -config openssl.cnf -in server.req -out server.crt -days 3650 # 生成客户端私钥 openssl ecparam -out client.key -name SM2 -genkey # 生成客户端证书请求文件 openssl req -config openssl.cnf -new -key client.key -out client.req # 对生成的客户端证书请求文件进行签发，签发后将生成正式的客户端证书client.crt openssl ca -config openssl.cnf -in client.req -out client.crt -days 3650 # 注：中间会产生交互，按照以下内容进行填写（需注意每个交互的common name填不一样的内容，如分别写：test1,test2,test3）： Country Name (2 letter code) [AU]:CN State or Province Name (full name) [Some-State]:shanxi Locality Name (eg, city) []:xian Organization Name (eg, company) [Internet Widgits Pty Ltd]:Abc Organizational Unit Name (eg, section) []:hello --Common Name可以随意命名 Common Name (eg, YOUR name) []:world --Email可以选择性填写 Email Address []: Please enter the following \u0026#39;extra\u0026#39; attributes to be sent with your certificate request A challenge password []: 1qaz!QAZ An optional company name []:world 2、配置客户端文件 chmod 600 client.key chmod 600 client.crt chmod 600 ./demoCA/cacert.pem chmod 600 server.key chmod 600 server.crt 3、配置服务器端参数 cp server.crt server.key ./demoCA/cacert.pem $PGDATA cp client.crt client.key /home/vastbase/data/vastbase/ export PGSSLCERT=\u0026#34;/home/vastbase/cadir/client.crt\u0026#34; export PGSSLKEY=\u0026#34;/home/vastbase/cadir/client.key\u0026#34; export PGSSLMODE=\u0026#34;verify-ca\u0026#34; export PGSSLROOTCERT=\u0026#34;/home/vastbase/data/vastbase/cacert.pem\u0026#34; vi postgresql.conf ssl = on require_ssl = on ssl_cert_file = \u0026#39;server.crt\u0026#39; ssl_key_file = \u0026#39;server.key\u0026#39; ssl_ca_file = \u0026#39;cacert.pem\u0026#39; ssl_crl_file = \u0026#39;\u0026#39; 4、配置客户端认证方式 vi pg_hba.conf hostssl all all 0.0.0.0/0 cert 5、重启数据库服务 vb_ctl restart vsql - vastbase -r --创建生成客户端证书时Common Name同名用户 create user test3 password\u0026#39;Test@123\u0026#39;; 1、客户端vsql连接到服务端 vsql -dvastbase -r -h IP -U test3 --预期 连接成功，提示SSL connection 1 需求背景 1.2 Oracle Profile功能 一、查看profile信息 设置sqlplus输出格式\nSET LINESIZE 200 SET PAGESIZE 100 SET COLSEP \u0026#39; | \u0026#39; SET NUMWIDTH 15 SET HEADING ON SET FEEDBACK OFF 查看用户的profile\nSELECT username, profile FROM dba_users; USERNAME | PROFILE ---------+---------- SYS | DEFAULT SYSTEM | DEFAULT .. | .. 查看所有profile配置项\nSELECT * FROM dba_profiles ORDER BY profile; PROFILE | RESOURCE_NAME | RESOURCE | LIMIT ----------------------+---------------------------+----------+----------- DEFAULT | CONPOSITE_LIMIT | KERNEL | UNLIMITED DEFAULT | PASSWORD_LOCK_TIME | PASSWORD | 1 DEFAULT | PASSWORD_VERIFY_FUNCTION | PASSWORD | NULL DEFAULT | PASSWORD_REUSE_MAX | PASSWORD | UNLIMITED DEFAULT | PASSWORD_REUSE_TIME | PASSWORD | UNLIMITED DEFAULT | PASSWORD_LIFE_TIME | PASSWORD | 180 DEFAULT | FAILED_LOGIN_ATTEMPTS | PASSWORD | 10 DEFAULT | PRIVATE_SGA | KERNEL | UNLIMITED DEFAULT | CONNECT_TIME | KERNEL | UNLIMITED DEFAULT | IDLE_TIME | KERNEL | UNLIMITED DEFAULT | LOGICAL_READS_PER_CALL | KERNEL | UNLIMITED DEFAULT | LOGICAL_READS_PER_SESSION | KERNEL | UNLIMITED DEFAULT | CPU_PER_CALL | KERNEL | UNLIMITED DEFAULT | CPU_PER_SESSION | KERNEL | UNLIMITED DEFAULT | SESSIONS_PER_USER | KERNEL | UNLIMITED DEFAULT | PASSWORD_GRACE_TIME | PASSWORD | 7 MONITORING_PROFILE | .. ... | ... 二、管理profile 创建profile\nCREATE PROFILE pro1 LIMIT CPU_PER_SESSION 60000 PASSWORD_LIFE_TIME 90 FAILED_LOGIN_ATTEMPTS 3; SELECT * FROM dba_profiles WHERE profile = \u0026#39;PRO1\u0026#39;; PROFILE | RESOURCE_NAME | RESOURCE | LIMIT -------------------+---------------------------+----------+----------- PRO1 | CONPOSITE_LIMIT | KERNEL | DEFAULT PRO1 | PASSWORD_LOCK_TIME | PASSWORD | DEFAULT PRO1 | PASSWORD_VERIFY_FUNCTION | PASSWORD | DEFAULT PRO1 | PASSWORD_REUSE_MAX | PASSWORD | DEFAULT PRO1 | PASSWORD_REUSE_TIME | PASSWORD | DEFAULT PRO1 | PASSWORD_LIFE_TIME | PASSWORD | 90 PRO1 | FAILED_LOGIN_ATTEMPTS | PASSWORD | 3 PRO1 | PRIVATE_SGA | KERNEL | DEFAULT PRO1 | CONNECT_TIME | KERNEL | DEFAULT PRO1 | IDLE_TIME | KERNEL | DEFAULT PRO1 | LOGICAL_READS_PER_CALL | KERNEL | DEFAULT PRO1 | LOGICAL_READS_PER_SESSION | KERNEL | DEFAULT PRO1 | CPU_PER_CALL | KERNEL | DEFAULT PRO1 | CPU_PER_SESSION | KERNEL | 6000 PRO1 | SESSIONS_PER_USER | KERNEL | DEFAULT PRO1 | PASSWORD_GRACE_TIME | PASSWORD | DEFAULT 修改profile\nALTER PROFILE pro1 LIMIT CPU_PER_SESSION 10000 PASSWORD_LIFE_TIME 80; SELECT * FROM dba_profiles WHERE profile = \u0026#39;PRO1\u0026#39;; 删除profile\nDROP PROFILE pro1 CASCADE; 三、管理用户profile 创建用户\nCREATE USER u1 IDENTIFIED BY \u0026#34;u1@1234\u0026#34; PROFILE default; 为用户分配profile\nALTER USER u1 PROFILE pro1; SELECT username, profile FROM dba_users WHERE username = \u0026#39;U1\u0026#39;; 2 需求设计 2.1 需求目标 语法\nCREATE PROFILE pro1 LIMIT CPU_PER_SESSION 60000; ALTER USER u1 PROFILE pro1; DROP PROFILE pro1 CASCADE; 系统表名、系统表字段\nSELECT * FROM dba_profiles WHERE profile = \u0026#39;PRO1\u0026#39;; PROFILE | RESOURCE_NAME | RESOURCE | LIMIT -----------------+---------------------------+----------+----------- PRO1 | CONPOSITE_LIMIT | KERNEL | DEFAULT 参数\n1 身份认证概述 1.1 身份认证基本概念 本文涉及3个基本概念：\n用户 角色 配置参数 一、用户 存储用户的系统表pg_authid\n\\d pg_authid; Column | Type | Modifiers -----------------+--------------------------+----------- rolname | name | not null rolsuper | boolean | not null rolinherit | boolean | not null rolcreaterole | boolean | not null rolcreatedb | boolean | not null rolcatupdate | boolean | not null rolcanlogin | boolean | not null rolreplication | boolean | not null rolauditadmin | boolean | not null rolsystemadmin | boolean | not null rolconnlimit | integer | not null rolpassword | text | rolvalidbegin | timestamp with time zone | rolvaliduntil | timestamp with time zone | rolrespool | name | roluseft | boolean | rolparentid | oid | roltabspace | text | rolkind | \u0026#34;char\u0026#34; | rolnodegroup | oid | roltempspace | text | rolspillspace | text | rolexcpdata | text | rolmonitoradmin | boolean | roloperatoradmin | boolean | rolpolicyadmin | boolean | rolpasswordext | text | 查看全部用户\nSELECT rolname,oid,rolparentid,rolkind,rolvalidbegin FROM pg_authid; rolname | oid | rolparentid | rolkind | rolvalidbegin -------------------------+-------+-------------+---------+--------------- gs_role_copy_files | 1044 | 0 | n | gs_role_signal_backend | 1045 | 0 | n | gs_role_tablespace | 1046 | 0 | n | gs_role_replication | 1047 | 0 | n | gs_role_account_lock | 1048 | 0 | n | gs_role_pldebugger | 1055 | 0 | n | gs_role_directory_create | 1056 | 0 | n | gs_role_directory_drop | 1059 | 0 | n | shenkun | 10 | 0 | n | u1 | 24576 | 0 | n | (10 rows) 二、角色 三、配置参数 存储GUC参数的系统试图pg_settings\n\\d pg_settings; Column | Type | Modifiers -----------+---------+----------- name | text | setting | text | unit | text | category | text | short_desc | text | extra_desc | text | context | text | vartype | text | source | text | min_val | text | max_val | text | enumvals | text[] | boot_val | text | reset_val | text | sourcefile | text | sourceline | integer | CREATE VIEW pg_settings AS SELECT * FROM pg_catalog.pg_show_all_settings() AS A; -- 调用 show_all_settings() 查看有关的参数\nSELECT name,setting,vartype,context FROM pg_settings WHERE name like \u0026#39;%pass%\u0026#39;; name | setting | vartype | context -------------------------+---------+---------+--------- bypass_dram | 0.01 | real | sighup bypass_nvm | 0.5 | real | sighup modify_initial_password | off | bool | sighup password_effect_time | 90 | real | sighup password_encryption_type | 2 | integer | sighup password_lock_time | 1 | real | sighup password_max_length | 32 | integer | sighup password_min_digital | 0 | integer | sighup password_min_length | 8 | integer | sighup password_min_lowercase | 0 | integer | sighup password_min_special | 0 | integer | sighup password_min_uppercase | 0 | integer | sighup password_notify_time | 7 | integer | sighup password_policy | 1 | integer | sighup password_reuse_max | 0 | integer | sighup password_reuse_time | 60 | real | sighup (16 rows) SELECT name,setting,vartype,context FROM pg_settings WHERE name like \u0026#39;%login%\u0026#39;; name | setting | vartype | context ----------------------+---------+---------+------------ audit_login_logout | 7 | integer | sighup failed_login_attempts | 10 | integer | sighup xloginsert_locks | 8 | integer | postmaster (3 rows) SELECT name,setting,vartype,context FROM pg_settings WHERE name like \u0026#39;%session%\u0026#39;; name | setting | vartype | context ------------------------------------+--------------+---------+----------- idle_in_transaction_session_timeout | 0 | integer | user session_history_memory | 10240 | integer | sighup session_replication_role | origin | enum | superuser session_respool | invalid_pool | string | user session_statistics_memory | 5120 | integer | sighup session_timeout | 600 | integer | user track_stmt_session_slot | 1000 | integer | sighup (7 rows) SELECT name,setting,vartype,context FROM pg_settings WHERE name like \u0026#39;%statement%\u0026#39;; name | setting | vartype | context ---------------------------+---------+---------+----------- log_min_duration_statement | 1800000 | integer | superuser log_min_error_statement | error | enum | superuser log_statement | none | enum | superuser log_statement_stats | off | bool | superuser statement_timeout | 0 | integer | user (5 rows) SELECT name,setting,vartype,context FROM pg_settings WHERE name like \u0026#39;%connection%\u0026#39;; name | setting | vartype | context ------------------------------+---------+---------+------------ cache_connection | on | bool | sighup character_set_connection | UTF8 | string | user collation_connection | | string | user connection_alarm_rate | 0.9 | real | sighup log_connections | off | bool | backend log_disconnections | off | bool | backend max_connections | 200 | integer | postmaster max_inner_tool_connections | 50 | integer | postmaster sysadmin_reserved_connections | 3 | integer | postmaster connection_info | {\u0026#34;driver_name\u0026#34;:\u0026#34;libpq\u0026#34;,\u0026#34;driver_version\u0026#34; ....} | string | user (10 rows) 设置参数的语法\nopengauss中SET语法链接：https://docs.opengauss.org/zh/docs/latest/docs/SQLReference/SET.html\n本文主要关注以下语法：\n设置自定义变量\nSET @var_name := expr [, @var_name := expr] ... SET @var_name = expr [, @var_name = expr] ... 2 特性分析 特性设计 语法支持\nSET @var_name := expr [, @var_name := expr] ... [FOR USER username] SET @var_name := expr [, @var_name := expr] ... [FOR ROLE username] VariableMultiSetStmt: SET VariableSetElemsList VariableSetElemsList: VariableSetElem | VariableSetElemsList \u0026#39;,\u0026#39; VariableSetElem VariableSetElem user_defined_single ExecSetVariableStmt 特性流程 新增系统表vb_role_settings\n新增系统表vb_role_settings，存储用户级GUC参数。原有的pg_settings存储实例级GUC参数 设置用户级GUC参数\n使用SET name=setting FOR USER username语法设置用户级GUC参数 解析用户级GUC参数\n检查name是否在白名单内，检查setting的取值是否满足实例级GUC的约束，检查username是否存在 存储用户级GUC参数\n将name, setting, useroid存入vb_role_settings 使用用户级GUC参数\n在原使用示例级GUC参数的地方，先检查是否存在用户级GUC参数，如果存在用户级GUC参数，则使用用户级GUC参数，否则，使用实例级GUC参数 3 特性设计 主成功场景 （一） 设置、查看、删除用户级GUC参数 配置用户级参数\nSET password_effect_time = 90 FOR USER \u0026#39;shenkun\u0026#39;; 由于开发周期短，当前版本中，支持的功能较少，但符合客户需求：\n参数列表：暂时支持10多个用户级GUC参数，具体参数列表请参考产品文档。 作用范围：每个用户级参数，可对单个用户生效，也可对一组用户(role)生效 设置方式：只支持通过SET和RESET设置参数值，暂不支持通过配置文件设置参数值。 查看所有用户级参数\n新增系统表vb_role_settings，记录所有用户级GUC参数。有实例级GUC参数值不等于用户级GUC参数值时，该系统表中才记录用户级GUC参数的值\nSELECT * FROM vb_role_settings; profileoid | profilename | setting | rolid | 2025-02-18 11:00:00 ------------+---------------+----------------------------- 1 file1 password_effect_time 1 file1 password_max_length SELECT * FROM vb_role_settings WHERE profilename = \u0026#39;file1\u0026#39;; rolid | setid | setname | setval | setvartype | change | ------+-------+-----------------------+--------+------------+---------------------+ 10 | 1 | password_effect_time | 90 | int | 2025-02-18 11:00:00 | 10 | 2 | password_max_length | 10 | int | 2025-02-18 11:11:00 | 查看当前用户的用户级参数\nSELECT * FROM vb_role_settings WHERE rolid = (SELECT oid FROM pg_roles WHERE rolname = CURRENT_USER); rolid | setid | setname | setval | setvartype | change | ------+-------+-----------------------+--------+------------+---------------------+ 10 | 1 | password_effect_time | 90 | int | 2025-02-18 11:00:00 | 10 | 2 | password_max_length | 10 | int | 2025-02-18 11:11:00 | 配置用户级参数为默认值\n-- 如果实例级GUC参数的值也是default，则会删除vb_role_settings中相关的记录值，即不重复记录 SET password_effect_time = default FOR USER \u0026#39;shenkun\u0026#39;; 删除用户级参数\n-- 系统表中，password_effect_time这条记录将被删除 RESET password_effect_time FOR USER \u0026#39;shenkun\u0026#39;; （二）验证用户级GUC参数 内核中，在使用GUC参数的地方，先获取当前登录系统的用户，再检查是否存在该用户对应的用户级GUC参数，如果存在，则直接使用用户级GUC参数，如果不存在，则使用实例级GUC参数。\n（三）级联删除用户级GUC参数 级联删除用户级参数\nSELECT oid FROM pg_roles WHERE rolname = \u0026#39;shenkun\u0026#39; DROP USER \u0026#39;shenkun\u0026#39;; -- 系统表中所有\u0026#39;shenkun\u0026#39;相关的记录将被删除 SELECT * FROM vb_role_settings; （四）主备用户级GUC参数同步 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/vastbase-auth/","summary":"\u003ch1 id=\"国策用例\"\u003e国策用例\u003c/h1\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e4、配置客户端认证方式\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ehostssl all all 0.0.0.0/0 cert\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e1、生成国密证书\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e创建 CA 目录 cadir 并进入\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir cadir\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e cadir\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecopy 配置文件 openssl.cnf 到当前目录（不同环境，配置文件路径可能不一样）\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp /etc/pki/tls/openssl.cnf .\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e开始搭建CA环境\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir ./demoCA ./demoCA/newcerts ./demoCA/private\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod \u003cspan class=\"m\"\u003e777\u003c/span\u003e ./demoCA/private\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e创建serial文件,写入01\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;01\u0026#39;\u003c/span\u003e\u0026gt;./demoCA/serial\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e创建文件index.txt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etouch ./demoCA/index.txt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e修改openssl.cnf配置文件中CA_default的参数\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003edir\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e ./demoCA\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003edefault_md\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e sha256\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e至此CA环境搭建完成\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e生成CA私钥\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -out demoCA/private/cakey.pem -name SM2 -genkey\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e生成根证书请求文件\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -config openssl.cnf -key demoCA/private/cakey.pem -new -out cacert.req -subj /C\u003cspan class=\"o\"\u003e=\u003c/span\u003eCN/ST\u003cspan class=\"o\"\u003e=\u003c/span\u003eBJ/L\u003cspan class=\"o\"\u003e=\u003c/span\u003eHaiDian/O\u003cspan class=\"o\"\u003e=\u003c/span\u003eVAST/OU\u003cspan class=\"o\"\u003e=\u003c/span\u003eSEC/CN\u003cspan class=\"o\"\u003e=\u003c/span\u003eCLIENT\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e生成自签发根证书\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e生成根证书时，需要修改openssl.cnf文件，设置basicConstraints\u003cspan class=\"o\"\u003e=\u003c/span\u003eCA:TRUE\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evi openssl.cnf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e生成CA自签发根证书\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ca -config openssl.cnf -in cacert.req -keyfile demoCA/private/cakey.pem -selfsign -out demoCA/cacert.pem\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e生成服务器私钥文件server.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -out server.key -name SM2 -genkey\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e生成服务器证书请求文件server.req\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -config openssl.cnf -key server.key -new -out server.req -subj /C\u003cspan class=\"o\"\u003e=\u003c/span\u003eCN/ST\u003cspan class=\"o\"\u003e=\u003c/span\u003eBJ/L\u003cspan class=\"o\"\u003e=\u003c/span\u003eHaiDian/O\u003cspan class=\"o\"\u003e=\u003c/span\u003eVAST/OU\u003cspan class=\"o\"\u003e=\u003c/span\u003eSEC/CN\u003cspan class=\"o\"\u003e=\u003c/span\u003eserver\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e生成服务端/客户端证书时，修改openssl.cnf文件，设置basicConstraints\u003cspan class=\"o\"\u003e=\u003c/span\u003eCA:FALSE\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evi openssl.cnf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e对生成的服务器证书请求文件进行签发，签发后将生成正式的服务器证书server.crt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ca -config openssl.cnf -in server.req -out server.crt -days \u003cspan class=\"m\"\u003e3650\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e生成客户端私钥\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -out client.key -name SM2 -genkey\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e生成客户端证书请求文件\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -config openssl.cnf -new -key client.key -out client.req -subj /C\u003cspan class=\"o\"\u003e=\u003c/span\u003eCN/ST\u003cspan class=\"o\"\u003e=\u003c/span\u003eBJ/L\u003cspan class=\"o\"\u003e=\u003c/span\u003eHaiDian/O\u003cspan class=\"o\"\u003e=\u003c/span\u003eVAST/OU\u003cspan class=\"o\"\u003e=\u003c/span\u003eSEC/CN\u003cspan class=\"o\"\u003e=\u003c/span\u003eclient\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e对生成的客户端证书请求文件进行签发，签发后将生成正式的客户端证书client.crt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ca -config openssl.cnf -in client.req -out client.crt -days \u003cspan class=\"m\"\u003e3650\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e注：中间会产生交互，按照以下内容进行填写（需注意每个交互的common name填不一样的内容，如分别写：test1,test2,test3）：\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eCountry Name \u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e letter code\u003cspan class=\"o\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003eAU\u003cspan class=\"o\"\u003e]\u003c/span\u003e:CN\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eState or Province Name \u003cspan class=\"o\"\u003e(\u003c/span\u003efull name\u003cspan class=\"o\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003eSome-State\u003cspan class=\"o\"\u003e]\u003c/span\u003e:shanxi\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eLocality Name \u003cspan class=\"o\"\u003e(\u003c/span\u003eeg, city\u003cspan class=\"o\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e[]\u003c/span\u003e:xian\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eOrganization Name \u003cspan class=\"o\"\u003e(\u003c/span\u003eeg, company\u003cspan class=\"o\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003eInternet Widgits Pty Ltd\u003cspan class=\"o\"\u003e]\u003c/span\u003e:Abc\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eOrganizational Unit Name \u003cspan class=\"o\"\u003e(\u003c/span\u003eeg, section\u003cspan class=\"o\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e[]\u003c/span\u003e:hello\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--Common Name可以随意命名\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eCommon Name \u003cspan class=\"o\"\u003e(\u003c/span\u003eeg, YOUR name\u003cspan class=\"o\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e[]\u003c/span\u003e:world\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--Email可以选择性填写\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eEmail Address \u003cspan class=\"o\"\u003e[]\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ePlease enter the following \u003cspan class=\"s1\"\u003e\u0026#39;extra\u0026#39;\u003c/span\u003e attributes\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eto be sent with your certificate request\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eA challenge password \u003cspan class=\"o\"\u003e[]\u003c/span\u003e: 1qaz!QAZ\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eAn optional company name \u003cspan class=\"o\"\u003e[]\u003c/span\u003e:world\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# ---------------------------------------\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ehttps://gitee.com/opengauss/openGauss-server/pulls/3254\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir certs\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp ../../tassl/tassl_demo/cert/openssl.cnf  certs/\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e certs\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#CA\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -genkey -name SM2 -out CA.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -config openssl.cnf -new -subj /C\u003cspan class=\"o\"\u003e=\u003c/span\u003eCN/ST\u003cspan class=\"o\"\u003e=\u003c/span\u003eBJ/L\u003cspan class=\"o\"\u003e=\u003c/span\u003eHaiDian/O\u003cspan class=\"o\"\u003e=\u003c/span\u003eYUNHEENMO/OU\u003cspan class=\"o\"\u003e=\u003c/span\u003eMogDB/CN\u003cspan class=\"o\"\u003e=\u003c/span\u003eFooCA -key CA.key -out CA.csr\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -sm3 -req -days \u003cspan class=\"m\"\u003e1500\u003c/span\u003e -in CA.csr -extfile openssl.cnf -extensions v3_ca -signkey CA.key -out CA.crt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#server\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -genkey -name SM2 -out server.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -config openssl.cnf -new -subj /C\u003cspan class=\"o\"\u003e=\u003c/span\u003eCN/ST\u003cspan class=\"o\"\u003e=\u003c/span\u003eBJ/L\u003cspan class=\"o\"\u003e=\u003c/span\u003eHaiDian/O\u003cspan class=\"o\"\u003e=\u003c/span\u003eYUNHEENMO/OU\u003cspan class=\"o\"\u003e=\u003c/span\u003eMogDB/CN\u003cspan class=\"o\"\u003e=\u003c/span\u003eserver -key server.key -out server.csr\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -sm3 -req -days \u003cspan class=\"m\"\u003e1500\u003c/span\u003e -in server.csr -CA CA.crt -CAkey CA.key -extfile openssl.cnf -out server.crt -CAcreateserial\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#server_enc\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -genkey -name SM2 -out server_enc.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -config openssl.cnf -new -subj /C\u003cspan class=\"o\"\u003e=\u003c/span\u003eCN/ST\u003cspan class=\"o\"\u003e=\u003c/span\u003eBJ/L\u003cspan class=\"o\"\u003e=\u003c/span\u003eHaiDian/O\u003cspan class=\"o\"\u003e=\u003c/span\u003eYUNHEENMO/OU\u003cspan class=\"o\"\u003e=\u003c/span\u003eMogDB/CN\u003cspan class=\"o\"\u003e=\u003c/span\u003eserver -key server_enc.key -out server_enc.csr\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -sm3 -req -days \u003cspan class=\"m\"\u003e1500\u003c/span\u003e -in server_enc.csr -CA CA.crt -CAkey CA.key -extfile openssl.cnf -out server_enc.crt -CAcreateserial\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#client\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -genkey -name SM2 -out client.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -config openssl.cnf -new -subj /C\u003cspan class=\"o\"\u003e=\u003c/span\u003eCN/ST\u003cspan class=\"o\"\u003e=\u003c/span\u003eBJ/L\u003cspan class=\"o\"\u003e=\u003c/span\u003eHaiDian/O\u003cspan class=\"o\"\u003e=\u003c/span\u003eYUNHEENMO/OU\u003cspan class=\"o\"\u003e=\u003c/span\u003eMogDB/CN\u003cspan class=\"o\"\u003e=\u003c/span\u003eclient -key client.key -out client.csr\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -sm3 -req -days \u003cspan class=\"m\"\u003e1500\u003c/span\u003e -in client.csr -CA CA.crt -CAkey CA.key -extfile openssl.cnf -out client.crt -CAcreateserial\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#client_enc\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -genkey -name SM2 -out client_enc.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -config openssl.cnf -new -subj /C\u003cspan class=\"o\"\u003e=\u003c/span\u003eCN/ST\u003cspan class=\"o\"\u003e=\u003c/span\u003eBJ/L\u003cspan class=\"o\"\u003e=\u003c/span\u003eHaiDian/O\u003cspan class=\"o\"\u003e=\u003c/span\u003eYUNHEENMO/OU\u003cspan class=\"o\"\u003e=\u003c/span\u003eMogDB/CN\u003cspan class=\"o\"\u003e=\u003c/span\u003eclient -key client_enc.key -out client_enc.csr\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl x509 -sm3 -req -days \u003cspan class=\"m\"\u003e1500\u003c/span\u003e -in client_enc.csr -CA CA.crt -CAkey CA.key -extfile openssl.cnf -out client_enc.crt -CAcreateserial\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#修改权限\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod \u003cspan class=\"m\"\u003e0600\u003c/span\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#增加密码保护\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ec -sm4 -in server.key  -out server.key  -passout pass:123qweQWE\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc generate -S 123qweQWE -D ./  -o  server\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ec -sm4 -in server_enc.key  -out server_enc.key  -passout pass:234werWER\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc generate -S 234werWER -D ./  -o server_enc\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ec -sm4 -in client.key  -out client.key  -passout pass:345ertERT\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc generate -S 345ertERT -D ./  -o client\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ec -sm4 -in client_enc.key  -out client_enc.key  -passout pass:456rtyRTY\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc generate -S 456rtyRTY -D ./  -o client_enc\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod \u003cspan class=\"m\"\u003e0600\u003c/span\u003e *\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#客户端：\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCERT\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport CERT=`pwd`\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLMODE=verify-ca\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLTLCP=1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLROOTCERT=$CERT/CA.crt\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLKEY=$CERT/client.key\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLCERT=$CERT/client.crt\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLENCKEY=$CERT/client_enc.key\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003eexport PGSSLENCCERT=$CERT/client_enc.crt\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u003c/span\u003e \u0026gt; client_env\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003esource\u003c/span\u003e client_env\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e#服务器：\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl=on\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_ciphers = \u0026#39;ALL\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_use_tlcp=on\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_ca_file = \u0026#39;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$CERT\u003c/span\u003e\u003cspan class=\"s2\"\u003e/CA.crt\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_key_file=\u0026#39;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$CERT\u003c/span\u003e\u003cspan class=\"s2\"\u003e/server.key\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_cert_file=\u0026#39;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$CERT\u003c/span\u003e\u003cspan class=\"s2\"\u003e/server.crt\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_enc_key_file=\u0026#39;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$CERT\u003c/span\u003e\u003cspan class=\"s2\"\u003e/server_enc.key\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/data -c \u003cspan class=\"s2\"\u003e\u0026#34;ssl_enc_cert_file=\u0026#39;\u003c/span\u003e\u003cspan class=\"nv\"\u003e$CERT\u003c/span\u003e\u003cspan class=\"s2\"\u003e/server_enc.crt\u0026#39;\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e1、生成国密证书\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 创建 CA 目录 cadir 并进入\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# copy 配置文件 openssl.cnf 到当前目录（不同环境，配置文件路径可能不一样）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp /etc/pki/tls/openssl.cnf .\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 开始搭建CA环境\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir ./demoCA ./demoCA/newcerts ./demoCA/private\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod \u003cspan class=\"m\"\u003e777\u003c/span\u003e ./demoCA/private\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 创建serial文件,写入01\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;01\u0026#39;\u003c/span\u003e\u0026gt;./demoCA/serial\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 创建文件index.txt\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etouch ./demoCA/index.txt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 至此CA环境搭建完成\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 生成CA私钥\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -out demoCA/private/cakey.pem -name SM2 -genkey\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 生成根证书请求文件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -config openssl.cnf -key demoCA/private/cakey.pem -new -out cacert.req\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 生成自签发根证书\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 生成根证书时，需要修改openssl.cnf文件，设置basicConstraints=CA:TRUE\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evi openssl.cnf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 生成CA自签发根证书\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ca -config openssl.cnf -in cacert.req -keyfile demoCA/private/cakey.pem -selfsign -out demoCA/cacert.pem\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 生成服务器私钥文件server.key\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -out server.key -name SM2 -genkey\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 生成服务器证书请求文件server.req\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -config openssl.cnf -key server.key -new -out server.req\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 生成服务端/客户端证书时，修改openssl.cnf文件，设置basicConstraints=CA:FALSE\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evi openssl.cnf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 对生成的服务器证书请求文件进行签发，签发后将生成正式的服务器证书server.crt\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ca -config openssl.cnf -in server.req -out server.crt -days \u003cspan class=\"m\"\u003e3650\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 生成客户端私钥\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ecparam -out client.key -name SM2 -genkey\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 生成客户端证书请求文件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl req -config openssl.cnf -new -key client.key -out client.req\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 对生成的客户端证书请求文件进行签发，签发后将生成正式的客户端证书client.crt\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eopenssl ca -config openssl.cnf -in client.req -out client.crt -days \u003cspan class=\"m\"\u003e3650\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 注：中间会产生交互，按照以下内容进行填写（需注意每个交互的common name填不一样的内容，如分别写：test1,test2,test3）：\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eCountry Name \u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e letter code\u003cspan class=\"o\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003eAU\u003cspan class=\"o\"\u003e]\u003c/span\u003e:CN\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eState or Province Name \u003cspan class=\"o\"\u003e(\u003c/span\u003efull name\u003cspan class=\"o\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003eSome-State\u003cspan class=\"o\"\u003e]\u003c/span\u003e:shanxi\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eLocality Name \u003cspan class=\"o\"\u003e(\u003c/span\u003eeg, city\u003cspan class=\"o\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e[]\u003c/span\u003e:xian\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eOrganization Name \u003cspan class=\"o\"\u003e(\u003c/span\u003eeg, company\u003cspan class=\"o\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003eInternet Widgits Pty Ltd\u003cspan class=\"o\"\u003e]\u003c/span\u003e:Abc\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eOrganizational Unit Name \u003cspan class=\"o\"\u003e(\u003c/span\u003eeg, section\u003cspan class=\"o\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e[]\u003c/span\u003e:hello\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--Common Name可以随意命名\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eCommon Name \u003cspan class=\"o\"\u003e(\u003c/span\u003eeg, YOUR name\u003cspan class=\"o\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e[]\u003c/span\u003e:world\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--Email可以选择性填写\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eEmail Address \u003cspan class=\"o\"\u003e[]\u003c/span\u003e:\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ePlease enter the following \u003cspan class=\"s1\"\u003e\u0026#39;extra\u0026#39;\u003c/span\u003e attributes\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eto be sent with your certificate request\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eA challenge password \u003cspan class=\"o\"\u003e[]\u003c/span\u003e: 1qaz!QAZ\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eAn optional company name \u003cspan class=\"o\"\u003e[]\u003c/span\u003e:world\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e2、配置客户端文件\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod \u003cspan class=\"m\"\u003e600\u003c/span\u003e client.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod \u003cspan class=\"m\"\u003e600\u003c/span\u003e client.crt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod \u003cspan class=\"m\"\u003e600\u003c/span\u003e ./demoCA/cacert.pem\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod \u003cspan class=\"m\"\u003e600\u003c/span\u003e server.key\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003echmod \u003cspan class=\"m\"\u003e600\u003c/span\u003e server.crt\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e3、配置服务器端参数\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp server.crt server.key ./demoCA/cacert.pem \u003cspan class=\"nv\"\u003e$PGDATA\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp client.crt client.key /home/vastbase/data/vastbase/\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003ePGSSLCERT\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;/home/vastbase/cadir/client.crt\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003ePGSSLKEY\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;/home/vastbase/cadir/client.key\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003ePGSSLMODE\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;verify-ca\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003ePGSSLROOTCERT\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;/home/vastbase/data/vastbase/cacert.pem\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evi postgresql.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003essl\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e on\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003erequire_ssl\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e on\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003essl_cert_file\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;server.crt\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003essl_key_file\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;server.key\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003essl_ca_file\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;cacert.pem\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nv\"\u003essl_crl_file\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s1\"\u003e\u0026#39;\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e4、配置客户端认证方式\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evi pg_hba.conf\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ehostssl all all 0.0.0.0/0 cert\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e5、重启数据库服务\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_ctl restart\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql - vastbase -r\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--创建生成客户端证书时Common Name同名用户\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecreate user test3 password\u003cspan class=\"s1\"\u003e\u0026#39;Test@123\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e1、客户端vsql连接到服务端\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evsql -dvastbase -r -h IP -U test3\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--预期\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e连接成功，提示SSL connection\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"1-需求背景\"\u003e1 需求背景\u003c/h1\u003e\n\u003ch2 id=\"12-oracle-profile功能\"\u003e1.2 Oracle Profile功能\u003c/h2\u003e\n\u003ch3 id=\"一查看profile信息\"\u003e一、查看profile信息\u003c/h3\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e设置sqlplus输出格式\u003c/p\u003e","title":"vastbase 身份认证"},{"content":"1 需求背景 1.1 数据加密背景 加密的原理\n不同场景中，适合的加密算法类型不同。对存储数据加密，通常采用对称密码算法，此处主要介绍对称密码算法：\n加密原理：输入1个明文，输入1个密钥，对明文和密钥进行一些运算（比如异或，代换），可得到1个密文。密钥通常是随机生成的。 加密算法：DES算法，发布于1977年，已确定为不安全加密算法。3DES算法，调用3次DES算法，生成3个密钥，安全性与DES差别不大，也属于不安全的加密算法。AES算法，发布于2001年，通用的国际标准 数据库加密函数\n几乎所有数据库，都提供内置加密函数，让用户通过SQL语句调用。最典型的场景如下：\n-- 假设，数据库提供函数encrypt(明文，密钥，加密算法)，输出为密文 -- 用户想表\u0026#39;t1\u0026#39;中存储数据\u0026#39;shenkun\u0026#39;，则存储的语法如下：（用户自己保管密钥） INSERT INTO t1 VALUES (encrypt(\u0026#39;shenkun\u0026#39;, \u0026#39;一串随机的密钥\u0026#39;, \u0026#39;aes\u0026#39;)); 1.2 oracle 加密包 早期版本的oracle中，包含1个名为dbms_obfuscation_toolkit的包，提供7个函数，主要实现加密、解密等功能：\n版本信息：oracle 8i版本开始提供，oracle 10g版本开始不被推荐使用，由dbms_crypto代替，oracle 21c版本正式移除 函数列表： 生成随机数：desgetkey(seed) -\u0026gt; key 加密：desencrypt(input, key) -\u0026gt; encrypted_data 解密：descdecrypt(input, key) -\u0026gt; decrypted_data 生成随机数：des3getkey(which=\u0026gt;0, seed) -\u0026gt; key 加密：des3encrypt(input, key, which=\u0026gt;0, iv=\u0026gt;012345678abcdef) -\u0026gt; encrypted_data 解密：des3decrypt(input, key, which=\u0026gt;0, iv=\u0026gt;012345678abcdef) -\u0026gt; decrypted_data 哈希：md5(input) -\u0026gt; checksum 函数参数：函数参数有3种数据类型：varchar2, raw。与raw类型相比，如果是varchar2类型，参数名需加上_string后缀。比如，raw类型的入参名为input，则varcha2类型入参名为input_string 函数限制： desgetkey：seed长度最短为80字节 desencrypt：input长度是8字节的整数倍；key最短为8字节，超过8字节的部分被丢弃 descdecrypt：input长度是8字节的整数倍；key最短为8字节，超过8字节的部分被丢弃 des3getkey: seed长度最短为80字节 des3encrypt：input长度是8字节的整数倍；which为0时，key最短为16字节，超过16字节的部分被丢弃；which为1时，key最短为24字节，超过24字节的部分被丢弃 des3dencrypt：input长度是8字节的整数倍；which为0时，key最短为16字节，超过16字节的部分被丢弃；which为1时，key最短为24字节，超过24字节的部分被丢弃 md5：无 参考文档 函数介绍：函数背景、注意事项等：https://docs.oracle.com/cd/A97630_01/appdev.920/a96590/adgsec04.htm 函数参数：参数类型、调用示例等：https://docs.oracle.com/cd/B10500_01/appdev.920/a96612/d_obtoo2.htm 以下是上述函数的调用示例：\n创建辅助函数\n简单封住数据类型转换函数，方便阅读函数：\nCREATE FUNCTION strtoraw(string VARCHAR2) RETURN RAW IS BEGIN RETURN utl_raw.cast_to_raw(string); END; / CREATE FUNCTION rawtostr(rawdata RAW) RETURN VARCHAR2 IS BEGIN RETURN utl_raw.cast_to_varchar2(rawdata); END; / DES生成密钥\nSELECT dbms_obfuscation_toolkit.desgetkey(seed=\u0026gt;strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;)) FROM dual; -- seed最短长度为80字节，每次输出的值都是随机的，长度为8字节 DES加密\nSELECT dbms_obfuscation_toolkit.desencrypt(input=\u0026gt;strtoraw(\u0026#39;1111111111111111\u0026#39;), key=\u0026gt;strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 输出 655EA628CF62585F20D3B8A6E657876B DES解密\nSELECT rawtostr(dbms_obfuscation_toolkit.desdecrypt(input=\u0026gt;hextoraw(\u0026#39;655EA628CF62585F20D3B8A6E657876B\u0026#39;), key=\u0026gt;strtoraw(\u0026#39;11111111\u0026#39;))) FROM dual; -- 输出 1111111111111111 3DES生成密钥\nSELECT dbms_obfuscation_toolkit.des3getkey(which=\u0026gt;0, seed=\u0026gt;strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;)) FROM dual; -- seed最短长度为80字节，每次输出的值都是随机的，which=0，输出16字节，which=1，输出24字节 3DES加密\nSELECT dbms_obfuscation_toolkit.des3encrypt(input=\u0026gt;strtoraw(\u0026#39;1111111111111111\u0026#39;), key=\u0026gt;strtoraw(\u0026#39;1111111122222222\u0026#39;), which=\u0026gt;0, iv=\u0026gt;strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 输出 0D28E17571051319ACCE2D19D9AED5C8 3DES解密\nSELECT rawtostr(dbms_obfuscation_toolkit.des3decrypt(input=\u0026gt;hextoraw(\u0026#39;0D28E17571051319ACCE2D19D9AED5C8\u0026#39;), key=\u0026gt;strtoraw(\u0026#39;1111111122222222\u0026#39;), which=\u0026gt;0, iv=\u0026gt;strtoraw(\u0026#39;11111111\u0026#39;))) FROM dual; -- 输出 1111111111111111 MD5哈希\nSELECT dbms_obfuscation_toolkit.md5(input=\u0026gt;strtoraw(\u0026#39;1111111111111111\u0026#39;)) FROM dual; -- 输出 FA1D3EB08A879DE9A4CD9995A1AA91E1 1.3 vasebase 加密包（旧版本） vastbase也提供dbms_obfuscation_toolkit包，代码在4年前或更早前合入，函数个数，函数名，函数参数等与oracle保持一致：\n函数列表： 生成随机数：desgetkey(seed) -\u0026gt; key 加密：desencrypt(input, key) -\u0026gt; encrypted_data 解密：descdecrypt(input, key) -\u0026gt; decrypted_data 生成随机数：des3getkey(seed) / des3getkey(which, seed) -\u0026gt; key 加密：des3encrypt(input, key, which = 0) / des3encrypt(input, key, iv) / des3encrypt(input, key, which, iv) -\u0026gt; encrypted_data 解密：des3decrypt(input, key, which = 0) / des3decrypt(input, key, iv) / des3decrypt(input, key, which, iv) -\u0026gt; encrypted_data -\u0026gt; decrypted_data 哈希：md5(input) -\u0026gt; checksum 函数参数：函数参数有3种数据类型: text, bytea, raw 以下是上述函数的调用示例：\n创建辅助函数与安装加密插件\n简单封住数据类型转换函数，方便阅读函数：\nCREATE FUNCTION strtoraw(string VARCHAR2) RETURN RAW IS BEGIN RETURN utl_raw.cast_to_raw(string); END; / CREATE FUNCTION rawtostr(rawdata RAW) RETURN VARCHAR2 IS BEGIN RETURN utl_raw.cast_to_varchar2(rawdata); END; / -- 安装加解密插件 CREATE EXTENSION pgcrypto; DES生成密钥\nSELECT dbms_obfuscation_toolkit.desgetkey(strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;)) FROM dual; -- seed最短长度为80字节，每次输出的值都是随机的，长度为8字节 DES加密\nSELECT dbms_obfuscation_toolkit.desencrypt(strtoraw(\u0026#39;1111111111111111\u0026#39;), strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 输出 (vastbase) 5A56366D4B4D3969574638673037696D356C65486138A7616167394370743236 -- 输出（oracle） 655EA628CF62585F20D3B8A6E657876B DES解密\nSELECT rawtostr(dbms_obfuscation_toolkit.desdecrypt(hextoraw(\u0026#39;655EA628CF62585F20D3B8A6E657876B\u0026#39;), strtoraw(\u0026#39;11111111\u0026#39;))) FROM dual; -- 输出 (vastbase) ERROR: invalid symbol -- 输出（oracle） 1111111111111111 3DES生成密钥\nSELECT dbms_obfuscation_toolkit.des3getkey(0, strtoraw(\u0026#39;11111111112222222222333333333344444444445555555555666666666677777777778888888888\u0026#39;)) FROM dual; -- seed最短长度为80字节，每次输出的值都是随机的，which=0，输出16字节，which=1，输出24字节 3DES加密\nSELECT dbms_obfuscation_toolkit.des3encrypt(strtoraw(\u0026#39;1111111111111111\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;), 0, strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 输出 (vastbase) 4F7A53663334507232592F3542747033644975635673765966543477414C5737 -- 输出（oracle） 0D28E17571051319ACCE2D19D9AED5C8 3DES解密\nSELECT rawtostr(dbms_obfuscation_toolkit.des3decrypt(hextoraw(\u0026#39;0D28E17571051319ACCE2D19D9AED5C8\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;), 0, strtoraw(\u0026#39;11111111\u0026#39;))) FROM dual; -- 输出 (vastbase) ERROR: invalid symbol -- 输出（oracle） 1111111111111111 MD5哈希\nSELECT dbms_obfuscation_toolkit.md5(strtoraw(\u0026#39;1111111111111111\u0026#39;)) FROM dual; -- 输出 FA1D3EB08A879DE9A4CD9995A1AA91E1 1.4 需求目标 需求场景 以前，客户使用oracle，并通过dbms_obfuscation_toolkit插件加密存储数据。现在，客户使用vastbase，并将数据迁移到vastbase中，包括以前由dbms_obfuscation_toolkit插件加密后的数据。在该场景中，需要满足2个要求：\n解密旧数据：oracle加密数据，将密文迁移至vasebase，vastbase可解密迁移来的密文 加密新数据：客户系统中，vastbase与oracle混用，在数据库运维、数据共享等场景中，确保多个系统中数据一致，存在加密新数据的场景 需求背景 早在4年前，vastbase也提供了dbms_obfuscation_toolkit包，该包提供7个函数，函数名与函数参数个数与oracle一致。\n但是，实际使用过程中，这7个函数与oracle的函数存在一些差异，在上述场景中，该差异可能导致客户应用不可用。\n函数输出不一致：比如，相同的加密函数、明文、密钥、加密算法，vastbase与oracle的输出内容、输出长度不一致。 示例：desencrypt()函数，加密16字节，oracle密文为16字节，vastbase密文为32字节，vastbase的密文中，会携带分组填充，并且以base64编码 参数约束不一致：比如，相同的加密函数，vastbase与oracle的参数长度限制不一致 需求目标 为解决上述问题，本版本的vastbase需达到以下要求：\n加密函数输出结果与oracle一致 解密函数输出结果与oracle一致 函数参数约束与oracle一致 保持前向兼容，即可解密旧版本vastbase加密的结果（需用户主动控制加密函数的版本） 相关问题 bytea特殊字符转换\n将text转换为bytea的过程中，可能出现text被阶段的问题。\n比如一串text数据abc\\0cd，长度为6，转换为bytea的过程为：先将text转换为cstring，再讲csting转换为bytea，由于cstring无法携带数据长度，所以，csting转换为bytea时，根据\\0来判断数据结尾。\nSELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;) FROM dual; -- 预期输出：8字节，实际输出：3字节 des3encrypt ------------ @jx SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;)::bytea FROM dual; -- 预期输出：8字节，实际输出：4字节（oracle无bytea类型） des3encrypt ------------ \\x40826a58 SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;::bytea, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;) FROM dual; des3encrypt ------------------- \\x40826a5800608c87 SELECT utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;)); des3encrypt ------------------- 40826A5800608C87 在实际使用场景中，示例如下：\nCREATE TABLE t1 (c1 TEXT, c2 BYTEA, c3 RAW, c4 BYTEA); -- 加密 INSERT INTO t1 VALUES ( dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;), dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;)::bytea, utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;)), dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;::bytea, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;) ); SELECT * FROM t1; c1 | c2 | c3 | c4 -----+------------+------------------+-------------------- @jx | \\x40826a58 | 40826A5800608C87 | \\x40826a5800608c87 -- 解密 SELECT dbms_obfuscation_toolkit.des3decrypt(c1, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;) FROM t1; SELECT dbms_obfuscation_toolkit.des3decrypt(c2, \u0026#39;1111111111111111\u0026#39;::bytea, 0, \u0026#39;11111111\u0026#39;::bytea) FROM t1; -- 解密失败 SELECT dbms_obfuscation_toolkit.des3decrypt(c3, utl_raw.cast_to_raw(\u0026#39;1111111111111111\u0026#39;), 0, utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;)) FROM t1; SELECT dbms_obfuscation_toolkit.des3decrypt(c4, \u0026#39;1111111111111111\u0026#39;, 0, \u0026#39;11111111\u0026#39;) FROM t1; 上述场景中，该问题的规避方法是，建议用户手动强制将入参函数的类型转换为bytea类型。\n但是，如果用户没有规避，可能会导致c2列解密失败，因此，只能考虑直接禁用bytea类型。可以考虑解决text转bytea的阶段问题，但该问题是公共问题，且影响范围大，本版本来不及解决。\noracle只有raw类型，无bytea类型。\nCREATE TABLE t1 (c1 VARCHAR2(100), c2 RAW(100), c3 RAW(100)); -- 加密 INSERT INTO t1 VALUES ( dbms_obfuscation_toolkit.des3encrypt(input_string=\u0026gt;\u0026#39;11111111\u0026#39;, key_string=\u0026gt;\u0026#39;1111111111111111\u0026#39;, which=\u0026gt;0, iv_string=\u0026gt;\u0026#39;11111111\u0026#39;), utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(input_string=\u0026gt;\u0026#39;11111111\u0026#39;, key_string=\u0026gt;\u0026#39;1111111111111111\u0026#39;, which=\u0026gt;0, iv_string=\u0026gt;\u0026#39;11111111\u0026#39;)), dbms_obfuscation_toolkit.des3encrypt(input=\u0026gt;utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;), key=\u0026gt;utl_raw.cast_to_raw(\u0026#39;1111111111111111\u0026#39;), which=\u0026gt;0, iv=\u0026gt;utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;)) ); SELECT * FROM t1; raw类型自动转换\nvastbase的::raw实现与utl_raw.cast_to_raw不一致\nSELECT dbms_obfuscation_toolkit.desencrypt(utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;), utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 输出 655EA628CF62585F SELECT dbms_obfuscation_toolkit.desencrypt(\u0026#39;11111111\u0026#39;::raw, \u0026#39;11111111\u0026#39;::raw) FROM dual; -- 底层的加解密函数中，输入的长度变成了4字节，输出结果与上面不一致 SELECT utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;) FROM dual; -- 输出 3131313131313131 SELECT \u0026#39;11111111\u0026#39;::raw FROM dual; -- 输出 1111111 oracle无::raw用法\nSELECT dbms_obfuscation_toolkit.desencrypt(input=\u0026gt;utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;), key=\u0026gt;utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 输出 655EA628CF62585F SELECT utl_raw.cast_to_raw(\u0026#39;11111111\u0026#39;) FROM dual; -- 输出 3131313131313131 需求实现 为实现上述目标，主要的工作量如下：\n加密算法：黑盒识别oracle的des与3des算法的具体实现，包括分组加密模式、分组填充、默认IV值等，确保新版本vastbase的输出与oracle一致 数据类型：分析不同类型数据之间的相互转换，比如oracle的[varchar2, raw]，vastbase的[text, bytea, raw] 前向兼容：识别旧版本vastbase的des与3des算法的具体实现，包括分组加密模式、分组填充、默认IV值、输出输出编码解码等，避免新版本vastbase无法解密旧版本vastbase加密的数据 报错信息：旧版本vastbase对异常入参的报错信息较模糊 代码质量：旧版本vastbase的加解密函数不符合cleancode规范，参数命名较模糊 需求约束 插件版本：安装dbms_obfuscation_toolkit插件时，默认安装新版本插件，如需使用旧版本插件，需主动指定旧版本。新版本插件与旧版本插件不兼容 解释：vastbase旧版本（本需求交付前的版本）插件的加密结果与oracle不一致，vastbase新版本（本需求交付的版本）插件的加密结果与oracle保持一致，因此，vastbase的新版本插件无法解密旧版本插件加密的数据。加密结果中，并没有存储版本号，即无法自动识别加密结果的版本 数据类型：使用dbms_obfuscation_toolkit插件时，加密与解密函数中，参数类型支持text或raw类型，不支持bytea类型 解释：oracle仅支持text和raw类型，无bytea类型。vastbase旧版本插件支持bytea类型，但是，text转bytea时存在截断的公共问题，本版本无法解决，因此，本版本无法支持bytea类型 函数入参： 编号 函数 参数 oracle约束 vasebase约束（旧版本） vasebase约束（新版本） 1 desgetkey(seed) seed 长度为[80, max]字节 长度为[0, max]字节 与oracle一致 2 des3getkey(which, seed) seed 长度为[80, max]字节 长度为[0, max]字节 与oracle一致 3 desencrypt(input, key) input 长度为8字节整数倍 长度为[0, max]字节 与oracle一致 4 desencrypt(input, key) key 长度为[8, max] 字节 长度为[0, max]字节 与oracle一致 5 desdecrypt(input, key) input 长度为8字节整数倍 长度为[0, max] 与oracle一致 6 desdecrypt(input, key) key 长度为[8, max] 字节 长度为[0, max]字节 与oracle一致 7 des3encrypt(input, key, which=0，iv) input 长度为8字节整数倍 长度为[0, max]字节 与oracle一致 8 des3encrypt(input, key, which=0，iv) key which=0，key长度[16, max]字节；which=1，key长度[24, max]字节 which=0，key长度[16, max]字节，前8字节与后8字节不能一致。which=1，key长度[24, max]字节，前，中，后8字节不能一致 与oracle一致 9 des3encrypt(input, key, which=0，iv) which 0或1 所有整数，除0和1，其他整数与0效果一致 与oracle一致 10 des3encrypt(input, key, which=0，iv) iv 长度为8字节整数倍 长度为[0, max]字节 与oracle一致 11 des3encrypt(input, key, which=0，iv) input 长度为8字节整数倍 长度为[0, max]字节 与oracle一致 12 des3decrypt(input, key, which=0，iv) key which=0，key长度[16, max]字节；which=1，key长度[24, max]字节 which=0，key长度[16, max]字节，前8字节与后8字节不能一致。which=1，key长度[24, max]字节，前，中，后8字节不能一致 与oracle一致 13 des3decrypt(input, key, which=0，iv) which 0或1 所有整数，除0和1，其他整数与0效果一致 与oracle一致 14 des3decrypt(input, key, which=0，iv) iv 长度为8字节整数倍 长度为[0, max]字节 与oracle一致 2 需求分析 2.1 主成功场景 一、安装不同版本的pgcrypto 查看pgcrypto可用的版本\nSELECT * FROM pg_available_extension_versions WHERE name = \u0026#39;pgcrypto\u0026#39;; -- 预期输出 可用版本包括1.2和2.0 安装pgcrypto-2.0版本\nCREATE EXTENSION pgcrypto; SELECT * FROM pg_extension WHERE extname = \u0026#39;pgcrypto\u0026#39;; -- 预期输出 默认版本为 2.0 -- 源码中，有pgcrypto.control控制 DROP EXTENSION pgcrypto; 安装pgcrypto-1.2版本\nCREATE EXTENSION pgcrypto WITH VERSION \u0026#39;1.2\u0026#39;;; SELECT * FROM pg_extension WHERE extname = \u0026#39;pgcrypto\u0026#39;; -- 预期输出 版本为 1.2 DROP EXTENSION pgcrypto; 从pgcrypto-2.0降级为pgcrypto-1.2\nCREATE EXTENSION pgcrypto; ALTER EXTENSION pgcrypto UPDATE TO \u0026#39;1.2\u0026#39;; SELECT * FROM pg_extension WHERE extname = \u0026#39;pgcrypto\u0026#39;; -- 预期输出 版本为 1.2 DROP EXTENSION pgcrypto; 从pgcrypto-1.2升级为pgcrypto-2.0\nCREATE EXTENSION pgcrypto WITH VERSION \u0026#39;1.2\u0026#39;;; ALTER EXTENSION pgcrypto UPDATE TO \u0026#39;2.0\u0026#39;; SELECT * FROM pg_extension WHERE extname = \u0026#39;pgcrypto\u0026#39;; -- 预期输出 版本为 2.0 DROP EXTENSION pgcrypto; 二、dbms_obfuscation_toolkit函数基本功能 客户核心需求是，在dbms_obfuscation_toolkit中，加密函数与解密函数与oracle保持一致。即本场景为核心场景。\ndes加密函数\n首先，简单封装2个数据类型转换函数，方便阅读SQL语句\nCREATE FUNCTION strtoraw(string VARCHAR2) RETURN RAW IS BEGIN RETURN utl_raw.cast_to_raw(string); END; / CREATE FUNCTION rawtostr(rawdata RAW) RETURN VARCHAR2 IS BEGIN RETURN utl_raw.cast_to_varchar2(rawdata); END; / 本场景中，预期输出需与oracle保持一致\n-- 安装加解密插件 CREATE EXTENSION pgcrypto; SELECT dbms_obfuscation_toolkit.desencrypt(strtoraw(\u0026#39;1111111111111111\u0026#39;), strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 预期输出 655EA628CF62585F20D3B8A6E657876B des解密函数\n本场景中，预期输出需与oracle保持一致\nSELECT rawtostr(dbms_obfuscation_toolkit.desdecrypt(hextoraw(\u0026#39;655EA628CF62585F20D3B8A6E657876B\u0026#39;), strtoraw(\u0026#39;11111111\u0026#39;))) FROM dual; -- 预期输出 1111111111111111 3des加密函数\n本场景中，预期输出需与oracle保持一致\nSELECT dbms_obfuscation_toolkit.des3encrypt(strtoraw(\u0026#39;1111111111111111\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;), 0, strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; -- 预期输出 0D28E17571051319ACCE2D19D9AED5C8 3des解密函数\n本场景中，预期输出需与oracle保持一致\nSELECT rawtostr(dbms_obfuscation_toolkit.des3decrypt(hextoraw(\u0026#39;0D28E17571051319ACCE2D19D9AED5C8\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;), 0, strtoraw(\u0026#39;11111111\u0026#39;))) FROM dual; -- 预期输出 1111111111111111 3des加密函数iv为空\n本场景中，预期输出需与oracle保持一致\nSELECT dbms_obfuscation_toolkit.des3encrypt(strtoraw(\u0026#39;1111111111111111\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;)) FROM dual; -- 预期输出 7934131269E334A2BCC64878CC5A075A 3des解密函数iv为空\n本场景中，预期输出需与oracle保持一致\nSELECT rawtostr(dbms_obfuscation_toolkit.des3decrypt(hextoraw(\u0026#39;7934131269E334A2BCC64878CC5A075A\u0026#39;), strtoraw(\u0026#39;1111111122222222\u0026#39;))) FROM dual; -- 预期输出 1111111111111111 三、dbms_obfuscation_toolkit函数不同入参 des加密超长数据\n首先，创建1个表存储加解密结果\nCREATE TABLE plain (c1 RAW); CREATE TABLE cipher (c1 RAW); 此处，待加密的数据长度为80000字节\nINSERT INTO plain VALUES (strtoraw(repeat(\u0026#39;0123456789\u0026#39;, 8000))); INSERT INTO CIPHER VALUES (dbms_obfuscation_toolkit.desencrypt(strtoraw(repeat(\u0026#39;0123456789\u0026#39;, 8000)), strtoraw(\u0026#39;11111111\u0026#39;))); SELECT length(c1) FROM plain; SELECT length(c1) FROM cipher; SELECT (SELECT c1 FROM plain) = (SELECT c1 FROM cipher); -- 预期输出 f des解密超长数据\nSELECT (SELECT c1 FROM plain) = (SELECT dbms_obfuscation_toolkit.desdecrypt(c1, strtoraw(\u0026#39;11111111\u0026#39;))FROM cipher); -- 预期输出 t TRUNCATE plain; TRUNCATE cipher; 3des加密超长数据\nINSERT INTO plain VALUES (strtoraw(repeat(\u0026#39;0123456789\u0026#39;, 8000))); INSERT INTO CIPHER VALUES (dbms_obfuscation_toolkit.des3encrypt(strtoraw(repeat(\u0026#39;0123456789\u0026#39;, 8000)), strtoraw(\u0026#39;1111111122222222\u0026#39;), 0, strtoraw(\u0026#39;11111111\u0026#39;))); SELECT length(c1) FROM plain; SELECT length(c1) FROM cipher; SELECT (SELECT c1 FROM plain) = (SELECT c1 FROM cipher); -- 预期输出 f 3des解密超长数据\nSELECT (SELECT c1 FROM plain) = (SELECT dbms_obfuscation_toolkit.des3decrypt(c1, strtoraw(\u0026#39;1111111122222222\u0026#39;), 0, strtoraw(\u0026#39;11111111\u0026#39;)) FROM cipher); -- 预期输出 t DROP TABLE plain; DROP TABLE cipher; 3des中keymode参数为1\nSELECT dbms_obfuscation_toolkit.des3encrypt(strtoraw(\u0026#39;1111111111111111\u0026#39;), strtoraw(\u0026#39;111111112222222233333333\u0026#39;), 1, strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; SELECT dbms_obfuscation_toolkit.des3decrypt(hextoraw(\u0026#39;7934131269E334A2BCC64878CC5A075A\u0026#39;), strtoraw(\u0026#39;111111112222222233333333\u0026#39;), 1, strtoraw(\u0026#39;11111111\u0026#39;)) FROM dual; 四、 附录 使用bytea加密 DES加密\nSELECT dbms_obfuscation_toolkit.desencrypt(\u0026#39;1111111111111111\u0026#39;::bytea, \u0026#39;11111111\u0026#39;::bytea); -- 输出 \\x655EA628CF62585F20D3B8A6E657876B DES解密\nSELECT convert_from(dbms_obfuscation_toolkit.desdecrypt(\u0026#39;\\x655EA628CF62585F20D3B8A6E657876B\u0026#39;::bytea, \u0026#39;11111111\u0026#39;::bytea), \u0026#39;UTF8\u0026#39;); -- 输出 1111111111111111 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/vastbase-encrypt/","summary":"\u003ch1 id=\"1-需求背景\"\u003e1 需求背景\u003c/h1\u003e\n\u003ch2 id=\"11-数据加密背景\"\u003e1.1 数据加密背景\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e加密的原理\u003cbr\u003e\n不同场景中，适合的加密算法类型不同。对存储数据加密，通常采用对称密码算法，此处主要介绍对称密码算法：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e加密原理：输入1个明文，输入1个密钥，对明文和密钥进行一些运算（比如异或，代换），可得到1个密文。密钥通常是随机生成的。\u003c/li\u003e\n\u003cli\u003e加密算法：DES算法，发布于1977年，已确定为不安全加密算法。3DES算法，调用3次DES算法，生成3个密钥，安全性与DES差别不大，也属于不安全的加密算法。AES算法，发布于2001年，通用的国际标准\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e数据库加密函数\u003cbr\u003e\n几乎所有数据库，都提供内置加密函数，让用户通过SQL语句调用。最典型的场景如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 假设，数据库提供函数encrypt(明文，密钥，加密算法)，输出为密文\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 用户想表\u0026#39;t1\u0026#39;中存储数据\u0026#39;shenkun\u0026#39;，则存储的语法如下：（用户自己保管密钥）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eencrypt\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;shenkun\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;一串随机的密钥\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aes\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"12-oracle-加密包\"\u003e1.2 oracle 加密包\u003c/h2\u003e\n\u003cp\u003e早期版本的oracle中，包含1个名为dbms_obfuscation_toolkit的包，提供7个函数，主要实现加密、解密等功能：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e版本信息：oracle 8i版本开始提供，oracle 10g版本开始不被推荐使用，由dbms_crypto代替，oracle 21c版本正式移除\u003c/li\u003e\n\u003cli\u003e函数列表：\n\u003cul\u003e\n\u003cli\u003e生成随机数：desgetkey(seed) -\u0026gt; key\u003c/li\u003e\n\u003cli\u003e加密：desencrypt(input, key) -\u0026gt; encrypted_data\u003c/li\u003e\n\u003cli\u003e解密：descdecrypt(input, key) -\u0026gt; decrypted_data\u003c/li\u003e\n\u003cli\u003e生成随机数：des3getkey(which=\u0026gt;0, seed) -\u0026gt; key\u003c/li\u003e\n\u003cli\u003e加密：des3encrypt(input, key, which=\u0026gt;0, iv=\u0026gt;012345678abcdef) -\u0026gt; encrypted_data\u003c/li\u003e\n\u003cli\u003e解密：des3decrypt(input, key, which=\u0026gt;0, iv=\u0026gt;012345678abcdef) -\u0026gt; decrypted_data\u003c/li\u003e\n\u003cli\u003e哈希：md5(input) -\u0026gt; checksum\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e函数参数：函数参数有3种数据类型：varchar2, raw。与raw类型相比，如果是varchar2类型，参数名需加上_string后缀。比如，raw类型的入参名为input，则varcha2类型入参名为input_string\u003c/li\u003e\n\u003cli\u003e函数限制：\n\u003cul\u003e\n\u003cli\u003edesgetkey：seed长度最短为80字节\u003c/li\u003e\n\u003cli\u003edesencrypt：input长度是8字节的整数倍；key最短为8字节，超过8字节的部分被丢弃\u003c/li\u003e\n\u003cli\u003edescdecrypt：input长度是8字节的整数倍；key最短为8字节，超过8字节的部分被丢弃\u003c/li\u003e\n\u003cli\u003edes3getkey: seed长度最短为80字节\u003c/li\u003e\n\u003cli\u003edes3encrypt：input长度是8字节的整数倍；which为0时，key最短为16字节，超过16字节的部分被丢弃；which为1时，key最短为24字节，超过24字节的部分被丢弃\u003c/li\u003e\n\u003cli\u003edes3dencrypt：input长度是8字节的整数倍；which为0时，key最短为16字节，超过16字节的部分被丢弃；which为1时，key最短为24字节，超过24字节的部分被丢弃\u003c/li\u003e\n\u003cli\u003emd5：无\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e参考文档\n\u003cul\u003e\n\u003cli\u003e函数介绍：函数背景、注意事项等：\u003ca href=\"https://docs.oracle.com/cd/A97630_01/appdev.920/a96590/adgsec04.htm\"\u003ehttps://docs.oracle.com/cd/A97630_01/appdev.920/a96590/adgsec04.htm\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e函数参数：参数类型、调用示例等：\u003ca href=\"https://docs.oracle.com/cd/B10500_01/appdev.920/a96612/d_obtoo2.htm\"\u003ehttps://docs.oracle.com/cd/B10500_01/appdev.920/a96612/d_obtoo2.htm\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e以下是上述函数的调用示例：\u003c/p\u003e","title":"vastbase 加密函数"},{"content":"1 准备开发环境 1.1 登录远程windows 连接vpn\n下载vpn软件，使用入职时他人帮忙申请的vpn账号登录 登录远程windows电脑\n使用入职时他人帮忙申请的远程windows账号 登录gitlab\n入职时，有人已帮忙申请gutlab账号。http://172.16.19.246 查看vastbase代码\nhttp://172.16.19.246/VastbaseG100/src 默认无权限，可能搜不到，请找小组领导开通权限 1.2 准备vastbase编译环境 在远程windows中，登录远程centos\n配置git\n生成rsa密钥，配置到gitlab中\n下载vastbase源码\nmkdir g100 cd g100 git clone -b master git@172.16.19.246:VastbaseG100/src.git 下载vastbase依赖的二进制文件\n需要自行通过svn下载，然后，上传到vastbase源码同级目录\n在文件管理器中，输出ftp://172.16.19.4后，会提示输出账号和密码\nip: 172.16.19.4 用户名: clouder 密码: 自行询问 目录: /Database/Vastbase/third_party 配置用于编译vastbase的环境变量\ncd g100 touch venv 请确保此时的目录结构如下：\nls g100 |-- g100 |-- src |-- binarylibs |-- venv 设置环境变量\nexport CODE_BASE=`pwd` export BINARYLIBS=`pwd`/binarylibs # 安装目录在源码里写死了，改不了 export GAUSSHOME=`pwd`/src/mppdb_temp_install export GCC_PATH=$BINARYLIBS/buildtools/gcc7.3 export CC=$GCC_PATH/gcc/bin/gcc export CXX=$GCC_PATH/gcc/bin/g++ export LD_LIBRARY_PATH=$GAUSSHOME/lib:$GCC_PATH/gcc/lib64:$GCC_PATH/isl/lib:$GCC_PATH/mpc/lib/:$GCC_PATH/mpfr/lib/:$GCC_PATH/gmp/lib/:$LD_LIBRARY_PATH export PATH=$GAUSSHOME/bin:$GCC_PATH/gcc/bin:$PATH # 以下是vastbase增加的 export PATH=$BINARYLIBS/buildtools/cmake/bin:$PATH 配置快捷命令\ncd $CODE_BASE source venv echo \u0026#34; alias vcode=\u0026#39;cd /home/shenkun/g100\u0026#39; alias venv=\u0026#39;vcode \u0026amp;\u0026amp; source ./venv\u0026#39; alias vinstall=\u0026#39;vcode \u0026amp;\u0026amp; cd src/mppdb_temp_install\u0026#39; alias vmake=\u0026#39;vcode \u0026amp;\u0026amp; cd src \u0026amp;\u0026amp; sh build.sh -m debug -3rd $BINARYLIBS -svn 11\u0026#39; alias vcmake=\u0026#39;vcode \u0026amp;\u0026amp; cd src \u0026amp;\u0026amp; sh build.sh -m debug -3rd $BINARYLIBS -svn 11 -cmake\u0026#39; alias vrecmake=\u0026#39;vcode \u0026amp;\u0026amp; cd src/tmp_build \u0026amp;\u0026amp; make -sj \u0026amp;\u0026amp; make install -sj\u0026#39; alias vinit=\u0026#39;vb_initdb -D $GAUSSHOME/data -w vb.12345 --nodename=db1\u0026#39; alias vstart=\u0026#39;vb_ctl start -D $GAUSSHOME/data\u0026#39; alias vrestart=\u0026#39;vb_ctl restart -D $GAUSSHOME/data\u0026#39; \u0026#34; \u0026gt;\u0026gt; ~/.bashrc source ~/.bashrc 安装其他依赖工具\n# 切换到root用户 yum install -y libaio-devel flex bison ncureses-devel patch readline-devel python3 # 修改系统默认python版本 rm -f /usr/bin/python ln -s /usr/bin/python3.6 /usr/bin/python 1.3 准备vastbase开发环境 scp shenkun@172.16.100.134:~/vscode/allpkg.tar.gz # 密码 vg@123 tar -zxvf allpkg.tar.gz cd allpkg mv ./.local/share/code-server ~/.local/share cd code-server ./code-server # 1 安装数据库 1.1 编译 由于已配置快捷命令，此处直接用快捷命令\n# 设置环境变量 venv # 编译代码 vcmake # 进入安装目录 vinstall # 增量变量 vrecmake 不用快捷命令的话：\n# 设置环境变量 cd /home/shenkun/g100 source venv # 编译代码 cd src sh build.sh -m debug -3rd $BINARYLIBS -svn 11 -cmake # 进入安装目录 cd $GAUSSHOME 1.2 安装 初始化数据库\nvb_initdb -D $GAUSS/data --nodename=db1 启动数据库\nvb_ctl start -D $GAUSS/data 重启数据库\nvb_ctl restart -D $GAUSS/data 1.3 连接数据库 vsql -p 5432 -d postgres -r -c \u0026#34;ALTER USER $USER PASSWORD \u0026#39;vast@123\u0026#39;\u0026#34; vsql -p 5432 -d postgres -r 其他环境 1.1 通过ftp访问共享软件库 1.2 通过svn访问共享文档库 1.3 安装其他软件 wps office 2 加解密函数 一、desencrypt函数 vastbase旧函数 格式\n-- 参数 dbms_obfunction_toolkit.desencrypt(plian, key) -\u0026gt; cipher -- 参数类型 -- raw: 16进制编码，约等于bytea，只是无\\x前缀 -- text: 密文自动转换为 base64编码 desencrypt(text, text) -\u0026gt; text desencrypt(bytea, bytea) -\u0026gt; bytea desencrypt(raw, raw) -\u0026gt; raw 输出\nCREATE EXTENSION pgcrypto; SELECT dbms_obfuscation_toolkit.desencrypt(\u0026#39;11111111\u0026#39;, \u0026#39;11111111\u0026#39;)::bytea::raw; -- 输出 5A56366D4B4D396957463845572B4B732F67447777513D3D SELECT dbms_obfuscation_toolkit.desencrypt(\u0026#39;11111111\u0026#39;::bytea::raw, \u0026#39;11111111\u0026#39;::bytea::raw); -- 输出 5A56366D4B4D396957463845572B4B732F67447777513D3D SELECT dbms_obfuscation_toolkit.desencrypt(\u0026#39;11111111\u0026#39;::bytea, \u0026#39;11111111\u0026#39;::bytea)::raw; -- 输出 5A56366D4B4D396957463845572B4B732F67447777513D3D SELECT dbms_obfuscation_toolkit.desencrypt(\u0026#39;1111111111111111\u0026#39;, \u0026#39;11111111\u0026#39;)::bytea::raw; -- 输出 5A56366D4B4D3969574638673037696D356C654861387A616167394370743236 oracle函数 格式\n-- 参数 dbms_obfuscation_toolkit.desdecrypt(plain, key, OUT cipher) -- 参数类型 desdecrypt(varchar2, varchar2, varchar2) desdecrypt(raw, raw, raw) 输出\nraw 类型\nCREATE OR REPLACE FUNCTION desencrypt(plain VARCHAR2, key VARCHAR2) RETURN VARCHAR2 IS cipher RAW(100); BEGIN dbms_obfuscation_toolkit.desencrypt(utl_raw.cast_to_raw(plain), utl_raw.cast_to_raw(key), encrypted_data=\u0026gt;cipher); RETURN rawtohex(cipher); END; / SELECT desencrypt(\u0026#39;11111111\u0026#39;, \u0026#39;11111111\u0026#39;) FROM dual; SELECT utl_raw.cast_to_raw(dbms_obfuscation_toolkit.desencrypt(input_string=\u0026gt;\u0026#39;11111111\u0026#39;, key_string=\u0026gt;\u0026#39;11111111\u0026#39;)) FROM dual; -- 输出 655EA628CF62585F SELECT utl_raw.cast_to_raw(dbms_obfuscation_toolkit.desencrypt(input_string=\u0026gt;\u0026#39;1111111111111111\u0026#39;, key_string=\u0026gt;\u0026#39;11111111\u0026#39;)) FROM dual; SELECT desencrypt(\u0026#39;1111111111111111\u0026#39;, \u0026#39;11111111\u0026#39;) FROM dual; -- 输出 655EA628CF62585F20D3B8A6E657876B varchar 类型\nCREATE OR REPLACE FUNCTION desencrypt(plain VARCHAR2, key VARCHAR2) RETURN VARCHAR2 IS cipher VARCHAR2(100); BEGIN dbms_obfuscation_toolkit.desencrypt(plain, key, encrypted_string=\u0026gt;cipher); RETURN cipher; END; / SELECT utl_raw.cast_to_raw(desencrypt(\u0026#39;11111111\u0026#39;, \u0026#39;11111111\u0026#39;)) FROM dual; -- 输出 655EA628CF62585F -- 换个格式 DECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.desencrypt(\u0026#39;11111111\u0026#39;, \u0026#39;11111111\u0026#39;, encrypted_string=\u0026gt;cipher); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / 二、des3encrypt函数 vastbase旧函数 格式\n-- (一) 参数 dbms_obfuscation_toolkit.des3encrypt(plain, key, iv) -\u0026gt; cipher -- input_string key_string encrypted_string / encrypted_data -- key为16字节，超过16字节的未被使用 -- 参数类型 des3encrypt(text, text, text) -\u0026gt; raw des3encrypt(bytea, bytea, bytea) -\u0026gt; bytea des3encrypt(raw, raw, raw) -\u0026gt; raw -- (二) 参数 dbms_obfuscation_toolkit.des3encrypt(plain, key, keymode = 0) -\u0026gt; cipher -- 参数类型 des3encrypt(text, text, int = 0) -\u0026gt; raw des3encrypt(bytea, bytea, int = 0) -\u0026gt; bytea des3encrypt(raw, raw, int = 0) -\u0026gt; raw -- （三）参数 dbms_obfuscation_toolkit.des3encrypt(plain, key, keymode, iv) -\u0026gt; cipher des3encrypt(text, text, int, text) -\u0026gt; raw des3encrypt(bytea, bytea, int, bytea) -\u0026gt; bytea des3encrypt(raw, raw, int, raw) -\u0026gt; raw 输出\n-- (一) SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, \u0026#39;11111111\u0026#39;)::bytea::raw; -- ERROR: wrong key SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111122222222\u0026#39;, \u0026#39;11111111\u0026#39;)::bytea::raw; SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;::bytea, \u0026#39;1111111122222222\u0026#39;::bytea, \u0026#39;11111111\u0026#39;::bytea)::raw; SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;::bytea::raw, \u0026#39;1111111122222222\u0026#39;::bytea::raw, \u0026#39;11111111\u0026#39;::bytea::raw); -- 输出 4F7A536633345072325939536B547A776c334C6278513D3D -- （二） SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111122222222\u0026#39;)::bytea::raw; SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111122222222\u0026#39;, 0)::bytea::raw; -- 输出 5465744A2B552B384E73504B7671372B2B36424D38413D3D SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;111111112222222211111111\u0026#39;, 1)::bytea::raw; -- ERROR: wrong key SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;111111112222222233333333\u0026#39;, 1)::bytea::raw; -- 输出 5A56366D4B4D3966957463845572B4B732F67447777513D3D -- (三) SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111122222222\u0026#39;, 0, \u0026#39;11111111\u0026#39;)::bytea::raw; -- 输出 4F7A536633345072325939536B547A776c334C6278513D3D SELECT dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;111111112222222233333333\u0026#39;, 1, \u0026#39;11111111\u0026#39;)::bytea::raw; -- 输出 51494A71574142676A49635143695859617366464C413D3D oracle函数 格式\n-- (一) 参数 dbms_obfuscation_toolkit.des3encrypt(plain, key, OUT cipher, keymode = 0, iv = NULL) -- input_string key_sgring encrypted_string which iv_string -- input key encrypted_data which iv -- 参数类型 des3encrypt(varchar2, varchar2, varchar2, int = 0, varchar2 = NULL) des3encrypt(raw, raw, raw, int = 0, raw = NULL) 输出\nDECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, encrypted_string=\u0026gt;cipher); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / -- 输出 C7E61EC9A68F8C02 DECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, encrypted_string=\u0026gt;cipher, which=\u0026gt;0, iv_string=\u0026gt;NULL); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / -- 输出 C7E61EC9A68F8C02 DECLARE cipher RAW(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(\u0026#39;3131313131313131\u0026#39;, \u0026#39;31313131313131313131313131313131\u0026#39;, encrypted_data=\u0026gt;cipher, which=\u0026gt;0, iv=\u0026gt;\u0026#39;0123456789abcdef\u0026#39;); dbms_output.put_line(cipher); END; / -- 输出 C7E61EC9A68F8C02 DECLARE cipher RAW(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(hextoraw(\u0026#39;3131313131313131\u0026#39;), hextoraw(\u0026#39;31313131313131313131313131313131\u0026#39;), encrypted_data=\u0026gt;cipher, which=\u0026gt;0, iv=\u0026gt;hextoraw(\u0026#39;0123456789abcdef\u0026#39;)); dbms_output.put_line(cipher); END; / -- 输出 C7E61EC9A68F8C02 DECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(hextoraw(\u0026#39;11111111\u0026#39;), \u0026#39;1111111111111111\u0026#39;, encrypted_string=\u0026gt;cipher, which=\u0026gt;0, iv_string=\u0026gt;NULL); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / -- 输出 C7E61EC9A68F8C02 DECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, encrypted_string=\u0026gt;cipher, which=\u0026gt;0, iv_string=\u0026gt;hextoraw(\u0026#39;0123456789abcdef\u0026#39;)); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / -- 输出 6FFB37B42D9EB72E DECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, encrypted_string=\u0026gt;cipher, which=\u0026gt;0, iv_string=\u0026gt;\u0026#39;11111111\u0026#39;); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / -- 输出 40826A5800607C87 DECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(\u0026#39;11111111\u0026#39;, \u0026#39;111111112222222233333333\u0026#39;, encrypted_string=\u0026gt;cipher, which=\u0026gt;1, iv_string=\u0026gt;\u0026#39;11111111\u0026#39;); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / -- 输出 40826A5800608C8 DECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(\u0026#39;1111111111111111\u0026#39;, \u0026#39;1111111111111111\u0026#39;, encrypted_string=\u0026gt;cipher); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / -- 输出 C7E61EC9A68F8C02165CEC3E75635F5D 问题单\nselect utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;1111111111111111\u0026#39;, key_string=\u0026gt;010199010401050110974949, which=\u0026gt;0)) from dual; -- 输出 E7E14DFD9E0DED3B D80084E1EDD76DF1 select utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;1111111111111111\u0026#39;, key_string=\u0026gt;\u0026#39;101990104010501109749490\u0026#39;, which=\u0026gt;0)) from dual; -- 输出 E7E14DFD9E0DED3B D80084E1EDD76DF1 select utl_raw.cast_to_raw(dbms_obfuscation_toolkit.des3encrypt(\u0026#39;1111111111111111\u0026#39;, key_string=\u0026gt;\u0026#39;010199010401050110974949\u0026#39;, which=\u0026gt;0)) from dual; -- 输出 6BD3D44F21050468F90eD91712B47B4C DECLARE cipher VARCHAR2(200); BEGIN dbms_obfuscation_toolkit.des3encrypt(\u0026#39;1111111111111111\u0026#39;, \u0026#39;101990104010501109749490\u0026#39;, encrypted_string=\u0026gt;cipher, which=\u0026gt;0, iv_string=\u0026gt;NULL); dbms_output.put_line(utl_raw.cast_to_raw(cipher)); END; / -- 输出 7E14DFD9E0DED3B D80084E1EDD76DF1 http://172.16.19.246/VastbaseG100/src/-/merge_requests/13079/diffs\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/vastbase-build/","summary":"\u003ch1 id=\"1-准备开发环境\"\u003e1 准备开发环境\u003c/h1\u003e\n\u003ch2 id=\"11-登录远程windows\"\u003e1.1 登录远程windows\u003c/h2\u003e\n\u003col\u003e\n\u003cli\u003e连接vpn\u003cbr\u003e\n下载vpn软件，使用入职时他人帮忙申请的vpn账号登录\u003c/li\u003e\n\u003cli\u003e登录远程windows电脑\u003cbr\u003e\n使用入职时他人帮忙申请的远程windows账号\u003c/li\u003e\n\u003cli\u003e登录gitlab\u003cbr\u003e\n入职时，有人已帮忙申请gutlab账号。\u003ca href=\"http://172.16.19.246/\"\u003ehttp://172.16.19.246\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e查看vastbase代码\u003cbr\u003e\n\u003ca href=\"http://172.16.19.246/VastbaseG100/src\"\u003ehttp://172.16.19.246/VastbaseG100/src\u003c/a\u003e\n\u003cul\u003e\n\u003cli\u003e默认无权限，可能搜不到，请找小组领导开通权限\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"12-准备vastbase编译环境\"\u003e1.2 准备vastbase编译环境\u003c/h2\u003e\n\u003cp\u003e在远程windows中，登录远程centos\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e配置git\u003cbr\u003e\n生成rsa密钥，配置到gitlab中\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e下载vastbase源码\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir g100\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e g100\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egit clone -b master git@172.16.19.246:VastbaseG100/src.git\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e下载vastbase依赖的二进制文件\u003cbr\u003e\n需要自行通过svn下载，然后，上传到vastbase源码同级目录\u003cbr\u003e\n在文件管理器中，输出\u003ccode\u003eftp://172.16.19.4\u003c/code\u003e后，会提示输出账号和密码\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eip: 172.16.19.4\u003c/li\u003e\n\u003cli\u003e用户名: clouder\u003c/li\u003e\n\u003cli\u003e密码: 自行询问\u003c/li\u003e\n\u003cli\u003e目录: /Database/Vastbase/third_party\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e配置用于编译vastbase的环境变量\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e g100\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etouch venv\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e请确保此时的目录结构如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003els g100\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e-- g100\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e|\u003c/span\u003e-- src\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e|\u003c/span\u003e-- binarylibs\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e|\u003c/span\u003e-- venv\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e设置环境变量\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCODE_BASE\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eBINARYLIBS\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e/binarylibs\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 安装目录在源码里写死了，改不了\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eGAUSSHOME\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e\u003cspan class=\"nb\"\u003epwd\u003c/span\u003e\u003cspan class=\"sb\"\u003e`\u003c/span\u003e/src/mppdb_temp_install\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eGCC_PATH\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$BINARYLIBS\u003c/span\u003e/buildtools/gcc7.3\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCC\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$GCC_PATH\u003c/span\u003e/gcc/bin/gcc\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eCXX\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$GCC_PATH\u003c/span\u003e/gcc/bin/g++\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003eLD_LIBRARY_PATH\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/lib:\u003cspan class=\"nv\"\u003e$GCC_PATH\u003c/span\u003e/gcc/lib64:\u003cspan class=\"nv\"\u003e$GCC_PATH\u003c/span\u003e/isl/lib:\u003cspan class=\"nv\"\u003e$GCC_PATH\u003c/span\u003e/mpc/lib/:\u003cspan class=\"nv\"\u003e$GCC_PATH\u003c/span\u003e/mpfr/lib/:\u003cspan class=\"nv\"\u003e$GCC_PATH\u003c/span\u003e/gmp/lib/:\u003cspan class=\"nv\"\u003e$LD_LIBRARY_PATH\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003ePATH\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$GAUSSHOME\u003c/span\u003e/bin:\u003cspan class=\"nv\"\u003e$GCC_PATH\u003c/span\u003e/gcc/bin:\u003cspan class=\"nv\"\u003e$PATH\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 以下是vastbase增加的\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003ePATH\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"nv\"\u003e$BINARYLIBS\u003c/span\u003e/buildtools/cmake/bin:\u003cspan class=\"nv\"\u003e$PATH\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e配置快捷命令\u003c/p\u003e","title":"Vastbase 搭建环境、编译代码、安装数据库"},{"content":"1 概述 来源：https://docs.oracle.com/en/database/oracle/oracle-database/23/dbseg\n基础安全\n身份认证 密码最小长度 连续失败锁定 账户锁定 新旧密码重复 密码有效期 访问控制 敏感数据发现 传输加密 安全审计 高级安全\n透明加密 数据脱敏 访问控制 行级访问控制 数据库保险柜：细粒度访问控制 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/oracle-security/","summary":"\u003ch1 id=\"1-概述\"\u003e1 概述\u003c/h1\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e来源：\u003ca href=\"https://docs.oracle.com/en/database/oracle/oracle-database/23/dbseg\"\u003ehttps://docs.oracle.com/en/database/oracle/oracle-database/23/dbseg\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e基础安全\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e身份认证\n\u003cul\u003e\n\u003cli\u003e密码最小长度\u003c/li\u003e\n\u003cli\u003e连续失败锁定\u003c/li\u003e\n\u003cli\u003e账户锁定\u003c/li\u003e\n\u003cli\u003e新旧密码重复\u003c/li\u003e\n\u003cli\u003e密码有效期\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e访问控制\u003c/li\u003e\n\u003cli\u003e敏感数据发现\u003c/li\u003e\n\u003cli\u003e传输加密\u003c/li\u003e\n\u003cli\u003e安全审计\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e高级安全\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e透明加密\u003c/li\u003e\n\u003cli\u003e数据脱敏\u003c/li\u003e\n\u003cli\u003e访问控制\n\u003cul\u003e\n\u003cli\u003e行级访问控制\u003c/li\u003e\n\u003cli\u003e数据库保险柜：细粒度访问控制\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e","title":"Oracle 安全特性"},{"content":"1 Oracle 集群管理 1.2 登录数据库 sqlplus / as sysdba 2 Oracle 语法 2.1 数据类型 仅列举常见数据类型：\n大类 类型 解释 数值 INT or INTGER 整数 - NUMBESR(p, s) p: 精度，整数和小数总位数，s: 小数位数 - SMALLINT 等于 NUMBESR(38) - FLOAT(p) 浮点数，p: 二进制精度，最大126 字符 CHAR(n) 固定长度字符，n: 长度，不足n用空格填充 - VARCHAR2(n) 可变长度字符，n: 最大长度，最大4000 时间 DATE 日期 - TIMESTAMP 日期和时间 二进制 CLOB 长文本数据 2.2 常用SQL 常见语法\n-- 1 创建表 CREATE TABLE t1 (c1 INT, c2 VARCHAR2(10)); -- 2 插入数据 INSERT INTO t1 VALUES (1, \u0026#39;abcc\u0026#39;); INSERT INTO t1 VALUES (2, \u0026#39;ddee\u0026#39;); -- 3 查询数据 SELECT * FROM t1 WHERE c1 \u0026gt; 0; -- 4 更新数据 UPDATE t1 SET c2 = \u0026#39;abbc\u0026#39; WHERE c1 = 1; -- 5 删除数据 DELETE FROM t1 WHERE c1 = 2; -- 6 删除表 DROP TABLE t1; 内置函数\nCREATE TABLE t1 (c1 INT, c2 VARCHAR2(10)); INSERT INTO t1 VALUES (1, upper(\u0026#39;abcc\u0026#39;)); SELECT c1,c2,lower(c2) FROM t1; 2.3 常用系统表 -- 查看所有表 SELECT * FROM user_tables; -- 查看lorand用户有权访问的表 SELECT owner,table_name FROM all_tables WHERE owner = \u0026#39;lorand\u0026#39;; -- 查看t1表的列信息 SELECT column_name,data_type FROM user_tab_columns WHERE table_name = \u0026#39;t1\u0026#39;; -- 查看所有索引 SELECT * FROM user_indexes; -- 查看所有用户 SELECT * FROM dba_users; -- 查看数据库信息 SELECT * FROM v$database; -- 查看实例信息 SELECT * FROM v$instance; 常用设置 SET LINESIZE 200 SET PAGESIZE 100 SET COLSEP \u0026#39; | \u0026#39; SET NUMWIDTH 15 SET HEADING ON SET FEEDBACK OFF 查看表的所有列\nSELECT column_name,data_type,data_length,nullable FROM all_tab_columns WHERE table_name = UPPER(\u0026#39;dba_profiles\u0026#39;); ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/oracle-overview/","summary":"\u003ch1 id=\"1-oracle-集群管理\"\u003e1 Oracle 集群管理\u003c/h1\u003e\n\u003ch2 id=\"12-登录数据库\"\u003e1.2 登录数据库\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esqlplus / as sysdba\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch1 id=\"2-oracle-语法\"\u003e2 Oracle 语法\u003c/h1\u003e\n\u003ch2 id=\"21-数据类型\"\u003e2.1 数据类型\u003c/h2\u003e\n\u003cp\u003e仅列举常见数据类型：\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth\u003e大类\u003c/th\u003e\n          \u003cth\u003e类型\u003c/th\u003e\n          \u003cth\u003e解释\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e数值\u003c/td\u003e\n          \u003ctd\u003eINT or INTGER\u003c/td\u003e\n          \u003ctd\u003e整数\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eNUMBESR(p, s)\u003c/td\u003e\n          \u003ctd\u003ep: 精度，整数和小数总位数，s: 小数位数\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eSMALLINT\u003c/td\u003e\n          \u003ctd\u003e等于 NUMBESR(38)\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eFLOAT(p)\u003c/td\u003e\n          \u003ctd\u003e浮点数，p: 二进制精度，最大126\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e字符\u003c/td\u003e\n          \u003ctd\u003eCHAR(n)\u003c/td\u003e\n          \u003ctd\u003e固定长度字符，n: 长度，不足n用空格填充\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eVARCHAR2(n)\u003c/td\u003e\n          \u003ctd\u003e可变长度字符，n: 最大长度，最大4000\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e时间\u003c/td\u003e\n          \u003ctd\u003eDATE\u003c/td\u003e\n          \u003ctd\u003e日期\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e-\u003c/td\u003e\n          \u003ctd\u003eTIMESTAMP\u003c/td\u003e\n          \u003ctd\u003e日期和时间\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd\u003e二进制\u003c/td\u003e\n          \u003ctd\u003eCLOB\u003c/td\u003e\n          \u003ctd\u003e长文本数据\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003ch2 id=\"22-常用sql\"\u003e2.2 常用SQL\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e常见语法\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 1 创建表\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eVARCHAR2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e10\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2 插入数据\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;abcc\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;ddee\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 查询数据\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 4 更新数据\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eUPDATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSET\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;abbc\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 5 删除数据\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDELETE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWHERE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 6 删除表\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eDROP\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e内置函数\u003c/p\u003e","title":"Oracle 基本介绍"},{"content":" 设置bash\nexport PS1=\u0026#34;[\\e[35;1m][\\$(date +\u0026#39;%m-%d/%H:%M:%S\u0026#39;)][\\e[36;1m]\\w [\\e[0m]\\n\u0026gt; \u0026#34; 安装code-servels\nhttps://blog.zhaokeyong.cn/archives/CentOScode-server\n安装3.4版本，方便\n# 1 从本地机器上，找到code-server所在文件夹 cd /home/shenkun/vscode mkdir allpkg # 放插件的目录 cp -r ~/.local allpkg cp -r ./code-server allpkg tar -zcvf allpkg.tar.gz allpkg cd /home/shenkun/vscode tar -zxvf allpkg.tar.gz mv allpkg/code-server ./ rm -rf ~/.local/share/code-server/* mv allpkg/.local/share/code-server/* ~/.local/share/code-server nohup ./code-server \u0026amp; # 设置配置文件 vi ~/.config/code-server/config.yaml bind-addr: 0.0.0.0:3000 auth: password password: password cert: false nohup ./code-server \u0026amp; 常用插件：\nc/c++\ngitlens\nmarkdown preview enhanced\n安装 oracle\nhttps://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001006330 配置core文件目录\nmkdir /core chmod 777 /core echo \u0026#34;1\u0026#34; \u0026gt;\u0026gt; /proc/sys/kernel/core_uses_pid echo \u0026#34;/core/core-%e-%p-%t\u0026#34; \u0026gt; /proc/sys/kernel/core_pattern vi /etc/security/limits.conf # 在末尾增加以下2行：记得带星号* * hard core unlimited * soft core unlimited 配置git\ngit config --global user.name \u0026#34;shenkun\u0026#34; git config --global user.email \u0026#34;shenkun@bupt.cn\u0026#34; ssh-keygen -t rsa -C \u0026#34;shenkun@bupt.cn\u0026#34; cat ~/.ssh/id_rsa ","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/new-machine/","summary":"\u003col start=\"0\"\u003e\n\u003cli\u003e\n\u003cp\u003e设置bash\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eexport\u003c/span\u003e \u003cspan class=\"nv\"\u003ePS1\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;[\\e[35;1m][\\$(date +\u0026#39;%m-%d/%H:%M:%S\u0026#39;)][\\e[36;1m]\\w [\\e[0m]\\n\u0026gt; \u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e安装code-servels\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"https://blog.zhaokeyong.cn/archives/CentOScode-server\"\u003ehttps://blog.zhaokeyong.cn/archives/CentOScode-server\u003c/a\u003e\u003cbr\u003e\n安装3.4版本，方便\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 1 从本地机器上，找到code-server所在文件夹\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e /home/shenkun/vscode\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emkdir allpkg\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 放插件的目录\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp -r ~/.local allpkg\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecp -r ./code-server allpkg\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etar -zcvf allpkg.tar.gz allpkg\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003ecd\u003c/span\u003e /home/shenkun/vscode\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003etar -zxvf allpkg.tar.gz\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emv allpkg/code-server ./\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003erm -rf ~/.local/share/code-server/*\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003emv allpkg/.local/share/code-server/* ~/.local/share/code-server\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enohup ./code-server \u003cspan class=\"p\"\u003e\u0026amp;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 设置配置文件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evi ~/.config/code-server/config.yaml\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ebind-addr: 0.0.0.0:3000\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eauth: password\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003epassword: password\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecert: \u003cspan class=\"nb\"\u003efalse\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003enohup ./code-server \u003cspan class=\"p\"\u003e\u0026amp;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e常用插件：\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ec/c++\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003egitlens\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003emarkdown preview enhanced\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e安装 oracle\u003c/p\u003e","title":"工具 配置新环境"},{"content":"1 基本介绍 要求 数据库基本原理 C语言 数据结构 操作系统 数据存储需求 数据存储方案 文件 excel 数据库 2 kkdb 成果展示 初始化\n# 系统表 sys_class: 存储所有表 sys_attr: 存储所有列 dbinit ls ~/dbdata 基本语法\nCREATE\n输入：CREATE TABLE t1 (c1 INT, c2 TEXT); 语法解析：表名、列名、列数据类型 系统表：存储表信息、列信息 表文件：创建文件 INSERT\n输入：INSERT INTO t1 VALUES (1, \u0026#39;first\u0026#39;) 语法解析：表名、列数据 数据处理：封装数据 表文件：写入数据 SELECT\n输入：SELECT * FROM t1 语法解析：表名、列 表文件：读取数据 数据处理：解析数据 UPDATE\nDELETE\nDROP\n并发访问\nCS模式\n服务器\ndbserver start 客户端\ndbclient 127.0.0.1 8888 SELECT * FROM t1; 服务器多线程\ndbclient 127.0.0.1 8888 dbclient 127.0.0.1 8888 输出：服务端sprintf，然后发至客户端\n正确性\n原子性、隔离性：事务ID、事务快照、可见性\n# 原子性 BEGI INSERT INTO t1 VALUES (3, \u0026#39;three\u0026#39;) INSERT INTO t1 VALUES (4, \u0026#39;four\u0026#39;) ROLLBACK # 隔离性性 dbclient BEGIN INSERT INTO t1 VALUES (5, \u0026#39;five\u0026#39;) INSERT INTO t1 VALUES (6, \u0026#39;six\u0026#39;) COMMIT dbclient SELECT * FROM t1 SELECT * FROM t1 高性能\n异步落盘：buffer pool\ndbclient CONFIG checkpoint = 10min INSERT INTO t1 VALUES (7, \u0026#39;seven\u0026#39;) hexdump t1 CHECKPOINT hexdump t1 故障恢复：\n预写日志\ndbclient INSERT INTO t1 VALUES (8, \u0026#39;eight\u0026#39;) cat xlog 故障恢复\nkill dbserver dbserver 127.0.0.1 8888 hexdump t1 SELECT * FROM t1 基本运算\n投影\nSELECT c2 FROM t2; 选择\n内置函数\nSELECT is_str(c1) FROM t1; WHERE子句\nSELECT * FROM t1 WHERE c1 \u0026gt; 10 SELECT * FROM t1 WHERE is_bigger(c1, 10); 限制\nSELECT * FROM t1 WHERE c1 \u0026gt; 10 LIMIT 1; 执行器\nfor (;;) scan filter qual 高性能\n索引\nCREATE INDEX ON t1(c1); SELECT * FROM t1 WHERE c1 = 666; JOIN\n优化器\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/projects/kkdb-1-preview/","summary":"\u003ch1 id=\"1-基本介绍\"\u003e1 基本介绍\u003c/h1\u003e\n\u003ch2 id=\"要求\"\u003e要求\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e数据库基本原理\u003c/li\u003e\n\u003cli\u003eC语言\u003c/li\u003e\n\u003cli\u003e数据结构\u003c/li\u003e\n\u003cli\u003e操作系统\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"数据存储需求\"\u003e数据存储需求\u003c/h2\u003e\n\u003ch2 id=\"数据存储方案\"\u003e数据存储方案\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e文件\u003c/li\u003e\n\u003cli\u003eexcel\u003c/li\u003e\n\u003cli\u003e数据库\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-kkdb\"\u003e2 kkdb\u003c/h1\u003e\n\u003ch2 id=\"成果展示\"\u003e成果展示\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e初始化\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 系统表\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esys_class: 存储所有表\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esys_attr: 存储所有列\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edbinit\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003els ~/dbdata\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e基本语法\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eCREATE\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e输入：CREATE TABLE t1 \u003cspan class=\"o\"\u003e(\u003c/span\u003ec1 INT, c2 TEXT\u003cspan class=\"o\"\u003e)\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e语法解析：表名、列名、列数据类型\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e系统表：存储表信息、列信息\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e表文件：创建文件\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eINSERT\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e输入：INSERT INTO t1 VALUES \u003cspan class=\"o\"\u003e(\u003c/span\u003e1, \u003cspan class=\"s1\"\u003e\u0026#39;first\u0026#39;\u003c/span\u003e\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e语法解析：表名、列数据\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e数据处理：封装数据\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e表文件：写入数据\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eSELECT\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e输入：SELECT * FROM t1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e语法解析：表名、列\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e表文件：读取数据\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e数据处理：解析数据\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eUPDATE\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eDELETE\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eDROP\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e并发访问\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eCS模式\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e服务器\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edbserver start\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e客户端\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edbclient 127.0.0.1 \u003cspan class=\"m\"\u003e8888\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eSELECT * FROM t1\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e服务器多线程\u003c/p\u003e","title":"kkdb 1 预览"},{"content":"目录：\n1 概述 2 flex 参考： 1 概述 需求\n判断字符串，是否满足规定的规则。\n示例\n字符串：\n‘abc’, ‘a1’, ‘a+’, …\n规则：\n字符串中只包含字母\n编码：\n/* 省略 */ 问题：\n复杂性：在字符串较长，规则繁多时，判断逻辑将会很复杂，编码工作量大\n方案：\n通过通用的正则表达式制定规则 通过很多开源或非开源的词法解析工具，实现判断逻辑。 正则表达式：\n[a-zA-Z]+ ： 字符串中只包含字母\n如此，我们仅需简单制定正则表达式，通过第三方词法解析工具实现判断逻辑。\n2 flex 1 词法解析\n词法解析工具有很多，本文仅介绍flex。\nflex编写的规则文件，后缀为.l\n2 编译流程\n编写 [规则.l] 文件 通过flex，将 [规则.l] 文件，转换为 [规则.c] 文件 将 [规则.c] 文件，以其他文件一起，正常编译即可 3 文件格式\n%{ /* include */ %} /* define */ %% rule {code();} %% void usercode() { yylex(); } 4 正则表达式\n单字符\n模式 示例 解释 公式 示例 rule {printf(“-“);} a a 相等字符 $ = a abac : -b-c . 任意字符 任意字符，除换行符 $ != \\n abc : — [a b c] a, b, c 任一字符 $ = a or a or a a+b+c : -+-+- [a b-d] a, b, c, d 范围字符 $ = a or b to d a+c : -+- [^ a] b, c, … 其他字符，除a外 $ = !a bab : -a- [^ a-z] A, B, … 其他字符，除a到z外 $ = !(a to z) Abc : A– [^ a-z A-Z] 1, 2, … 其他字符，除a到z外，除A-Z外 Aa1 : Aa- a? a 是否存在，存在于不存在 a,aa,baac : -,–,b–c 重复多字符\n模式 示例 解释 公式 示例 rule {printf(“-“);} a* a, aa, aaa, … 任意重复字符,零个或多个 a,aa,baab : -,-,b-b a+ a, aa, aaa, … 任意重复字符，一个或多个 a,aa,baab : -,-,b-b r{3, 4} aaa,aaaa 指定重复字符 aa,aaa,aaaaa : aa,-,-a r{3, } aaa, … 指定重复字符，大于3个 aa,aaa,aaaaa : aa,-,- 字符连接\n模式 解释 示例 rule {printf(“-“);} abc 字符串联 ab,abc,abcd : ab,-,-d a bc 并联 a/b 以b结尾，保留b a,b,ab,acb : a,b,-b,acb ab(cd)* 优先级 ab,abcd,abcdcd,abccd : -,-,-,-ccd [a-d]{-}[cd] 集合相减 a,b,c,d : -,-,c,d 其他实例\n模式 示例 示例 rule {printf(“-“);} ab* a,ab,abb 任意重复字符 ab+ ab,abb 任意重复字符 5 规则执行流程\n顺序执行，满足即停\n[ab] {printf(“-“)}\n. []\n结果：\na,b,c,d : –\n顺序执行，满足不停 REJECT\n[ab] {printf(“-“); REJECT}\n. {printf(“+”);}\n结果：\na,b,c : -++-+++\n条件执行 BEGIN(usestate) BEGIN(INITIAL)\n%s state1\n/* 也可以是： %x state1，如此，state1将变成一个整数 */\n%%\ns1 BEGIN(state1);\n[ab] printf(“+”);\n[ab] printf(“-“);\ne1 BEGIN(INITIAL);\n%%\n结果：\na s1 a e1 a : - + -\n参考： flex使用：\nhttps://zhuanlan.zhihu.com/p/108167693\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/flex/","summary":"\u003cp\u003e目录：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-%E6%A6%82%E8%BF%B0\"\u003e1 概述\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-flex\"\u003e2 flex\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%8F%82%E8%80%83%EF%BC%9A\"\u003e参考：\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"1-概述\"\u003e1 概述\u003c/h1\u003e\n\u003cp\u003e\u003cstrong\u003e需求\u003c/strong\u003e\u003cbr\u003e\n判断字符串，是否满足规定的规则。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e示例\u003c/strong\u003e\u003cbr\u003e\n字符串：\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e‘abc’, ‘a1’, ‘a+’, …\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003e规则：\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e字符串中只包含字母\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003e编码：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* 省略 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e问题：\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003e复杂性\u003c/strong\u003e：在字符串较长，规则繁多时，判断逻辑将会很复杂，编码工作量大\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003e方案：\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cul\u003e\n\u003cli\u003e通过通用的\u003cstrong\u003e正则表达式\u003c/strong\u003e制定规则\u003c/li\u003e\n\u003cli\u003e通过很多开源或非开源的词法解析工具，实现判断逻辑。\u003c/li\u003e\n\u003c/ul\u003e\u003c/blockquote\u003e\n\u003cp\u003e正则表达式：\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e[a-zA-Z]+ ： 字符串中只包含字母\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003e如此，我们仅需简单制定正则表达式，通过第三方词法解析工具实现判断逻辑。\u003c/p\u003e\n\u003ch1 id=\"2-flex\"\u003e2 flex\u003c/h1\u003e\n\u003cp\u003e\u003cstrong\u003e1 词法解析\u003c/strong\u003e\u003cbr\u003e\n词法解析工具有很多，本文仅介绍flex。\u003cbr\u003e\nflex编写的规则文件，后缀为.l\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e2 编译流程\u003c/strong\u003e\u003c/p\u003e\n\u003cblockquote\u003e\n\u003col\u003e\n\u003cli\u003e编写 [规则.l] 文件\u003c/li\u003e\n\u003cli\u003e通过flex，将 [规则.l] 文件，转换为 [规则.c] 文件\u003c/li\u003e\n\u003cli\u003e将 [规则.c] 文件，以其他文件一起，正常编译即可\u003c/li\u003e\n\u003c/ol\u003e\u003c/blockquote\u003e\n\u003cp\u003e\u003cstrong\u003e3 文件格式\u003c/strong\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e%\u003c/span\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* include */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e%\u003c/span\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/* define */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e%%\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003erule\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\u003cspan class=\"nf\"\u003ecode\u003c/span\u003e\u003cspan class=\"p\"\u003e();}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e%%\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"kt\"\u003evoid\u003c/span\u003e \u003cspan class=\"nf\"\u003eusercode\u003c/span\u003e\u003cspan class=\"p\"\u003e()\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \u003cspan class=\"nf\"\u003eyylex\u003c/span\u003e\u003cspan class=\"p\"\u003e();\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e\u003cstrong\u003e4 正则表达式\u003c/strong\u003e\u003cbr\u003e\n\u003cstrong\u003e单字符\u003c/strong\u003e\u003c/p\u003e","title":"tool.flex.词法解析工具"},{"content":" 说明：原始markdow语法见本文底部\n目录：\n标题：1 标题：1.1 标题：1.1.1 标题：1.1.1.1 标题：1.1.1.1.1 标题：1.1.1.1.1.1 加粗：test\n横线：test\n斜体：test\n标题：1 标题：1.1 标题：1.1.1 标题：1.1.1.1 标题：1.1.1.1.1 标题：1.1.1.1.1.1 $~~$缩进\n节点：\na b ba 序号：\na b c d 分割线\n链接：点我\n链接：[id]\nsomething\nsomething\n图片：[![desc](/path/to/img.png)](http://www.baidu.com/ \u0026quot;desc\u0026quot;)\n引用：\nline 1\nline 2\nada\n代码func(int a, int b)\n代码块：\ndef func(int a, int b) { return 0; } def func(a, b): c = \u0026#34;abc\u0026#34; return a + b 表格：\nc1 c2 c3 1 2 3 2 2 3 html转换：\n♥\n分页符：\n[========]\nabc\n目录： 标题：1标题：1.1标题：1.1.1标题：1.1.1.1标题：1.1.1.1.1标题：1.1.1.1.1.1 加粗：**test** 横线：~~test~~ 斜体：*test* # 标题：1 ## 标题：1.1 ### 标题：1.1.1 #### 标题：1.1.1.1 ##### 标题：1.1.1.1.1 ###### 标题：1.1.1.1.1.1 $~~$ 节点： - a - b - ba 序号： 1. a 2. b 1. c 2. d 分割线 ------------ 链接：[点我](http://www.baidu.com \u0026#34;点我\u0026#34;) 链接：[[id]][linkid] something something [linkid]: http://www.baidu.com 图片： [![desc](../../1.PNG)](http://www.baidu.com \u0026#34;desc\u0026#34;) 引用： \u0026gt; line 1 \u0026gt; line 2 ada 代码`func(int a, int b)` 代码块： def func(int a, int b) { return 0; } def func(a, b): c = \u0026#34;abc\u0026#34; return a + b 表格： | c1 | c2 | c3 | | :- | -: | :-: | | 1 | 2 | 3| | 2 | 2 |3| html转换： \u0026amp;hearts; 分页符： [========] abc ","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/markdown/","summary":"\u003cblockquote\u003e\n\u003cp\u003e说明：原始markdow语法见本文底部\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003e目录：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E6%A0%87%E9%A2%98%EF%BC%9A1\"\u003e标题：1\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E6%A0%87%E9%A2%98%EF%BC%9A1-1\"\u003e标题：1.1\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E6%A0%87%E9%A2%98%EF%BC%9A1-1-1\"\u003e标题：1.1.1\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E6%A0%87%E9%A2%98%EF%BC%9A1-1-1-1\"\u003e标题：1.1.1.1\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E6%A0%87%E9%A2%98%EF%BC%9A1-1-1-1-1\"\u003e标题：1.1.1.1.1\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E6%A0%87%E9%A2%98%EF%BC%9A1-1-1-1-1-1\"\u003e标题：1.1.1.1.1.1\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e加粗：\u003cstrong\u003etest\u003c/strong\u003e\u003cbr\u003e\n横线：\u003cdel\u003etest\u003c/del\u003e\u003cbr\u003e\n斜体：\u003cem\u003etest\u003c/em\u003e\u003c/p\u003e\n\u003ch1 id=\"标题1\"\u003e标题：1\u003c/h1\u003e\n\u003ch2 id=\"标题11\"\u003e标题：1.1\u003c/h2\u003e\n\u003ch3 id=\"标题111\"\u003e标题：1.1.1\u003c/h3\u003e\n\u003ch4 id=\"标题1111\"\u003e标题：1.1.1.1\u003c/h4\u003e\n\u003ch5 id=\"标题11111\"\u003e标题：1.1.1.1.1\u003c/h5\u003e\n\u003ch6 id=\"标题111111\"\u003e标题：1.1.1.1.1.1\u003c/h6\u003e\n\u003cp\u003e$~~$缩进\u003c/p\u003e\n\u003cp\u003e节点：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ea\u003c/li\u003e\n\u003cli\u003eb\n\u003cul\u003e\n\u003cli\u003eba\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e序号：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003ea\u003c/li\u003e\n\u003cli\u003eb\n\u003col\u003e\n\u003cli\u003ec\u003c/li\u003e\n\u003cli\u003ed\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e分割线\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003e链接：\u003ca href=\"http://www.baidu.com/\" title=\"点我\"\u003e点我\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003e链接：\u003ca href=\"http://www.baidu.com/\"\u003e[id]\u003c/a\u003e\u003cbr\u003e\nsomething\u003cbr\u003e\nsomething\u003c/p\u003e\n\u003cp\u003e图片：\u003ccode\u003e[![desc](/path/to/img.png)](http://www.baidu.com/ \u0026quot;desc\u0026quot;)\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e引用：\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eline 1\u003cbr\u003e\nline 2\u003c/p\u003e\u003c/blockquote\u003e\n\u003cp\u003eada\u003c/p\u003e\n\u003cp\u003e代码\u003ccode\u003efunc(int a, int b)\u003c/code\u003e\u003c/p\u003e\n\u003cp\u003e代码块：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003edef\u003c/span\u003e \u003cspan class=\"nf\"\u003efunc\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eb\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\t\u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003edef\u003c/span\u003e \u003cspan class=\"nf\"\u003efunc\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eb\u003c/span\u003e\u003cspan class=\"p\"\u003e):\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ec\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;abc\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003ea\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003eb\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e表格：\u003c/p\u003e\n\u003ctable\u003e\n  \u003cthead\u003e\n      \u003ctr\u003e\n          \u003cth style=\"text-align: left\"\u003ec1\u003c/th\u003e\n          \u003cth style=\"text-align: right\"\u003ec2\u003c/th\u003e\n          \u003cth style=\"text-align: center\"\u003ec3\u003c/th\u003e\n      \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e1\u003c/td\u003e\n          \u003ctd style=\"text-align: right\"\u003e2\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003e3\u003c/td\u003e\n      \u003c/tr\u003e\n      \u003ctr\u003e\n          \u003ctd style=\"text-align: left\"\u003e2\u003c/td\u003e\n          \u003ctd style=\"text-align: right\"\u003e2\u003c/td\u003e\n          \u003ctd style=\"text-align: center\"\u003e3\u003c/td\u003e\n      \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\u003cp\u003ehtml转换：\u003cbr\u003e\n♥\u003c/p\u003e\n\u003cp\u003e分页符：\u003c/p\u003e\n\u003cp\u003e[========]\u003c/p\u003e\n\u003cp\u003eabc\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-markdown\" data-lang=\"markdown\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e目录：\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    标题：1标题：1.1标题：1.1.1标题：1.1.1.1标题：1.1.1.1.1标题：1.1.1.1.1.1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e加粗：**test**  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e横线：~~test~~  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e斜体：*test*  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"gh\"\u003e# 标题：1  \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"gh\"\u003e\u003c/span\u003e\u003cspan class=\"gu\"\u003e## 标题：1.1  \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"gu\"\u003e### 标题：1.1.1  \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"gu\"\u003e#### 标题：1.1.1.1  \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"gu\"\u003e##### 标题：1.1.1.1.1  \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"gu\"\u003e###### 标题：1.1.1.1.1.1  \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"gu\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e$~~$\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e节点：  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e-\u003c/span\u003e a  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e-\u003c/span\u003e b  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"k\"\u003e-\u003c/span\u003e ba  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e序号：  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e1.\u003c/span\u003e a\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e2.\u003c/span\u003e b  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   \u003cspan class=\"k\"\u003e1.\u003c/span\u003e c\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   \u003cspan class=\"k\"\u003e2.\u003c/span\u003e d  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e分割线  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e------------\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e链接：[\u003cspan class=\"nt\"\u003e点我\u003c/span\u003e](\u003cspan class=\"na\"\u003ehttp://www.baidu.com \u0026#34;点我\u0026#34;\u003c/span\u003e)  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e链接：[[id]][linkid]  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esomething  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003esomething\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e[linkid]: http://www.baidu.com\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e图片：  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e[\u003cspan class=\"nt\"\u003e![desc\u003c/span\u003e](\u003cspan class=\"na\"\u003e../../1.PNG\u003c/span\u003e)](http://www.baidu.com \u0026#34;desc\u0026#34;)\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e引用：\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003e\u0026gt; \u003c/span\u003e\u003cspan class=\"ge\"\u003eline 1\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"ge\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003e\u0026gt; \u003c/span\u003e\u003cspan class=\"ge\"\u003eline 2\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"ge\"\u003e\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eada\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e代码\u003cspan class=\"sb\"\u003e`func(int a, int b)`\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e代码块：  \n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-markdown\" data-lang=\"markdown\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edef func(int a, int b)\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e{\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\treturn 0;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e}\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003edef func(a, b):\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    c = \u0026#34;abc\u0026#34;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    return a + b\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-markdown\" data-lang=\"markdown\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e表格：  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e| c1     |    c2  | c3 |\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e| :- | -: | :-: |\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e|    1 |    2 | 3|\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e|    2 |    2 |3|\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ehtml转换：\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"ni\"\u003e\u0026amp;hearts;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e分页符：\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e[========]\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eabc\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"tool.markdown.轻量级语言语法"},{"content":"感谢\n开源项目：https://gitee.com/careyjike_173/webssh\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/webssh/","summary":"\u003cp\u003e\u003cstrong\u003e感谢\u003c/strong\u003e\u003cbr\u003e\n开源项目：\u003ca href=\"https://gitee.com/careyjike_173/webssh\"\u003ehttps://gitee.com/careyjike_173/webssh\u003c/a\u003e\u003c/p\u003e","title":"tool.webssh.网页版SSH工具"},{"content":"目录：\n1 概述 1 概述 需求\n判断语法是否正确\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/tools/yacc/","summary":"\u003cp\u003e目录：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-%E6%A6%82%E8%BF%B0\"\u003e1 概述\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"1-概述\"\u003e1 概述\u003c/h1\u003e\n\u003cp\u003e\u003cstrong\u003e需求\u003c/strong\u003e\u003cbr\u003e\n判断语法是否正确\u003c/p\u003e","title":"tool.yacc.语法解析工具"},{"content":"目录 架构\nCPU\n内存管理\n进程线程\n文件系统\n目录\n1 CPU结构\n1.1 CPU结构 1.2 CPU寻址 2 内存管理\n2.1 内存申请 2.2 内存寻址 3 进程管理\n3.1 进程结构 3.2 进程调度 一、中断和异常 二、中断处理 三、系统调用 3.2 进程通信 3.3 锁 4 文件管理\n5 设备管理\n1 CPU结构 1.1 CPU结构 1.2 CPU寻址 5种寻址方式 直接寻址 : [1] 寄存器间接寻址 [bx] 寄存器相对寻址 [bx + 1] 基址变址寻址 [bx + si] 相对基址变址寻址 [bx + si + 1] 2 内存管理 2.1 内存申请 libc内部free list libc申请新逻辑页 内核使用伙伴算法，分配物理页，插入页表 2.2 内存寻址 逻辑地址 线性地址 物理地址 3 进程管理 3.1 进程结构 3.2 进程调度 一、中断和异常 进程状态转换 中断 时钟中断 IO中断 硬件故障 异常 陷入：有意识安排，返回下一条指令：系统调用 故障：可恢复错误，返回当前指令：缺页异常、段错误 终止：不可恢复错误、算术溢出、除0、… 二、中断处理 进程状态转换处理流程： 中断：保存当前进度，处理中断，返回下一条指令 cpu 取下一条指令 cpu 执行指令 cpu 执行一条指令后，扫描中断寄存器，查看是否有中断信号 如果有中断，中断硬件保存现场 中断硬件将触发器的内容送入PSW对应位置，查找中断向量表，调用中断处理程序 异常： 1.进入异常时： 保存处理器状态 准备高特权级执行环境 选择并执行合适的异常处理代码 2.处理异常时： 获取异常信息（调用参数、原因等） 3.结束异常时： 恢复处理器状态 返回低优先级 继续执行流 三、系统调用 系统调用：用户调用操作系统功能，包括进程管理、文件管理、设备管理等 系统调用方式：c函数库封装系统调用，用户调用c函数库。每个系统调用都有系统调用号 系统调用执行流程： 中断/异常机制：硬件保护现场，查找中断向量表，调用系统调用入口程序 系统调用入口程序：保存现场，参数压栈，查找系统调用表，调用系统调用例程或内核函数 执行系统调用例程 恢复线程，返回用户程序 3.2 进程通信 进程通信方式：\n信号\nkill(pid_t pid, int signum) /* 发送 */ signal(int signum, sig_handle_func()) /* 接收： 不阻塞，先恢复信号，再处理 */ sigaction(int signum, ...) /* 接收：阻塞，先处理，再恢复信号 */ 信号量\n2.1 无名信号量\nint sem_init(em_t *sem, int pshared, unsigned int value); /* 进程内,线程同步 */ int sem_wait(sem_t *sem); /* 加锁 */ int sem_post(sem_t *sem); /* 解锁 */ 2.2 有名信号量\nsem_t *sem_open(const char *name, int flag); 消息队列\nint msgget(key_t key, int msgflg); /* 创建 */ int msgsnd(int msqid, const void *data, size_t datasz, int msgflag); /* 发送 */ ssize_t msgrcv(int msqid, void *data, size_t datasz, long msgtype, int msgflag); /* 接收 */ 管道\n4.1 无名管道\nint pipe(inf fd[2]); /* 创建：0读1写 */ int write(int fd, void *data, size_t datasz); /* 发送 */ int read(int fd, void *data, size_t datasz); /* 接收 */ 4.2 有名管道\nint mkfifo(const char *file, mode_t mode); /* 创建 */ 共享内存 套接字 3.3 锁 线程锁 自旋锁 读写锁 线程死锁 预防 避免互斥访问 不允许持有并等待 不允许资源抢占 打破循环等待（按特定顺序获取资源） 解决 银行家算法 获取资源需管理者同意 管理者预演不会造成死锁 4 文件管理 文件系统崩溃一致性 一致性属性 持久化 原子性 有序性 一致性实现 日志 缺点：日志多次读写占用IO 改进：批量写日志 + 检查点 5 设备管理 分类 字符设备：LED、键盘、串口 顺序访问：内次读取一个字符 通过驱动与设备交互 块设备：内存、磁盘、u盘 随机访问：以块粒度进行读写 系统层增加缓冲区，避免与慢设备频繁交互 网络设备：网卡 面向格式化报文的收发 驱动以上维护多种协议 设备管理 字符抽象：文件系统：open/read/write/close 块抽象：文件系统、mmap 网络抽象：socket、文件系统：sockent/send/recv/close CPU与设备交互 可编程IO：cpu的in/out load/store指令 特点 消耗CPU时钟周期 与 数据量成正比 适合于小型设备 分类 PIO (port IO) IO设备具备独立的地址空间 使用特殊指令 in/out MMIO (Memory-mapped IO) 将设备映射到连续物理内存中 使用内存访问指令 行为与内存不完全一样，读写有副作用 直接内存访问 DMA：外设可直接访问总线 特点\nDMA与内存交互传输数据，无需CPU参与 适合与高吞吐量IO 结构\n[CPU] | [高速缓存] | ----+---------------+--------------+--------- 系统总线 | | [DMA控制器] [内存] | ----+---------------------------------------- PCI总线 | [外设] 读取步骤\n1.CPU中驱动发出请求，将设备数据读取至内存地址x 2.外设初始化DMA传递，将数据传送到数据DMA控制器 3.DMA将数据传送至内存地址x 4.DMA传输完成后，向CPU发出中断 5.PU执行每条指令后，检查中断是否到来 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/os/os-1-summary/","summary":"\u003ch1 id=\"目录\"\u003e目录\u003c/h1\u003e\n\u003col start=\"0\"\u003e\n\u003cli\u003e\n\u003cp\u003e架构\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eCPU\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e内存管理\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e进程线程\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e文件系统\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#%E7%9B%AE%E5%BD%95\"\u003e目录\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#1-CPU%E7%BB%93%E6%9E%84\"\u003e1 CPU结构\u003c/a\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-1-CPU%E7%BB%93%E6%9E%84\"\u003e1.1 CPU结构\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-CPU%E5%AF%BB%E5%9D%80\"\u003e1.2 CPU寻址\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#2-%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86\"\u003e2 内存管理\u003c/a\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#2-1-%E5%86%85%E5%AD%98%E7%94%B3%E8%AF%B7\"\u003e2.1 内存申请\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-2-%E5%86%85%E5%AD%98%E5%AF%BB%E5%9D%80\"\u003e2.2 内存寻址\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#3-%E8%BF%9B%E7%A8%8B%E7%AE%A1%E7%90%86\"\u003e3 进程管理\u003c/a\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#3-1-%E8%BF%9B%E7%A8%8B%E7%BB%93%E6%9E%84\"\u003e3.1 进程结构\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-2-%E8%BF%9B%E7%A8%8B%E8%B0%83%E5%BA%A6\"\u003e3.2 进程调度\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%80%E3%80%81%E4%B8%AD%E6%96%AD%E5%92%8C%E5%BC%82%E5%B8%B8\"\u003e一、中断和异常\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BA%8C%E3%80%81%E4%B8%AD%E6%96%AD%E5%A4%84%E7%90%86\"\u003e二、中断处理\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%89%E3%80%81%E7%B3%BB%E7%BB%9F%E8%B0%83%E7%94%A8\"\u003e三、系统调用\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-2-%E8%BF%9B%E7%A8%8B%E9%80%9A%E4%BF%A1\"\u003e3.2 进程通信\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#3-3-%E9%94%81\"\u003e3.3 锁\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#4-%E6%96%87%E4%BB%B6%E7%AE%A1%E7%90%86\"\u003e4 文件管理\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#5-%E8%AE%BE%E5%A4%87%E7%AE%A1%E7%90%86\"\u003e5 设备管理\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"1-cpu结构\"\u003e1 CPU结构\u003c/h1\u003e\n\u003ch2 id=\"11-cpu结构\"\u003e1.1 CPU结构\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"os-1-cpu\" loading=\"lazy\" src=\"/images/OS/os-1-summary/os-1-cpu.png\"\u003e\u003c/p\u003e\n\u003ch2 id=\"12-cpu寻址\"\u003e1.2 CPU寻址\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e5种寻址方式\n\u003cul\u003e\n\u003cli\u003e直接寻址 : [1]\u003c/li\u003e\n\u003cli\u003e寄存器间接寻址 [bx]\u003c/li\u003e\n\u003cli\u003e寄存器相对寻址 [bx + 1]\u003c/li\u003e\n\u003cli\u003e基址变址寻址 [bx + si]\u003c/li\u003e\n\u003cli\u003e相对基址变址寻址 [bx + si + 1]\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-内存管理\"\u003e2 内存管理\u003c/h1\u003e\n\u003ch2 id=\"21-内存申请\"\u003e2.1 内存申请\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003elibc内部free list\u003c/li\u003e\n\u003cli\u003elibc申请新逻辑页\n\u003cul\u003e\n\u003cli\u003e内核使用伙伴算法，分配物理页，插入页表\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cimg alt=\"os-2-1-malloc\" loading=\"lazy\" src=\"/images/OS/os-1-summary/os-2-1-malloc.png\"\u003e\u003c/p\u003e","title":"操作系统 1 总结"},{"content":"目录 架构\nCPU\n内存管理\n进程线程\n文件系统\n目录\n0 架构\n0.1 OS功能 0.2 OS特征 0.3 OS结构 0.4 OS分类 1 CPU\n1.1 CPU 结构 1.2 寄存器 1.3 汇编指令 1.4 程序 1.5 操作系统 2 内存管理\n结构 3 进程线程 1.1 概述 2 进程通信 2.1 分类 2.1 代码 一 信号 二 信号量 （Posix） 三 消息队列 四 管道 五 共享内存 六 套接字 2.3 命令 4 文件系统 0 架构 0.1 OS功能 从资源管理角度划分：\n进程/线程管理 内存管理 文件管理 设备管理 用户接口 0.2 OS特征 并发 共享 虚拟 随机：不可预测的事件，状态随机 0.3 OS结构 整体架构：\n应用程序 系统调用 OS内核 硬件 0.4 OS分类 批处理OS：任务串行 分时OS：任务时间片 实时OS：外部请求及时响应 个人计算机OS：任务通信、资源共享 网络操作OS： 分布式OS： 嵌入式OS： 1 CPU 1.1 CPU 结构 CPU 构成 运算器 控制器 寄存器：控制寄存器、状态寄存器 高速缓存 寄存器（8086 14个寄存器） 段寄存器（4）：CS, DS, SS, ES CS: 代码段寄存器 IP：指令寄存器 （CS + IP -\u0026gt; 代码地址） DS: 数据段寄存器 （DS + 地址 -\u0026gt; 数据地址） SS：栈寄存器 SP：栈顶寄存器 （SS + SP -\u0026gt; 栈顶寄存器） ES: 指针寄存器：IP, SP CPU寻址方式 直接寻址 : [1] 寄存器间接寻址 [bx] 寄存器相对寻址 [bx + 1] 基址变址寻址 [bx + si] 相对基址变址寻址 [bx + si + 1] CPU特权级别（x86架构支持4个cpu特权级别，不同级别支持的指令集不同） R0：内核态 R1: R2: R3: 用户态 CPU执行状态 状态分类 内核态：操作系统程序 用户态：用户程序 状态转换 转换类型 用户态 -\u0026gt; 内核态：中断，异常，陷入（操作系统提供给用户的接口） 内核态 -\u0026gt; 用户态：设置程序状态字PSW 中断：来自IO设备、其他硬件设备（硬件异步） 分类 IO中断 时钟中断 硬件故障 中断行为：保存当前进度，处理中断，返回下一条指令 cpu 取下一条指令 cpu 执行指令 cpu 执行一条指令后，扫描中断寄存器，查看是否有中断信号 如果有中断，中断硬件保存现场 中断硬件将触发器的内容送入PSW对应位置，查找中断向量表，调用中断处理程序 中断向量表 0-19：不可屏蔽中断和异常 0 除0 1 单步调试 4 算数溢出 6 非法操作数 12 栈异常 13 保护性错误 14 缺页异常 20-31：保留 32-127：外部中断 128：系统调用异常 \u0026lt;– （重要） 129-238：外部中断 239：本地APIC时钟中断 … 255 本地APIC伪中断 多核CPU处理中断 中断控制器 GIC Generic Interrupt Controller：全局中断的分发与管理，判断中断交给哪个CPU 异常（软件同步） 分类 陷入：有意识安排，返回下一条指令：系统调用 故障：可恢复错误，返回当前指令：缺页异常、段错误 终止：不可恢复错误、算术溢出、除0、… 异常处理 1.进入异常时： 保存处理器状态 准备高特权级执行环境 选择并执行合适的异常处理代码 2.处理异常时： 获取异常信息（调用参数、原因等） 3.结束异常时： 恢复处理器状态 返回低优先级 继续执行流 CPU指令类型 特权指令：启动IO、内存清0、修改程序状态字、设置时钟、允许/禁止中断 非特权指令：控制转移、算数运算、取数指令 1.2 寄存器 https://www.bilibili.com/video/BV1zW411n79C?p=7\u0026amp;spm_id_from=pageDriver\u0026amp;vd_source=027eab78efac77b882eeae0ff84cb89e\n单位：\n1 word 字 = 16位 = 2b 8086有14个寄存器，每个CPU 1 word\n通用寄存器（4）：AX,BC,CX,DX 寄存器功能：\n/* 1. 16位CPU 8086 */ typedef int WORD; /* WORD = 16 */ /* 2. CPU */ WORD _memory_[110240] = {0}; /*--------------------------------------*/ /* ---------------------* */ WORD AX; /* */ WORD BX; /* */ WORD CX; /* */ WORD DX; /* */ /* */ WORD SI; //字符串复制 /* */ WORD DI; /* */ /* */ WORD SS; WORD BP; WORD SP; /* ========= */ WORD stack_segment[1024] WORD CS; WORD IP; /* ========= */ WORD code_segment[4096]; WORD DS; /* [] */ /* */ WORD data_segment[4096]; WORD ES; /* */ /**************************/ BP是SS栈偏移 mv [bp] -\u0026gt; mv [ss + bp] /* ---------------------* */ /*-------------------------------------*/ 1.3 汇编指令 #define SP__ (stack_segment[SP]) #define IP__ (code_segment[IP]) /* 取地址 mov ax [0x0f] */ #define l_l(a) (data_segment[DS + a]) /* [a], [a + 1]处理数组 */ /* decleare */ #define dw(a, ...) (code_segment[0] = a; code_segment[1] = b) /* decleare word */ #define db(str) (code_segment[0] = str[0]; code_segment[1] = str[1]) /* decleare bytes */ /* 汇编指令 */ #define mov(a, b) (a = b) #define add(a, b) (a += b) #define sub(a, b) (a -= b) #define push(a) {SP -= 2; SP__ = a;} #define pop(a) {a = SP__; SP += 2;} // a 用于接收出栈的数据 #define inc(a) (a++) #define loop(pos) (CX--; if CX != 0 goto pos) /* see func doloop() */ #define and(a, b) #define or(a, b) #define _int(a) 1.4 程序 从代码到执行的流程\n编写 编译 链接（可执行文件） 执行 编译过程\nint main() { int b = 2 * 2 * 2; return 0; } 编译结果\nassume cs:abc ; 声明代码段 abc segment mov ax, 2 add ax, ax add ax, ax mov ax, 4c00h ; 程序返回值 int 21H ; 中断 abc ends end 循环\nassume cs:abc ; 声明代码段 abc segment mov ax, 2 mov cx, 11 ; cx 用于计算循环 s: add ax, ax loop s mov ax, 4c00h ; 程序返回值 int 21H ; 中断 abc ends end 代码段中存放数据\nassume cs:codesg codesg segment dw 1, 2, 3, 4 /* 这四个数存放在代码段中，位置在代码段起始位置 */ start mov ax,0 /* 使用start关键字，设置代码段指令起始位置，防止CPU将上述数据读为code */ codesg ends end start /* end可声明代码从哪开始执行 */ 代码段，数据段，栈段\nassume cs:code1, ds:data1, ss:stack1 ; 声明 data1 segment dw 1,2,3,4 data1 ends stack1 segment dw 0,0,0,0 stack1 ends code1 segment start mov ax, stack1 mov ss, ax mov ax, data1 mov ds, ax code1 ends end start 寻址：\nreg : 通用寄存器\nsreg : 段寄存器\nip是特殊寄存器\nreg：ax bx cx sp bp si di\nsreg: ds ss cs es\n可用于内存单元寻址：bx bp si di\n单独或4种组合出现：bx,si bx,di bp,si bp,di\nmov [bp] = mov ss:[bp]\ncpu寻址方式：\n直接寻址 : [1] 寄存器间接寻址 [bx] 寄存器相对寻址 [bx + 1] 基址变址寻址 [bx + si] 相对基址变址寻址 [bx + si + 1] 强制类型转换：\nmv word ptr ax 1\ndiv [除数]\n参数长度（位）\n除数 被除数\n8 16 (存放在ax中)\n16 32 (存放在dx和ax中)\nax放商，dx放余数\n8086转移指令：\n无条件转移 jmp 条件转移 循环指令 loop 过程 即函数 中断 编译器指令offset\n以一段代码段为例：\nstart: mov ax,offset start ; 等价于 mov ax 0\ns: mov ax,offset s ; 等价于mov ax,3\njmp 无条件转移\n实现：修改ip，或修改 cp 和 ip jmp short 标号\n段内段转移，IP修改范围为[-128, 127]\n示例：\nstart: mov ax,0\njmp short s ; 无条件转移到s （内部实现：从当前位置开始算，按偏移地址转移）\nadd ax,1\ns: inc ax\n(内部实现：ip += offset s - offset MYSELF)\n1.5 操作系统 https://www.bilibili.com/video/BV1D441117ib?p=8\u0026amp;spm_id_from=pageDriver\u0026amp;vd_source=027eab78efac77b882eeae0ff84cb89e\nCPU状态： 内核态：操作系统程序 用户态：用户程序 CPU指令类型： 特权指令：启动IO、内存清0、修改程序状态字、设置时钟、允许/禁止中断 非特权指令：控制转移、算数运算、取数指令 CPU特权级别：x86架构支持4个cpu特权级别，不同级别支持的指令集不同 R0：内核态 R1: R2: R3: 用户态 CPU状态转换： 用户态 -\u0026gt; 内核态：中断，异常，陷入（操作系统提供给用户的接口） 内核态 -\u0026gt; 用户态：设置程序状态字PSW 中断类型：来自IO设备、其他硬件设别（） IO中断 时钟中断 硬件故障 中断行为：保存当前进度，处理中断，返回下一条指令 cpu 取下一条指令 cpu 执行指令 cpu 执行一条指令后，扫描中断寄存器，查看是否有中断信号 如果有中断，中断硬件保存现场 中断硬件将触发器的内容送入PSW对应位置，查找中断向量表，调用中断处理程序 中断向量表： 0-19：不可屏蔽中断和异常 0 除0 1 单步调试 4 算数溢出 6 非法操作数 12 栈异常 13 保护性错误 14 缺页异常 20-31：保留 32-127：外部中断 128：系统调用异常 \u0026lt;– （重要） 129-238：外部中断 239：本地APIC时钟中断 … 255 本地APIC伪中断 异常分类： 陷入：有意识安排，返回下一条指令 故障：可恢复错误，返回当前指令 终止：不可恢复错误 异常举例： 系统调用 页故障/页错误 断点指令 程序性异常：算术溢出、除0、… 系统调用功能：用户调用操作系统功能，包括进程管理、文件管理、设备管理等 系统调用方式：c函数库封装系统调用，用户调用c函数库。每个系统调用都有系统调用号。 系统调用执行流程： 中断/异常机制：硬件保护现场，查找中断向量表，调用系统调用入口程序 系统调用入口程序：保存现场，参数压栈，查找系统调用表，调用系统调用例程或内核函数 执行系统调用例程 恢复线程，返回用户程序 2 内存管理 结构 分段 设计\n虚拟地址分为若干大小的段 段表存储分段信息 每个进程1个段表，操作系统1个全局段表 实现\n虚拟地址为：[段号 + 段内偏移]（段号-\u0026gt;段基址 + 段内偏移） 物理地址：以段为单位分配 - 段表 --------+--------+-------- 段号 | 段基址 | 段长度 --------+--------+-------- 0 | 0x... | 2k 1 | 0x... | 5k --------+--------+--------- 优点\n逻辑连续 缺点\n分段粒度粗，容易产生外部碎片 分页 设计\n物理内存划分为连续、等长的物理页 虚拟页与物理页大小相等 虚拟页可映射至任意物理页 每个进程1个页表（或1级页表） 实现\n[虚拟页号 + 页内偏移] - 页表 --------+---------- 虚拟页号 | 物理页号 --------+---------- 0 | 10 1 | 13 --------+---------- 优点\n解决外部碎片 应用程序时空局限性：执行时，使用的数据或代码是连续的 缺点\n页表过大（解决：多级页表 -\u0026gt; 剪枝） 多级页表：[虚拟页号_0:虚拟页号_1:虚拟页号_2:虚拟页号_3 + 页内偏移] 优化\nTLB （性能）\n位置：位于CPU内部 功能：缓存虚拟页号到物理页号的映射关系 作用：先查TLB，如果TLB未命中，再查缓存 刷新：切换页表时，刷新全部TLB（优化：TLB缓存项记录页表标签，切换页表时无需全部刷新） [CPU] --\u0026gt; [TLB] --\u0026gt; [页表] [p3] [p9] [p5] 结构：根据CPU缓存 L1 L2 L3 分级结构 -\u0026gt; TLB 也是分级结构 swapping （大小）\n功能：虚拟内存 \u0026gt; 物理内存时，将内存页存放到磁盘 算法：FIFO、LRU/MRU、Clock 缺页异常 （稳定）\n原因：物理内存需求过大 处理：等待磁盘IO，将物理页读取至内存 伙伴系统（利用率）\n问题：外部碎片：空闲但不连续；内部碎片：分配空间过大 实现：分裂与合并 - 伙伴系统 时间1： [ ] 时间2： [ ] [ ] 时间3： [ ] [ ] 空闲链表：较大空间分裂时，将多余的部分移入上一空间数组链表\n- 空闲数组链表 [ 2^0 ] [ 2^1 ] -\u0026gt; [] -\u0026gt; [] [ 2^2 ] -\u0026gt; [] 写时复制（共享）\n3 进程线程 1.1 概述 进程 定义：Process/Task/Job 定义：某个数据集合上一次运行活动。资源分配单位。\n实现：进程控制块 Process Control Block PCB：进程描述符，进程属性\n基本信息：pid, 进程名，userid CPU现场：寄存器，程序计数器，状态字PSW，栈指针，页表指针 控制信息：状态，优先级，代码执行入口，程序磁盘地址，运行统计信息（执行时间，页面调度），进程同步与通信，进程队列指针，进程消息队列指针 资源信息：虚拟地址空间，打开的文件 状态：\n分类：\n就绪态：CPU不空闲 -\u0026gt; 运行：被调度程序选中 运行态： -\u0026gt; 就绪：时间片用完，高优先级抢占 -\u0026gt; 等待：系统调用、IO、进程通信、… 等待态：阻塞 -\u0026gt; 就绪：等待事件发生 创建态： 终止态：进程结束，统计运行信息，资源回收 挂起态：调节负载）（进程映像交换到磁盘） linux 进程状态：\nfork() -\u0026gt; 就绪态 -\u0026gt; 运行态 +--\u0026gt; 浅度睡眠 --+ | | +--\u0026gt; 深度睡眠 --+ | |--\u0026gt; 就绪态 （wake_up / 信号） +--\u0026gt; 暂停 --+ | | +--\u0026gt; 僵尸 --+ 就绪-\u0026gt;运行：schedule() 运行-\u0026gt;就绪：时间片结束 运行-\u0026gt;浅度睡眠：等待资源，interruptible_sleep_on()，schedule() 运行-\u0026gt;深度睡眠：等待资源，sleep_on()，schedule() 运行-\u0026gt;暂停：ptrace调试，schedule() 进程队列\n进程状态改变：从一个队列出队，进入另一个队列\n等待队列：等待事件不同，有多个等待队列\n进程生命周期\n创建 fork/exec：分配pid，分配pcb，复制父进程地址空间（linux优化：当子进程要写父进程地址时，才复制地址空间），继承父进程共享资源(打开的文件，工作目录)，设置队列指针 阻塞 wait 等待子进程：自己执行阻塞原语 唤醒 挂起 激活 撤销 exit：关闭文件，回收内存，撤销pcb 进程切换\n进程地址空间\n--------- 用户地址空间 栈 . . . 堆 --------- 数据段 --------- 代码段 --------- ... ----------- 操作系统地址空间 内核栈 ----------- 内核代码 ------------ 上下文切换：将cpu硬件状态从一个进程换到另一个进程\n直接开销：保护和恢复寄存器、切换地址空间 间接开销：高速缓存失效、缓冲区缓存失效、TLB失效 进程通信\n信号 信号量 （锁） 消息队列 （传递数据 + 阻塞） 管道 （传递数据 + 阻塞） 共享内存 （传递数据 + 阻塞） 套接字 （传递数据 + 阻塞） 线程\n进程问题\n创建进程开销大：数据段、代码段、堆、栈段 进程隔离性强：IPC开销大 进程内部无法支持并行 线程优点\n构成：执行所需最小状态：寄存器和栈（每个线程有自己的栈，共享数据、代码、堆） 线程id，线程状态，线程上下文，线程栈和栈指针 开销小：创建和销毁，切换，通信 性能高：多处理器并发执行 线程模型（用户线程 与 内核线程）\n多对一 一对一：内核线程数量大 多对多 线程调度\n调度场景\n[t1] [CPU1] [t2] -\u0026gt; [调度器] -\u0026gt; [t3] [CPU2] 调度算法\n衡量标准\n吞吐量\n周转时间：请求 -\u0026gt; 运行\n响应时间：请求 -\u0026gt; 第一次回应\nCPU利用率\n等待时间：就绪 -\u0026gt; 运行\n算法分类\n算法类型\n算法 实现 优点 缺点 批处理系统 先来先服务 FCFS - 公平、简单 长任务不友好 最短作业优先 SJF - 最短平均周转 长任务不友好 最短剩余时间优先 SRTN 最高响应比优先 HRRN 响应时间 = （处理时间 + 等待时间） / 处理时间 交互式系统 时间片轮转 RR - 公平、响应快 进程切换开销高、IO进程不友好 （IO进程进入优先级高、独立就绪队列） 最高优先级 HPF 优先级动态或静态 - 低优先级饥饿、优先级反转（低优先级进程持有锁，高优先级进程抢占，低优先级无法执行） 多级反馈队列 MFQ 多个就绪队列，优先级依次降低，时间片依次增加，时间片轮转调度，高优先级优先调度 最短进程优先 操作系统\nOS 策略 unix 动态优先 BSD 多级反馈 Linux 抢占 Windows 32优先级抢占（优先级进入就绪队列） Solaris 综合调度 调度问题\n优先级反转\n使用临界区资源时： 优先级上限：优先级临时设为最高 优先级继承：临时继承最高优先级 禁止中断：禁止被抢占 线程通信\n临界区 要求 互斥访问 有限等待 空闲让进 算法 皮特森算法 (?)\n// 进程 0 while (1) { flag[0] = true; turn = 1; while (flag[1] == true \u0026amp;\u0026amp; turn == 1) { /* 临界区 */ flag[0] = false; } } // 进程 1 while (1) { flag[1] = true; turn = 0; while (flag[0] == true \u0026amp;\u0026amp; turn == 0) { /* 临界区 */ flag[1] = false; } } 硬件原子\n概念 不可被打断的操作集合 其他核心不会看到中间状态 实现 intel 锁总线 arm LL/SC 线程锁 自旋锁 读写锁 线程死锁 预防 避免互斥访问 不允许持有并等待 不允许资源抢占 打破循环等待（按特定顺序获取资源） 解决 银行家算法 获取资源需管理者同意 管理者预演不会造成死锁 多核缓存\n[ cpu 0 ] [ cpu 1 ] [ cpu 2 ] [ cpu 3 ] [l1 cache] [l1 cache] [l1 cache] [l1 cache] [ l2 cache ] [ l2 cache ] [ l3 cache ] [ 内存 ] 缓存一致性 原则\n独占修改 cpu核独占缓存行：本地可读可写 其他核读需迁移到共享 其他核写需迁移到失效 共享 多核拷贝缓存行 本地可读 本地写迁移到独占修改，使其他核缓存行失效 其他核写需迁移到失效 失效 本地缓存行失效 本地不能读/写缓存行 本地读需迁移到共享，其他核需迁移到共享 本地写需迁移到独占修改，其他核该行失效 通知其他核\n全局缓存：记录缓存行拥有者信息 | dirty cpu1 cpu2 cpu3 | |0 1 1 1 | | 状态 内容 | | 状态 内容 | | 状态 内容 | cpu1 cpu2 cpu3 pthread_yield：让出cpu\n进程优先级：动态优先级，静态优先级\n2 进程通信 2.1 分类 2.1 代码 一 信号 // 发送 kill(pid_t pid, int signum) // 接收 signal(int signum, sig_handle_func()) /* 不阻塞，先恢复信号，再处理 */ sigaction(int signum, ...) /* 阻塞，先处理，再恢复信号 */ 二 信号量 （Posix） #include \u0026lt;semaphore.h\u0026gt; // 初始化 int sem_init(sem_t *sem, int pshared, unsigned int value); /* 0：进程内线程同步 */ int sem_destroy(sem_t *sem); // 上锁 int sem_wait(sem_t *sem); // 解锁 int sem_post(sem_t *sem); // 创建 （有名信号量） sem_t *sem_open(const char *name, int flag); int sem_close(sem_t *sem); int sem_unlink(const char *name); // 其他 int sem_trywait(sem_t *sem); int sem_timewait(sem_t *sem); 三 消息队列 // 创建 int msgget(key_t key, int msgflg); /* flag: 访问权限 */ key_t ftok(const char *pathname int projid); // 发送 int msgsnd(int msqid, const void *data, size_t datasz, int msgflag); // 接收 ssize_t msgrcv(int msqid, void *data, size_t datasz, long msgtype, int msgflag); /* msgtype: 接收指定类型消息 */ // 删除、赋值、查询 msgctl(int msqid, int cmd, struct msqid_ds *buf); 四 管道 // 创建（匿名管道） int pipe(inf fd[2]); /* 0读1写 */ // 关闭 void close(int fd); // 发送 int write(int fd, void *data, size_t datasz); // 接收 int read(int fd, void *data, size_t datasz); /* 阻塞 */ // 创建 （命名管道: 对应真实文件） + open() int mkfifo(const char *file, mode_t mode); int mknode(const char *path, mode_t mode, dev_t device_type); /* 较老 */ 五 共享内存 六 套接字 2.3 命令 # 信号: 查看 kill -l # 命名管道 mkfifo FILE mkfifo FILE p 4 文件系统 文件系统 ext2\n架构\n磁盘 | 引导 | | 块组1 | 块组 (数据存储在block中) | 块组2 | \u0026lt; | 超级块 | | 快组. | | 组描述符 * n | | 块组n | | 块位图 | | inode位图 | inode （大小：128 / 256bytes，block数据可能会超过记录至） | inode * n | \u0026lt; | 文件类型 | | block * n | | 文件大小 | | 链接数 | 有多少文件名指向此inode | 文件权限 | | 时间 | (创建、修改、访问) | 1级指针 * 12 | -\u0026gt; block （block 为 4k时，最大单一文件为2T，文件系统容量为16T） | 2级指针 * 1 | | 3级指针 * 1 | | 4级指针 * 1 | 文件系统崩溃一致性\n一致性属性 持久化 原子性 有序性 一致性实现 日志 缺点：日志多次读写占用IO 改进：批量写日志 + 检查点 设备管理 分类 字符设备：LED、键盘、串口 顺序访问：内次读取一个字符 通过驱动与设备交互 块设备：内存、磁盘、u盘 随机访问：以块粒度进行读写 系统层增加缓冲区，避免与慢设备频繁交互 网络设备：网卡 面向格式化报文的收发 驱动以上维护多种协议 设备管理 字符抽象：文件系统：open/read/write/close 块抽象：文件系统、mmap 网络抽象：socket、文件系统：sockent/send/recv/close CPU与设备交互 可编程IO：cpu的in/out load/store指令 特点 消耗CPU时钟周期 与 数据量成正比 适合于小型设备 分类 PIO (port IO) IO设备具备独立的地址空间 使用特殊指令 in/out MMIO (Memory-mapped IO) 将设备映射到连续物理内存中 使用内存访问指令 行为与内存不完全一样，读写有副作用 直接内存访问 DMA：外设可直接访问总线 特点\nDMA与内存交互传输数据，无需CPU参与 适合与高吞吐量IO 结构\n[CPU] | [高速缓存] | ----+---------------+--------------+--------- 系统总线 | | [DMA控制器] [内存] | ----+---------------------------------------- PCI总线 | [外设] 读取步骤\n1.CPU中驱动发出请求，将设备数据读取至内存地址x 2.外设初始化DMA传递，将数据传送到数据DMA控制器 3.DMA将数据传送至内存地址x 4.DMA传输完成后，向CPU发出中断 5.PU执行每条指令后，检查中断是否到来 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/os/os-2-principles/","summary":"\u003ch1 id=\"目录\"\u003e目录\u003c/h1\u003e\n\u003col start=\"0\"\u003e\n\u003cli\u003e\n\u003cp\u003e架构\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eCPU\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e内存管理\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e进程线程\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e文件系统\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#%E7%9B%AE%E5%BD%95\"\u003e目录\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#0-%E6%9E%B6%E6%9E%84\"\u003e0 架构\u003c/a\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#0-1-OS%E5%8A%9F%E8%83%BD\"\u003e0.1 OS功能\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#0-2-OS%E7%89%B9%E5%BE%81\"\u003e0.2 OS特征\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#0-3-OS%E7%BB%93%E6%9E%84\"\u003e0.3 OS结构\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#0-4-OS%E5%88%86%E7%B1%BB\"\u003e0.4 OS分类\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#1-CPU\"\u003e1 CPU\u003c/a\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-1-CPU-%E7%BB%93%E6%9E%84\"\u003e1.1 CPU 结构\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-%E5%AF%84%E5%AD%98%E5%99%A8\"\u003e1.2 寄存器\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-3-%E6%B1%87%E7%BC%96%E6%8C%87%E4%BB%A4\"\u003e1.3 汇编指令\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-4-%E7%A8%8B%E5%BA%8F\"\u003e1.4 程序\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-5-%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F\"\u003e1.5 操作系统\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#2-%E5%86%85%E5%AD%98%E7%AE%A1%E7%90%86\"\u003e2 内存管理\u003c/a\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E7%BB%93%E6%9E%84\"\u003e结构\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"#3-%E8%BF%9B%E7%A8%8B%E7%BA%BF%E7%A8%8B\"\u003e3 进程线程\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-1-%E6%A6%82%E8%BF%B0\"\u003e1.1 概述\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-%E8%BF%9B%E7%A8%8B%E9%80%9A%E4%BF%A1\"\u003e2 进程通信\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#2-1-%E5%88%86%E7%B1%BB\"\u003e2.1 分类\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-1-%E4%BB%A3%E7%A0%81\"\u003e2.1 代码\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%80-%E4%BF%A1%E5%8F%B7\"\u003e一 信号\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BA%8C-%E4%BF%A1%E5%8F%B7%E9%87%8F-%EF%BC%88Posix%EF%BC%89\"\u003e二 信号量 （Posix）\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%89-%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97\"\u003e三 消息队列\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%9B%9B-%E7%AE%A1%E9%81%93\"\u003e四 管道\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BA%94-%E5%85%B1%E4%BA%AB%E5%86%85%E5%AD%98\"\u003e五 共享内存\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%85%AD-%E5%A5%97%E6%8E%A5%E5%AD%97\"\u003e六 套接字\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-3-%E5%91%BD%E4%BB%A4\"\u003e2.3 命令\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F\"\u003e4 文件系统\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"0-架构\"\u003e0 架构\u003c/h1\u003e\n\u003ch2 id=\"01-os功能\"\u003e0.1 OS功能\u003c/h2\u003e\n\u003cp\u003e从资源管理角度划分：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e进程/线程管理\u003c/li\u003e\n\u003cli\u003e内存管理\u003c/li\u003e\n\u003cli\u003e文件管理\u003c/li\u003e\n\u003cli\u003e设备管理\u003c/li\u003e\n\u003cli\u003e用户接口\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"02-os特征\"\u003e0.2 OS特征\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e并发\u003c/li\u003e\n\u003cli\u003e共享\u003c/li\u003e\n\u003cli\u003e虚拟\u003c/li\u003e\n\u003cli\u003e随机：不可预测的事件，状态随机\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"03-os结构\"\u003e0.3 OS结构\u003c/h2\u003e\n\u003cp\u003e整体架构：\u003c/p\u003e","title":"操作系统 2 原理"},{"content":"目录 整体架构\n物理层\n链路层\n传输层\n应用层\nsocket编程\n目录\n0 概述\n0.1 七层体系结构 0.2 报文基本原理 1 应用层\n1.1 HTTP协议 1.1.1 HTTP 结构 1.1.2 HTTP 应用 1.2 DNS 协议 2 传输层\n2.1 TCP 2.1.1 TCP 的结构 2.1.2 TCP 的应用 3 网络层\n3.1 IP 3.1 IP 协议 3.1.2 IP 路由 3.2 ICMP 4 链路层\n4.1 链路层背景 4.2 链路层结构 4.3 链路层功能 4.4 链路层设备 5 物理层\n6 socket编程\n6.1 基本接口 5.2 阻塞模型 场景 一 阻塞IO 二 非阻塞IO 三 IO多路复用 - select() 主动检查 四 信号驱动IO 五 异步IO 5.3 IO多路复用 5.3.1 select() 5.3.2 poll() 5.3.3 epoll() 0 概述 0.1 七层体系结构 计算机网络使用自顶向下的多层网络结构：\nISO-OSI体系结构 五层体系结构 TCP/IP协议簇 7 应用层 6 表示层 5 会话层 5 应用层 4 应用层 4 传输层 4 传输层 3 传输层 3 网络层 3 网络层 2 网络层 2 链路层 2 链路层 1 网络接口层 1 物理层 1 物理层 各层的作用如下：\n分层 作用 传输单位 功能 协议 设备 应用层 不同应用根据业务设计 数据单元 APDU - TCP：HTTP、Telnet、FTP、SMTP、POP、SSH；UDP：DNS、SNMP、TFTP - 表示层 编码解码，加密和压缩 PPDU 抽象标准描述方法、标准的编码方式 JPEG、MPEG、ASII - 会话层 进程会话 SPDU 建立、管理、终止会话 NFS、SQL、NETBIOS、RPC - 传输层 不同主机进程通信 TCP报文段、UDP数据段 端到端连接，可靠报文传输：流量控制、差错控制、传输管理 TCP：面向连接、可靠传输；UDP：无连接、不可靠报文传输 网关 网络层 网际互连 数据段 PACKET 网络互联、路由选择、数据分组/分包、流量控制、拥塞控制、差错控制 ARP、RARP、IGMP、IP、ICMP 路由器 链路层 数据段封装为帧，检测与校验物理传输差错 帧 Frame 组帧、差错控制、流量控制 、传输管理 PPP、FR、HDLC、VLAN、MAC 网桥、交换机 物理层 透明比特传输 比特 Bit 物理端设备 IEEE802.3、EIA-232C、X.21 转发器 在网络层，网络有以下几种：\n按范围划分： 局域网 LAN Local 域域网 MAN：如有线电视网 广域网 WAN Wide：如通信子网 因特网 0.2 报文基本原理 IP与TCP 其他协议 1 应用层 1.1 HTTP协议 1.1.1 HTTP 结构 # 请求 +---------+------------+--------------+ | Method | URI | HTTP Version | 请求行 +---------+------------+--------------+ | Header : Value | | Header : Value | 请求头 | ... | | (no line) | +-------------------------------------+ | Body | 请求体 +-------------------------------------+ # 响应 +--------------+--------+-------------+ | HTTP Version | Status | Status Desc | 状态行 +--------------+--------+-------------+ | Header : Value | | Header : Value | 响应头 | ... | | (no line) | +-------------------------------------+ | Body | 响应体 +-------------------------------------+ 请求方法\n请求方法 Method 功能 GET 请求指定页面，返回指定页面 PUT 向服务端发送指定数据 POST 提交请求，可能修改资源 HEADER 类似GET，只获取HTTP 相应头 DELETE 请求删除指定页面 OPTIONS 查看服务器性能 TRACE 回显服务器收到的请求，用于测试和诊断 HTTP 请求头\n请求头 Header 功能 示例 Accept 客户端可接受的类型 - Host 指定服务端的域名和端口 Host: www.baidu.com Cookie 发送请求者身份、会话等信息 Range 多线程下载使用，指定请求的内容的某部分 Referer 当前访问的URL的上一个URL HTTP 响应状态码\n分类 描述 具体值 1xx 请求已接收，正在处理 - 2xx 请求成功，返回正常 200 OK 3xx 请求成功，重定向 301 永久转移，302 暂时转移，304 已缓存 4xx 请求成功 400 请求语法有问题，403 拒绝请求，404 请求的内容不存在 5xx 服务器错误 500 服务器内部错误，503 服务不可用，稍等 1.1.2 HTTP 应用 一、GET和POST区别 区别 GET POST 请求参数 参数少，放在URL中，格式为：URL?参数\u0026amp;参数 参数多，放在Body中 安全性 安全性低 安全性高 二、Cookie\n问题：HTTP无状态，客户端需保存身份认证参数、业务状态等信息 使用场景：服务端向客户端发送 HTTP 响应头，可设置客户端的 Cookie。示例：’Set-Cookie: [; expires=date][; domain=domain][; path=path][; secure]’ 格式：cookie文本（非持久化cookie和持久化cookie），大小为4KB左右，存在于每个HTTP请求中 设置的Cookie选项 功能 Expires 设置Cookie生存周期 Domain cookie的作用域（域名） Path cookie的访问目录 Security HTTPS TTPOnly 不允许其他客户端读 三、浏览器工作原理\n浏览器：DNS查找：从浏览器缓存、路由器缓存、DNS缓存中查找 浏览器：HTTP请求：向服务器发送请求 服务器：处理请求、返回HTML 浏览器：显示HTML 1，应用（人接交互模块、解析器、HTTP(S)协议模块、存储模块 + DNS模块）：提取URL、HTTP协议【请求报文】、DNS、标准库中的套接字Socket（） 2，系统调用（Socket系统调用）：Socket系统调用 3，操作系统（忽略进程调度、内存管理等 - Linux网络协议栈 ：一，通用网络接口层（sk_buff）：不区分协议，统一封装；二，网络协议实现层：TCP【TCP三次握手】、IP、ARP等的具体实现， - （netfilter）三，虚拟设备接口层（file_struct）：通过net_device抽象网络硬件设备 4，计算机硬件（CPU执行、内存、设备（网络通信设备））：DMA到网络设备 中间链路（网络边缘、网络核心）：我的设备子网（交换机、路由器）、服务器（集分布式架构的集群） 服务器（（DNS服务器、KPI）内容分发器、连接处理器、数据库或文件服务器） ：身份认证和解密等、解析、获取文件、HTTP协议返回 1.2 DNS 协议 一、DNS 应用场景\n+---------+----------+---------+---------+ | 四级域名 | 三级域名 | 二级域名 | 顶级域名 | +---------+----------+---------+---------+ www com/net/org/edu/gov/cn/net/.. 域名管理\n1. 顶级域TLD有两种，通用域、国家或地区域。常用的通用域：.com(商业)、.edu(教育性机构)、.gov(政府)、.net(网络服务供应商)、.org(非营利性机构)、.int(国际性组织)、.mil(军事组织)。 2. 每个域自己控制如何分配它下面的域 3. 为了创建一个新的域，创建者必须得到该新域的上级域管理员的许可 域名服务器\n1. 每层都有自己的域名服务器，最顶层为根域名服务器 2. 每层域名服务器都知道下一层域名服务器的IP 3. 为了容灾，每层至少两个及以上域名服务器 域名解析：通常情况下，主机向本地域名服务器的查询一般都是采用递归查询，本地域名服务器向根域名服务器的查询通常采用迭代查询。\n1. 主机运行DNS客户进程 2. DNS进程向DNS服务器发送DNS查询报文 3. DNS服务器迭代查询或递归查询，域名服务器自身会进行一些缓存 4. 如果差不多，则向上一级查询，最多回溯到根域名服务器 域名解析示例\n1. 主机10.74.36.90先向本地域名服务器10.74.1.11进行递归查询 2. 本地域名服务器采用迭代查询，向一个根域名服务器进行查询 3. 根域名服务器告诉本地域名服务器，下一次应该查询的顶级域名服务器 dns.me的IP地址 4. 本地域名服务器向顶级域名服务器 dns.me进行查询 5. 顶级域名服务器me告诉本地域名服务器，下一步查询权限服务器dns.jocent.me 的IP地址 6. 本地域名服务器向权限服务器 dns.jocent.me进行查询 7. 权限服务器 dns.jocent.me告诉本地域名服务器所查询的主机的IP地址 8. 本地域名服务器最后把查询结果告诉 10.74.36.90 二、DNS 协议\n+-------------------+-------------------+ | Transcation ID | Flags | 请求和响应的Trans ID相同 | Question Count | Answers Count | | Authority | Additional | +-------------------+-------------------+ | Queries | +---------------------------------------+ | Answers | | Authoritative nameservers | | Additional records | +---------------------------------------+ 三、DNS 协议内容\nTranscation ID：会话标识，请求和响应Transcation ID相同\nFlags\n名称 比特 含义 AR 1 查询还是响应，0:查询，1:响应 OP 4 0:标准查询 1:反向查询 2:服务器状态请求 AA 1 授权回答 TC 1 可截断 RD 1 期望递归 RA 1 可用递归 RET 4 返回码 Queery:\n格式\n+-----------------------+ | Name | 域名 +-----------+-----------+ | Type | Class | +-----------------------+ Type\n类型 助记 说明 1 A 由域名获取IPV4地址 2 NS 查询域名服务器 5 CNAME 查询规范名称 6 SOA 开始授权 12 PTR 把IP转换为域名 13 HINFO 主机信息 28 AAAA 由域名获取IPV6地址 252 AXFR 传送整个区的请求 255 ANY 对所有记录的请求 2 传输层 2.1 TCP 2.1.1 TCP 的结构 +----------------------+-----------------------+ | Src Port | Dest Port | +----------------------------------------------+ | Sequence Number | +----------------------------------------------+ | Ack Number | +----------------------+-----------------------+ | HeaderLen | | Flags | Window Size | +----------------------+-----------------------+ | Checksum | Pointer | +----------------------------------------------+ | Options and Pending | +----------------------------------------------+ 1. TCP 标记位 标记名 含义 URG ACK PSH RST SYN FIN 2. TCP 连接\nTCP 三次握手\n客户端 服务端 --+-----------------------------------------+-------------- | set [LISTEN] | 1. SYN=1, seq=x -----------------------\u0026gt;| | set [SYN-SENT] | \u0026lt;------ 2. ACK=1, ack=x+1, SYN=1, seq=y | | set [SYN-RECV] | 3. ACK=1, ack=y+1, seq=x+1 -----------\u0026gt; | | set [ESTABLISHED] | set [ESTABLISHED] TCP 传输\n客户端 服务端 --+-----------------------------------------------------+-------------- | [seq=100, ask=500] | [seq=500, ask=100] # 记录已发送的序号，记录需要接收的序号 | 1. seq=100, datalen=15, ask=500, windows=20 --\u0026gt; | | [seq=115] | | [ask=115] | \u0026lt;-- 2. seq=500, datalen=13,ask=115, windows=10 | | [ask=513, seq=115] TCP 四次挥手\n客户端 服务端 --+-----------------------------------------+-------------- | set [ESTABLISHED] | 1. FYN=1, seq=x ----------------------\u0026gt; | | set [FIN-WAIT-1] | \u0026lt;------------- 2. ACK=1, ack=x+1, seq=y | | set [FIN-WAIT-2] | set [CLOSE-WAIT] | \u0026lt;-------------------------- remain data | | \u0026lt;------ 3. ACK=1, ask=x+1, FIN=1, seq=y | | set [LAST-ACK] | 4. ACK=1, ack=y+1, seq=x+1 -----------\u0026gt; | | set [TIME-WAIT] | set [CLOSED] | 2 MSL | set [CLOSED] 2.1.2 TCP 的应用 1. TCP 计时器 重传计时器：发送报文 -MSL- 接收到ACK 时间等待计时器：发送FIN - 2MSL- 无 持续计时器：接收0窗口 - 60s- 发送探测报文 保活计时器：保活 -2小时- 发送探测报文 -75-秒 2. TCP 可靠性\n超时重传机制（数据不丢） 问题：网络不可靠，数据可能丢\n解决：\n客户端（主动识别）：每发送1条数据，就设置1个重传计时器，如果指定时间没收到该条数据的回复，则重传。重传计时器的阈值可自适应 服务端：每接受到1条数据，回复1条确认信息 流程图：\n客户端 服务端 --+-----------------------------------------------------+-------------- | [seq=100, ask=500] | [seq=500, ask=100] | 1. seq=100, datalen=15, ask=500, windows=20 --\u0026gt; | | 2. seq=115, datalen=15, ask=500, windows=20 --\u0026gt; | | 3. seq=130, datalen=15, ask=500, windows=20 --\u0026gt; | | [seq=145] | | 假如，只收到前两条，则回复 ask=130 | | 假如，收到1，回复ask=115; 假如丢失2，收到3，仍然回复ask=115 | \u0026lt;-- 2. seq=500, datalen=13,ask=130, windows=10 | | 校验和 （数据不错） 2. TCP 流量控制\n拥塞控制（风险规避） 问题：网络负载低时，发送数据多；网络负载高时，发送数据少 解决机制：客户端维护拥塞窗口，网络无拥塞，拥塞窗口变大，网络有拥塞，拥塞窗口变小。根据拥塞窗口，调整发送数据。 解决算法： 慢开始：拥塞窗口从1开始，每次发送后，快速增大 拥塞控制：拥塞窗口到达阈值，每次发送后，慢速增大。如果发生超时，拥塞窗口设置为1，重新慢开始 快重传：如果收到3条重传某1报文的请求，说明是个别丢包。客户端不等重传计时器，尽快重传；服务端不等捎带确认，尽快回复 快恢复：如果收到3条重传某1报文的请求，说明是个别丢包。拥塞窗口不设置为1，而只缩小一半 滑动窗口 3. TCP 差错控制 3 网络层 3.1 IP 3.1 IP 协议 IP 报文结构 +-----------------------------------------------------------------------------+ | Version | HdrLen | Service | TotalLen | 长度信息 +-----------------------------------------------------------------------------+ | Fragment Identify | Fragment Flag | Fragment Offset | 分片信息 +-----------------------------------------------------------------------------+ | TTL | Protol | Checksum | 合法校验 +-----------------------------------------------------------------------------+ | Src Ip | | Dst Ip | +-----------------------------------------------------------------------------+ | Options | +-----------------------------------------------------------------------------+ IP 报文成员 版本号：4或6\n服务 Service：未使用\n分片标识 Fragment Identify：用于IP分片场景，相同标识的IP分片，可以组装在一起\n分片标志 Fragment Flag：\nMF=1,后面还有分片；MF=0，后面无分片 DF=1，不能分片；DF=0，可以分片 分片偏移 Fragment Offset：每个分片的位置\n存活周期 TTL：每经过1个路由器，TTL减1\n协议 Protol：\n取值 协议 1 ICMP 2 IGMP 4 IP 6 TCP 8 EGP 9 IGP 17 UDP 41 IPV6 89 89 可选参数 Options：差错、测量、安全\n3.1.2 IP 路由 问题场景：不同网络间，主机通信\n路由模型：\n[路由器] | | | [机器]--------------[路由器]---------------[路由器]------------------[机器] 路由表： +---------------+----------+-----+ | 目标网络-掩码 | 下一跳 | 接口 | +---------------+----------+-----+ | 11.0.0.0 - 8 | 2.2.2.2 | 0 | | 1.1.1.0 - 30 | 1.1.1.1 | 1 | | ... | ... | .. | +--------------------------------+ 路由表：每个路由器，维护1份路由表\n直连路由：直接连接的设备 静态路由：网络管理员手工配置 动态路由：路由协议自动获取 路由：https://blog.csdn.net/xiaobai729/article/details/122920727\n3.2 ICMP ICMP 功能：差错报告机制\nICMP 报文\n+-----------+--------------+------------+ | IP Header | ICMP Header | ICMP Data | +-----------+--------------+------------+ | | | ICMP Header +------+-------+----------+-----------+ | Type | Code | Checksum | Options | +------+-------+----------+-----------+ ICMP 类型\n0 Echo响应 查询类 3 目的不可达 差错类 [3, 0] 目标网络不可达 [3, 1] 目标主机不可达 [3, 3] 目标端口不可达 [3, 4] 要求分段并设置DF 5 重定向 差错类 8 Echo请求 查询类 9 路由器通告 查询类 10 路由器请求 查询类 11 ICMP超时 差错类 [11, 0] TTL超时 [11, 1] 分片重组超时 12 ICMP参数异常 差错类 13 时间戳请求 查询类 14 时间戳应答 查询类 15 信息请求 查询类 16 信息应答 查询类 4 链路层 4.1 链路层背景 物理层传输有以下问题：\n物理传输有差错，需采取纠错机制 网络容量不同，需采取流量控制 物理层传输介质不同，屏蔽物理层差异 物理层bit传输，传输效率低 4.2 链路层结构 LLC子层：逻辑链路控制 功能 逻辑链路建立与释放 控制信号交换 流量控制 解释上层协议命令 处理传输错误 阶段 链路建立 链路保持 链路释放 MAC子层：介质访问控制 数据帧封装与拆卸 帧的寻址和识别 帧的发送和接受 帧的差错控制 介质访问冲突 4.3 链路层功能 链路层有以下4个关键功能：\n数据帧封装\n帧大小：由最大传输单元 MTU 控制（IP包MTU为1500字节） 帧组装 字节计数法：1特殊字符代表帧开始，1字段表示帧内字节数 比特填充首尾定界法：帧头帧尾插入特定比特串 字符填充法首尾定界法：如SYN字符开头、EXT字符结尾 违法编码法 差错控制\n方法分类 奇偶校验码 PPC：判断1的个数是偶数还是奇数（奇偶校验位）\n缺点：检查单个码元错误，用于误码率低环境 循环冗余校验码 CRC（整除取余思想）\n1. 选择多项式 x^4 + x^3 ++ 1 -\u0026gt; 11001 2. 帧尾预留4个bit (少一位) 3. 帧内数据除 11001 差错纠正\n方法分类 反馈检测法 自动重发请求法 空闲重发 连续重发 纠错码：编码自带纠错能力 海明码：多个校验位 实现：计算校验位数 -\u0026gt; 明确校验码位置 -\u0026gt; 确定校验码 -\u0026gt; 实现校验纠错 流量控制\n场景：两端发送速度与接受速度不一致 方法分类 基于反馈的流量控制方案 停-等方案：XON/XOFF协议：发送端发送数据帧-\u0026gt;发送端等待-\u0026gt;接收端接受数据帧-\u0026gt;接收端向发送端发送确认帧-\u0026gt;发送端继续发送数据 基于速率的流量控制 滑动窗口机制 4.4 链路层设备 按发展规律与功能划分，链路层的常见设备有：\n集线器 特点 多次复制的广播传输 缺点 共享传输介质 端口带宽过窄 容易产生广播风暴 网桥 二层交换机 具有多个交换端口：数据只对目标节点发送 数据转发效率更高 更强的MAC地址自动学习能力 5 物理层 多路复用 频分多路复用 时分多路复用 6 socket编程 6.1 基本接口 https://blog.csdn.net/hguisu/article/details/7445768/\n// server int socket(int protofamily, int type, int protocol); int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); int listen(int sockfd, int backlog); int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen); int close(int fd); // 阻塞 ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count); ssize_t send(int sockfd, const void *buf, size_t len, int flags); ssize_t recv(int sockfd, void *buf, size_t len, int flags); ssize_t sendto(int sockfd, const void *buf, size_t len, int flags, const struct sockaddr *dest_addr, socklen_t addrlen); ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t *addrlen); ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags); ssize_t recvmsg(int sockfd, struct msghdr *msg, int flags); // client int socket(int protofamily, int type, int protocol); int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen); // 结构体 struct sockaddr_in { sa_family_t sin_family; // AF_INET in_port_t sin_port; struct in_addr sin_addr; }; struct in_addr { uint32_t s_addr; }; 5.2 阻塞模型 场景 https://www.jianshu.com/p/ed1f9e9a1982\n一 阻塞IO 原理：服务器发出请求，并阻塞自己，等待系统调用返回\nserver os-kernel +-----------------------+--------------------------- | 0. read(fd, buf) --\u0026gt; | | 1. 向设备发送请求(fd) | 2. 等待设备的信号(fd) # 阻塞 | 3. 复制设备的数据(fd, buf) | 4. buf \u0026lt;-- | 二 非阻塞IO 原理：服务器发出请求，不阻塞自己，定期检查系统调用结果\nserver os-kernel +-----------------------+--------------------------- | 0. read(fd, buf) --\u0026gt; | | 1. 向设备发送请求(fd) | # 不阻塞 | 2. 等待设备的信号(fd) # 阻塞 | 0. read(fd, buf) --\u0026gt; | | 3. 复制设备的数据(fd, buf) | 4. buf \u0026lt;-- | 三 IO多路复用 - select() 主动检查 原理：一个进程，监听多个描述符，描述符就绪时通知进程\n实现：select(), poll(), epoll()\nserver os-kernel +---------------------------+--------------------------- | 1. fd1 = accept() --\u0026gt; | | 2. fd2 = accept() --\u0026gt; | | 3. [..., fd1, ..., fd2, ...] | 4. select([fd1, fd2]) --\u0026gt; | | 5. if one fd receive data: return | \u0026lt;-- 6. [..., 1, ..., 0] | | 7. read(fd1) --\u0026gt; | | \u0026lt;-- 8. data | 四 信号驱动IO 五 异步IO app kernel +-----------------------+--------------------------- | 1. fd = accept() --\u0026gt; | | 2. [fd, ] | 3. aio_read(fd) --\u0026gt; | | 4. if not fd.data: return | \u0026lt;-- 5. no data | | 6. signal(app) | 7. signal_handle() | 5.3 IO多路复用 函数：\nselect()：一次调用，检查所有文件句柄，返回活跃的文件句柄 poll()：一次调用，检查所有文件句柄，返回活跃的文件句柄 epoll：文件句柄绑定回调函数，活跃的文件句柄自动调用回调函数 5.3.1 select() // 内核 FDS[] = [fd_1, fd_2, fd_3, fd_4, fd_5, ...] FDSET = [false, false, false, false, false, ...] // 内核接口：遍历FDS，返回哪些FDS接收到了数据 int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); // 内核实现, fd_num最大为100 int select(maxfd, readfd, NULL, NULL, NULL) { int num = 0; for (int i = 0; i \u0026lt; maxfd; i++) { /* 阻塞与非阻塞 */ if (readfds[i] == 1) { readfds[i] = len(FDS[i].data) \u0026gt; 0 ? 1 : 0; num += len(FDS[i].data) \u0026gt; 0 ? 1 : 0; } } return num; } // 用户调用 void fetch_data() { fd_set rfds; int fd1 = accept(); int fd2 = accept(); int fd3 = accept(); for (;;) { FD_ZERO(\u0026amp;rfds); FD_SET(fd1, \u0026amp;rfds); FD_SET(fd2, \u0026amp;rfds); FD_SET(fd3, \u0026amp;rfds); select(fd3 + 1, \u0026amp;rfds, NULL, NULL, NULL); /* block here */ if (FD_ISSET(fd1, \u0026amp;rfds)) { read(fd1, ...); } if (FD_ISSET(fd2, \u0026amp;rfds)) { read(fd2, ...); } } } 5.3.2 poll() 5.3.3 epoll() // 用户调用 epoll工作模式\n场景：\nt1:\nbuff = [xxxxxxx_______]\nt2:\nread(buff)\nt3:\nbuff = [xxxx__________]\n分类：\nlevel-trigger: t3 可读 edge-trigger: t3 不可读\nwhile(buff.len \u0026gt; 0) {\nread(buff)\n} ","permalink":"https://my-blog.j8465383071.workers.dev/posts/network/network-1-summary/","summary":"\u003ch1 id=\"目录\"\u003e目录\u003c/h1\u003e\n\u003col start=\"0\"\u003e\n\u003cli\u003e\n\u003cp\u003e整体架构\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e物理层\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e链路层\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e传输层\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e应用层\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003esocket编程\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#%E7%9B%AE%E5%BD%95\"\u003e目录\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#0-%E6%A6%82%E8%BF%B0\"\u003e0 概述\u003c/a\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#0-1-%E4%B8%83%E5%B1%82%E4%BD%93%E7%B3%BB%E7%BB%93%E6%9E%84\"\u003e0.1 七层体系结构\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#0-2-%E6%8A%A5%E6%96%87%E5%9F%BA%E6%9C%AC%E5%8E%9F%E7%90%86\"\u003e0.2 报文基本原理\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#1-%E5%BA%94%E7%94%A8%E5%B1%82\"\u003e1 应用层\u003c/a\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-1-HTTP%E5%8D%8F%E8%AE%AE\"\u003e1.1 HTTP协议\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#1-1-1-HTTP-%E7%BB%93%E6%9E%84\"\u003e1.1.1 HTTP 结构\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-1-2-HTTP-%E5%BA%94%E7%94%A8\"\u003e1.1.2 HTTP 应用\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#1-2-DNS-%E5%8D%8F%E8%AE%AE\"\u003e1.2 DNS 协议\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#2-%E4%BC%A0%E8%BE%93%E5%B1%82\"\u003e2 传输层\u003c/a\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#2-1-TCP\"\u003e2.1 TCP\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#2-1-1-TCP-%E7%9A%84%E7%BB%93%E6%9E%84\"\u003e2.1.1 TCP 的结构\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#2-1-2-TCP-%E7%9A%84%E5%BA%94%E7%94%A8\"\u003e2.1.2 TCP 的应用\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#3-%E7%BD%91%E7%BB%9C%E5%B1%82\"\u003e3 网络层\u003c/a\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#3-1-IP\"\u003e3.1 IP\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#3-1-IP-%E5%8D%8F%E8%AE%AE\"\u003e3.1 IP 协议\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-1-2-IP-%E8%B7%AF%E7%94%B1\"\u003e3.1.2 IP 路由\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#3-2-ICMP\"\u003e3.2 ICMP\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#4-%E9%93%BE%E8%B7%AF%E5%B1%82\"\u003e4 链路层\u003c/a\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#4-1-%E9%93%BE%E8%B7%AF%E5%B1%82%E8%83%8C%E6%99%AF\"\u003e4.1 链路层背景\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-2-%E9%93%BE%E8%B7%AF%E5%B1%82%E7%BB%93%E6%9E%84\"\u003e4.2 链路层结构\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-3-%E9%93%BE%E8%B7%AF%E5%B1%82%E5%8A%9F%E8%83%BD\"\u003e4.3 链路层功能\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#4-4-%E9%93%BE%E8%B7%AF%E5%B1%82%E8%AE%BE%E5%A4%87\"\u003e4.4 链路层设备\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#5-%E7%89%A9%E7%90%86%E5%B1%82\"\u003e5 物理层\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003ca href=\"#6-socket%E7%BC%96%E7%A8%8B\"\u003e6 socket编程\u003c/a\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#6-1-%E5%9F%BA%E6%9C%AC%E6%8E%A5%E5%8F%A3\"\u003e6.1 基本接口\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#5-2-%E9%98%BB%E5%A1%9E%E6%A8%A1%E5%9E%8B\"\u003e5.2 阻塞模型\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%9C%BA%E6%99%AF\"\u003e场景\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%80-%E9%98%BB%E5%A1%9EIO\"\u003e一 阻塞IO\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BA%8C-%E9%9D%9E%E9%98%BB%E5%A1%9EIO\"\u003e二 非阻塞IO\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%B8%89-IO%E5%A4%9A%E8%B7%AF%E5%A4%8D%E7%94%A8-select-%E4%B8%BB%E5%8A%A8%E6%A3%80%E6%9F%A5\"\u003e三 IO多路复用 - select() 主动检查\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E5%9B%9B-%E4%BF%A1%E5%8F%B7%E9%A9%B1%E5%8A%A8IO\"\u003e四 信号驱动IO\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#%E4%BA%94-%E5%BC%82%E6%AD%A5IO\"\u003e五 异步IO\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#5-3-IO%E5%A4%9A%E8%B7%AF%E5%A4%8D%E7%94%A8\"\u003e5.3 IO多路复用\u003c/a\u003e\n\u003col\u003e\n\u003cli\u003e\u003ca href=\"#5-3-1-select\"\u003e5.3.1 select()\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#5-3-2-poll\"\u003e5.3.2 poll()\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"#5-3-3-epoll\"\u003e5.3.3 epoll()\u003c/a\u003e\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch1 id=\"0-概述\"\u003e0 概述\u003c/h1\u003e\n\u003ch2 id=\"01-七层体系结构\"\u003e0.1 七层体系结构\u003c/h2\u003e\n\u003cp\u003e计算机网络使用自顶向下的多层网络结构：\u003c/p\u003e","title":"计算机网络 1 总结"},{"content":"1 TLS协议支持第三方流量审计 1.1 功能简述 【需求背景】\nTLS协议，是保障通信安全的加密协议，可分为4个子功能：\n密钥生成：通过密钥交换或密钥协商等协议，让双方生成相同的密钥 身份认证：在开始阶段，双方均向对方发送自己的证书。双方接收证书后，基于PKI体系，校验证书是否合法。 数据加密：发送方发生数据前，使用密钥加密数据，发送数据密文。接受方接受密文后，使用密钥解密，获取数据。 数据校验：在加密数据的同时，生成数据完整性校验码，与数据密文拼接在一起。（简单理解：生成数据的哈希值，并使用密钥加密哈希值）接收方解密数据后，同样生成数据完整性校验码，与接收的相比，判断是否一致。 开源软件libssl.so提供TLS功能，应用只需调用接口，即可实现TLS协议。同时，libssl.so提供100+算法套件，可让应用选择不同的参数组合，1个算法套件，包含4个关键参数：\n密钥生成：密钥生成协议 身份认证：证书算法类型 数据加密：加密算法类型 数据校验：哈希算法类型 例如，libssl.so中，常用的算法套件为：ECDHE-RSA-AES128-SHA256，该套件中，参数的含义如下：\n密钥生成协议：ECDHE协议。（常见协议类型:DHE、ECDHE、RSA等） 证书算法类型：RSA 加密算法类型：AES-128 哈希算法类型：SHA-256 【需求分析】\nvastbase支持TLS协议，当vsql与vastbase通信时，双方可使用TLS模块，生成密钥，并使用密钥加密、解密通信数据，包括：SQL语句、SQL执行结果等。\n客户可能采用第三方工具，截取网络流量，获取传输中的SQL等数据，进行流量审计。但是，在使用TLS协议的情况下，网络中的数据是密文形式，无法进行流量审计。\nvastbase提供1个GUC参数ssl_ciphers，用于配置TLS协议采用的算法套件，旧版本，该参数的取值范围如下：\nECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-GCM-SHA256 DHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-SM4-CBC-SM3 4个仅tassl支持的国密算法套件 上述7个套件中，密钥生成协议为：ECDHE、DHE，此类DH协议，无法让第三方工具获取密钥。\n本版本，新增4个算法套件：\nAES128-SHA256 AES256-SHA256 AES128-GCM-SHA256 AES256-GCM-SHA384 上述4个套件，密钥生成协议为：RSA，该协议可让第三方工具获取密钥，使其可解密网络流量，获取SQL语句、SQL执行结果等。\n【需求实现】\n之前，vastbase限制ssl_ciphers的取值范围，仅放开7个算法套件，本版本，将新增放开4个算法套件。\n实现时，仅修改ssl_ciphers的取值范围，新增支持4个算法套件[AES128-SHA256、AES256-SHA256、AES128-GCM-SHA256、AES256-GCM-SHA384]，4个算法套件将直接传递给libssl.so，内核不做任何处理。\n因此，本需求无复杂设计。本文主要介绍完整的TLS协议工作原理。\n1.2 实现方案 一、ECDHE与RSA的区别 此处简化ECDHE与RSA的步骤与算法，提取最核心的原理，方便快速理解。\n一、ECDHE密钥协商协议\n第三方工具、攻击者完全无法获取密钥。\nclient server +-------------------------------------------+----------------------------------- | \u0026lt;---- 0. 双方随机约定一些公开参数 ------\u0026gt; | | 1. 生成随机私钥 client_priv | 2. 基于client_priv，计算公钥 client_pub | 3. 发送公钥 client_pub ------------\u0026gt; | 4. 接收公钥 client_pub | 5. 生成随机私钥 server_priv | 6. 基于server_priv，计算公钥 server_pub \u0026lt;------------ | 7. 发送公钥 server_pub | 8. 接收公钥 server_pub | 9. 基于client_priv，server_pub，计算密钥 | 10. 基于server_priv，client_pub，计算密钥 （第9步和第10步，可以计算出相同的密钥） 简单举个例子 client server +-------------------------------------------+----------------------------------- | \u0026lt;----- 0. generate and send (2,11) ----\u0026gt; | | 1. generate 8 | 2. caculate (8 * 2) % 11 = 5 | 3. send 5 ----------\u0026gt; | 4. receive 5 | 5. generate 10 | 6. caculate (10 * 2) % 11 = 9 \u0026lt;------------ | 7. send 9 | 8. receive 9 | 9. key = (8 * 9) % 11 = 6 | 10. key = (10 * 5) % 11 = 6 攻击者：截获网络流量，获取2,11,5,9，无法计算出密钥为6 二、RSA密钥交换协议\n第三方工具：配置步骤1中的server_priv，并截获步骤5中的enc_key，则可解密获取的密钥key。该密钥key将用于解密网络流量。\n攻击者：无法获取server_priv，则无法解密网络流量。\nclient server +-------------------------------------------+----------------------------------- | 1. 提前配置私钥、公钥 server_priv, server_pub \u0026lt;------------ | 2. 发送公钥 server_pub | 3. 生成密钥 key | 4. 使用公钥加密密钥 enc_key = enncrypt(key, server_pub) | 5. 发送密钥 enc_key --------\u0026gt; | 6. 接收密钥 enc_key | 7. 解密密钥 key = decrypt(enc_key, server_priv) 二、完整的TLS协议 完整的TLS协议如下图所示，其中：\n第21-47步，为完整的TLS协议，由libssl.so提供。本示例中，密钥协议为ECDHE。\n[user]-------------------------------------------- [client]------------------------------------------[server]----------------------------------------------- # 前提步骤：生成私钥、证书 1. 从安装包获取openssl工具 2. openssl随机生成ca.key 3. openssl根据ca.key，计算生成ca.cert 4. openssl随机生成私钥client.key 5. openssl根据client.key，计算生成client.cert - client.cert由ca.key签名，将由ca.cert验证签名 6. openssl随机生成私钥server.key 7. openssl根据server.key，计算生成server.cert - server.cert由ca.key签名，将由ca.cert验证签名 # 前置步骤：配置私钥、证书、算法套件 8. 设置GUC：ssl=on -------------------------------------------------------------------------------------\u0026gt; 9. 设置GUC：ssl_cert_file=server.cert ------------------------------------------------------------------\u0026gt; 10. 设置GUC：ssl_key_file=server.key -------------------------------------------------------------------\u0026gt; 11. 设置GUC：ssl_ca_file=ca.cert -----------------------------------------------------------------------\u0026gt; 12. 设置GUC：ssl_ciphers=\u0026#39;ECDHE-RSA-AES128-SHA256\u0026#39; -----------------------------------------------------\u0026gt; # 前置条件：配置私钥、证书 13. 设置环境变量：PGSSLMODE=verify-ca ----------------\u0026gt; 14. 设置环境变量：PGSSLCERT=client.cert --------------\u0026gt; 15. 设置环境变量：PGSSLKEY=client.key ----------------\u0026gt; 16. 设置环境变量：PGSSLROOTCERT=ca.cert --------------\u0026gt; 17. vsql -h $host -p $port -U $user -W $password --\u0026gt; # 阶段一、建立TCP连接 | 18. 获取$host, $port | 19. 与$host, $port 建立TCP连接 --------------------\u0026gt; | 20. 获取PGSSLMODE，判断是否使用SSL协议 # 阶段二、建立TLS连接（完全由第三方库libssl.so实现） | 21. 询问是否启用SSL协议 ---------------------------\u0026gt; | 22. 读取GUC：ssl=on | 23. 读取server.cert，server.key | \u0026lt;------------------------------ 24. 启用SSL协议 | 25. 生成随机数 $client_random | 26. 发送 [Client Hello] --------------------------\u0026gt; - 支持的最高TLS协议版本：1.2 - $client_random - 支持的密码套件: 默认12个 - - 其他 | 27. 接收 | 28. 生成随机数 $server_random | 29. 随机生成私钥 $server_priv | 30. 根据$server_priv，计算公钥$server_pub | 31. 根据客户端支持的密码套件，以及ssl_ciphers取值，选择算法套件 | 32. 用server.key对$client_random，$server_random，$server_pub签名，生成$server_signature | \u0026lt;--- 33. 发送 [Server Hello] [Cert] [Cert Request] - 选择的TLS协议版本：1.2 - $server_random - 选择的算法套件 - server.cert (用于身份认证) - 服务端支持的证书类型：RSA - $server_pub (用于生成密钥) - $server_signature | 34. 接收 | 35. 读取算法套件，根据算法套件，确定密钥生成协议 | 36. 随机生成私钥 $client_priv | 37. 根据$client_priv，计算公钥$client_pub | 38. 使用ca.cert，验证server.cert (身份认证) | 39. 使用server.cert，验证$server_signature | 40. 使用client.key对$client_random，$server_random，$client_pub等签名，生成$client_signature | 41. 使用$client_priv, $server_pub, $client_random, $server_random，计算$key (生成密钥) | 42. 发送 [Cert] [Key Exchange] [Cert Verify] [Cipher Spec] -----\u0026gt; - client.cert - $client_pub - $client_signature - $key准备就绪 | 43. 接收 | 44. 使用ca.cert，校验client.cert | 45. 使用client.cert，校验$client_signature | 46. 使用$server_priv, $client_pub, $client_random, $server_random，计算$key | \u0026lt;------------------------- 47. 发送 [Cipher Spec] - $key准备就绪 # （至此，双方之间的通信数据，将完全由$key加密，同时基于$生成完整性校验码） # 阶段三、身份认证 | 48. 随机生成 $client_nonce | 49. 使用$key，加密$client_nonce（同时生成完整性校验码，后面省略次步骤） | 50. 发送加密的$client_nonce | 51. 接收、解密（同时校验完整性校验码） | 52. 根据pg_authid系统表、pg_hba.conf，选择密码的hash算法 | 53. 随机生成 $server_nonce | 54. 从pg_authid获取$user 的 $salt,$iteration,$storedkey,$serverkey | 55. 使用$key 加密$server_nonce,$salt,$iteration | \u0026lt;----- 56. 发送加密的 $server_nonce,$salt,$iteration | 57. 接收、解密 | 58. 使用$password,$iteration,$salt等，计算$client_proof | 59. 使用$key 加密$client_proof | 60. 发送加密的 $client_proof ----------------------\u0026gt; | 61. 接受、解密 | 62. 根据$client_proof，生成$clientkey | 63. 校验$serverkey 与$clientkey 64. SELECT * FROM t1; ------------------------------\u0026gt; | 65. 使用$key，加密SQL语句 | 66. 发送加密后的SQL -------------------------------\u0026gt; | 67. 接收、解密 | ...(省略) 1.3 接口说明 修改1个GUC ssl_ciphers的取值范围 修改前： ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-GCM-SHA256 DHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-SM4-CBC-SM3 4个仅tassl支持的国密算法套件 修改后：新增4个取值 AES128-SHA256 AES256-SHA256 AES128-GCM-SHA256 AES256-GCM-SHA384 1.4 内存管理 不涉及\n1.5 安全 RSA协议安全性比ECDHE稍低，但RSA协议也是标准协议，且使用范围广，在HTTPS等中较常见。\n1.6 性能 几乎无影响。\n默认不生效，需单独配置ssl_ciphers，需求才生效。 仅修改密钥生成协议，影响TLS握手阶段，不影响数据传输阶段。 TLS握手阶段，RSA与ECDHE协议相比，网络交互次数相同，密钥生成速度接近。 1.7 专利 无\n1.8 升级管理 无适配。旧版本驱动，可正常连接新版本数据库。\n1.9 其他说明 无\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/10-design-ssl/","summary":"\u003ch1 id=\"1-tls协议支持第三方流量审计\"\u003e1 TLS协议支持第三方流量审计\u003c/h1\u003e\n\u003ch2 id=\"11-功能简述\"\u003e1.1 功能简述\u003c/h2\u003e\n\u003cp\u003e【需求背景】\u003cbr\u003e\nTLS协议，是保障通信安全的加密协议，可分为4个子功能：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e密钥生成：通过密钥交换或密钥协商等协议，让双方生成相同的密钥\u003c/li\u003e\n\u003cli\u003e身份认证：在开始阶段，双方均向对方发送自己的证书。双方接收证书后，基于PKI体系，校验证书是否合法。\u003c/li\u003e\n\u003cli\u003e数据加密：发送方发生数据前，使用密钥加密数据，发送数据密文。接受方接受密文后，使用密钥解密，获取数据。\u003c/li\u003e\n\u003cli\u003e数据校验：在加密数据的同时，生成数据完整性校验码，与数据密文拼接在一起。（简单理解：生成数据的哈希值，并使用密钥加密哈希值）接收方解密数据后，同样生成数据完整性校验码，与接收的相比，判断是否一致。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e开源软件libssl.so提供TLS功能，应用只需调用接口，即可实现TLS协议。同时，libssl.so提供100+算法套件，可让应用选择不同的参数组合，1个算法套件，包含4个关键参数：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e密钥生成：密钥生成协议\u003c/li\u003e\n\u003cli\u003e身份认证：证书算法类型\u003c/li\u003e\n\u003cli\u003e数据加密：加密算法类型\u003c/li\u003e\n\u003cli\u003e数据校验：哈希算法类型\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e例如，libssl.so中，常用的算法套件为：ECDHE-RSA-AES128-SHA256，该套件中，参数的含义如下：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e密钥生成协议：ECDHE协议。（常见协议类型:DHE、ECDHE、RSA等）\u003c/li\u003e\n\u003cli\u003e证书算法类型：RSA\u003c/li\u003e\n\u003cli\u003e加密算法类型：AES-128\u003c/li\u003e\n\u003cli\u003e哈希算法类型：SHA-256\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e【需求分析】\u003cbr\u003e\nvastbase支持TLS协议，当vsql与vastbase通信时，双方可使用TLS模块，生成密钥，并使用密钥加密、解密通信数据，包括：SQL语句、SQL执行结果等。\u003cbr\u003e\n客户可能采用第三方工具，截取网络流量，获取传输中的SQL等数据，进行流量审计。但是，在使用TLS协议的情况下，网络中的数据是密文形式，无法进行流量审计。\u003c/p\u003e\n\u003cp\u003evastbase提供1个GUC参数ssl_ciphers，用于配置TLS协议采用的算法套件，旧版本，该参数的取值范围如下：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eECDHE-ECDSA-AES256-GCM-SHA384\u003c/li\u003e\n\u003cli\u003eECDHE-RSA-AES256-GCM-SHA384\u003c/li\u003e\n\u003cli\u003eDHE-RSA-AES256-GCM-SHA384\u003c/li\u003e\n\u003cli\u003eECDHE-ECDSA-AES128-GCM-SHA256\u003c/li\u003e\n\u003cli\u003eDHE-RSA-AES128-GCM-SHA256\u003c/li\u003e\n\u003cli\u003eECDHE-RSA-AES128-SHA256\u003c/li\u003e\n\u003cli\u003eECDHE-ECDSA-SM4-CBC-SM3\u003c/li\u003e\n\u003cli\u003e4个仅tassl支持的国密算法套件\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e上述7个套件中，密钥生成协议为：ECDHE、DHE，此类DH协议，无法让第三方工具获取密钥。\u003c/p\u003e\n\u003cp\u003e本版本，新增4个算法套件：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eAES128-SHA256\u003c/li\u003e\n\u003cli\u003eAES256-SHA256\u003c/li\u003e\n\u003cli\u003eAES128-GCM-SHA256\u003c/li\u003e\n\u003cli\u003eAES256-GCM-SHA384\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e上述4个套件，密钥生成协议为：RSA，该协议可让第三方工具获取密钥，使其可解密网络流量，获取SQL语句、SQL执行结果等。\u003c/p\u003e\n\u003cp\u003e【需求实现】\u003cbr\u003e\n之前，vastbase限制ssl_ciphers的取值范围，仅放开7个算法套件，本版本，将新增放开4个算法套件。\u003c/p\u003e\n\u003cp\u003e实现时，仅修改ssl_ciphers的取值范围，新增支持4个算法套件[AES128-SHA256、AES256-SHA256、AES128-GCM-SHA256、AES256-GCM-SHA384]，4个算法套件将直接传递给libssl.so，内核不做任何处理。\u003c/p\u003e\n\u003cp\u003e因此，本需求无复杂设计。本文主要介绍完整的TLS协议工作原理。\u003c/p\u003e\n\u003ch2 id=\"12-实现方案\"\u003e1.2 实现方案\u003c/h2\u003e\n\u003ch3 id=\"一ecdhe与rsa的区别\"\u003e一、ECDHE与RSA的区别\u003c/h3\u003e\n\u003cp\u003e此处简化ECDHE与RSA的步骤与算法，提取最核心的原理，方便快速理解。\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e一、ECDHE密钥协商协议\u003cbr\u003e\n第三方工具、攻击者完全无法获取密钥。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eclient                                    server\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e+-------------------------------------------+-----------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e  \u0026lt;---- 0. 双方随机约定一些公开参数 ------\u0026gt;  \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 1. 生成随机私钥 client_priv\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 2. 基于client_priv，计算公钥 client_pub\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 3. 发送公钥 client_pub ------------\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"p\"\u003e|\u003c/span\u003e 4. 接收公钥 client_pub\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"p\"\u003e|\u003c/span\u003e 5. 生成随机私钥 server_priv\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"p\"\u003e|\u003c/span\u003e 6. 基于server_priv，计算公钥 server_pub\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u0026lt;------------   \u003cspan class=\"p\"\u003e|\u003c/span\u003e 7. 发送公钥 server_pub\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 8. 接收公钥 server_pub\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 9. 基于client_priv，server_pub，计算密钥\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"p\"\u003e|\u003c/span\u003e 10. 基于server_priv，client_pub，计算密钥\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e（第9步和第10步，可以计算出相同的密钥）\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e简单举个例子\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eclient                                    server\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e+-------------------------------------------+-----------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e  \u0026lt;----- 0. generate and send \u003cspan class=\"o\"\u003e(\u003c/span\u003e2,11\u003cspan class=\"o\"\u003e)\u003c/span\u003e ----\u0026gt; \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 1. generate \u003cspan class=\"m\"\u003e8\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 2. caculate \u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e8\u003c/span\u003e * 2\u003cspan class=\"o\"\u003e)\u003c/span\u003e % \u003cspan class=\"nv\"\u003e11\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e5\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 3. send \u003cspan class=\"m\"\u003e5\u003c/span\u003e ----------\u0026gt;  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"p\"\u003e|\u003c/span\u003e 4. receive \u003cspan class=\"m\"\u003e5\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"p\"\u003e|\u003c/span\u003e 5. generate \u003cspan class=\"m\"\u003e10\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"p\"\u003e|\u003c/span\u003e 6. caculate \u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e10\u003c/span\u003e * 2\u003cspan class=\"o\"\u003e)\u003c/span\u003e % \u003cspan class=\"nv\"\u003e11\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e9\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u0026lt;------------   \u003cspan class=\"p\"\u003e|\u003c/span\u003e 7. send \u003cspan class=\"m\"\u003e9\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 8. receive \u003cspan class=\"m\"\u003e9\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 9. \u003cspan class=\"nv\"\u003ekey\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e8\u003c/span\u003e * 9\u003cspan class=\"o\"\u003e)\u003c/span\u003e % \u003cspan class=\"nv\"\u003e11\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e6\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"p\"\u003e|\u003c/span\u003e 10. \u003cspan class=\"nv\"\u003ekey\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e10\u003c/span\u003e * 5\u003cspan class=\"o\"\u003e)\u003c/span\u003e % \u003cspan class=\"nv\"\u003e11\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e6\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e攻击者：截获网络流量，获取2,11,5,9，无法计算出密钥为6\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e二、RSA密钥交换协议\u003c/p\u003e","title":"海量 10 设计 SSL协议"},{"content":"1 简介 1.1 目的 在应用与数据库传输数据时，为避免攻击者对数据进行窃听、篡改、伪造、重放等攻击，Vastbase支持采用TLS协议保障数据机密性与完整性。\n通过TLS协议，应用传输数据指至服务端路程如下：\n建立连接：与数据建立TCP连接 生成密钥(TLS)：采用TLS协议协商生成密钥(连接级) 加密数据(TLS)：使用密钥加密数据(SQL等) 发送数据：通过TCP协议，发送数据密文至数据库 客户可能采用第三方工具，截取网络流量，获取传输中的SQL等数据，进行流量审计。但是，在使用TLS协议的情况下，网络中的数据是密文形式，无法进行流量审计。为解决该问题，本文介绍如何让第三方工具获取密钥，以解密网络中的数据密文。\n1.2 适用范围 本文适用于3.0.8 psu4以之后版本。未来本需求将同步至2.2.15版本。\n1.3 术语定义、首字母缩写词和缩略语 SSL: Secure Sockets Layer，于保障网络通信安全的加密协议，早期协议，存在设计缺陷，目前由TLS协议替代。但是，SSL也可不特指SSL协议，可泛指所有通信安全加密协议。同时，由于历史原因，以及前向兼容，数据库中的很多参数与接口采用SSL命令，实际使用的是TLS协议。无需纠结TLS与SSL差异，vastbase中SSL等于TLS。 TLS: Transport Layer Security，更安全的传输加密协议。早期版本1.0,1.1已不安全，主流版本为1.2,1.3。 1.3 参考资料 原始需求：https://www.tapd.cn/tapd_fe/60475194/story/detail/1160475194001084569 openssl支持的所有cipers： https://docs.openssl.org/3.0/man1/openssl-ciphers/ ssl与tls原理：博客写了一点点，没整理 2 TLS协议支持第三方流量审计 2.1 功能简述 【需求现状】\n目前，大部分第三方流量审计工具，可在一些特定场景下，解密由TLS协议加密后的数据。以vastbase为例，使用TLS协议分为以下阶段：\n生成证书、私钥文件 vastbase端配置证书、私钥文件 vsql端配置证书、私钥文件 vsql连接vastbase\n4.1 建立tcp连接\n4.2 使用证书校验对方身份\n4.3 双发协商选择算法套件：包括密钥生成协议、加密算法等\n4.4 双方协商生成密钥 vsql与vastbase传输数据\n5.1 发送数据前，使用密钥加密数据\n5.2 发送数据密文\n在4.3步骤中，可配置不同的密钥生成协议，对于其中一部分协议，在步骤4.4中，第三方工具可获取密钥，第步骤5.2中，第三方工具截取数据密文后，即可解密数据。\n但是，4.3步骤中，目前vastbase仅支持2种密钥生成协议，这2种协议都无法让第三方工具获取密钥。 【密钥生成协议】\n此处介绍2类常见的密钥生成协议：\n一、DHE密钥协商协议\nVastbase目前支持的2种协议，都属于此类协议\nclient server +-------------------------------------------+----------------------------------- | \u0026lt;-------- 0. 双方随机约定一些参数 ------\u0026gt; | | 1. 生成随机私钥 client_priv | 2. 基于client_priv，计算公钥 client_pub | 3. 发送公钥 client_pub ------------\u0026gt; | 4. 接收公钥 client_pub | 5. 生成随机私钥 server_priv | 6. 基于server_priv，计算公钥 server_pub \u0026lt;------------ | 7. 发送公钥 server_pub | 8. 接收公钥 server_pub | 9. 基于client_priv，server_pub，计算密钥 | 10. 基于server_priv，client_pub，计算密钥 （第9步和第10步，可以计算出相同的密钥） 简单举个例子 client server +-------------------------------------------+----------------------------------- | \u0026lt;----- 0. generate and send (2,11) ----\u0026gt; | | 1. generate 8 | 2. caculate (8 * 2) % 11 = 5 | 3. send 5 ----------\u0026gt; | 4. receive 5 | 5. generate 10 | 6. caculate (10 * 2) % 11 = 9 \u0026lt;------------ | 7. send 9 | 8. receive 9 | 9. key = (8 * 9) % 11 = 6 | 10. key = (10 * 5) % 11 = 6 攻击者：截获网络流量，获取2,11,5,9，无法计算出密钥为6 二、RSA密钥交换协议\n该协议支持第三方工具解密流量，客户选择的工具已适配该协议。TLS还支持其他PSK、SRP等协议，但是，由于这些协议比较少见，且客户选择的工具未适配，本次不适配其他协议。\nclient server +-------------------------------------------+----------------------------------- | 1. 提前配置私钥、公钥 server_priv, server_pub \u0026lt;------------ | 2. 发送公钥 server_pub | 3. 生成密钥 key | 4. 使用公钥加密密钥 enc_key = enncrypt(key, server_pub) | 5. 发送密钥 enc_key --------\u0026gt; | 6. 接收密钥 enc_key | 7. 解密密钥 key = decrypt(enc_key, server_priv) 攻击者：截获网络流量，获取公钥server_pub, 加密后的enc_key，因为没有私钥，无法解密得到key 第三方工具：如果提前拿到server_priv，并且截获网络流量获取en_key，则可解密得到key 【TLS算法套件】\nTLS协议主要提供4个功能：\n身份认证（基于证书） 密钥生成（对称密钥） 数据机密性（对称加密） 数据完整性 用户使用TLS协议时，可选择不同算法套件，不同算法套件中，上述4个功能采用的协议或算法不同。\nopenssl 1.1.1n支持的算法套件有100+种，在编译libssl.so时，裁剪一些冷门的、不安全的算法套件后，vastbase使用的openssl支持60种。（执行openssl ciphers -v或者-v ‘ALL:eNULL’可查看）\n内核已支持以下几种：\nECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-GCM-SHA256 DHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-SM4-CBC-SM3 4个仅tassl支持的国密算法套件 客户选择的第三方工具，支持7种：\n编号 算法套件 代码定义 支持情况 1 AES256-SHA256 TLS_RSA_WITH_AES_256_CBC_SHA256 可支持 2 AES128-SHA256 TLS_RSA_WITH_AES_128_CBC_SHA256 可支持 3 DES-CBC3-SHA TLS_RSA_WITH_3DES_EDE_CBC_SHA 含不安全算法3des，vastbase依赖的libssl.so编译裁剪 4 DES-CBC3-SHA SSL_RSA_WITH_3DES_EDE_CBC_SHA 含不安全算法3des，vastbase依赖的libssl.so编译裁剪 5 AES256-SHA SSL_RSA_WITH_AES_256_CBC_SHA 含不安全算法sha1，可支持，不建议支持 6 AES128-SHA TLS_RSA_WITH_AES_128_CBC_SHA 含不安全算法sha1，可支持，不建议支持 7 AES256-GCM-SHA256 TLS_RSA_WITH_AES_256_GCM_SHA256 找不到，只有AES256-GCM-SHA384、AES128-GCM-SHA256 客户提的几种看起来取名简单，和之前的风格不同，但这是openssl取的，这些名称都直接传递给libssl.so，openssl迭代过很多版本，执行openssl cipher -v显示的对应的名称就是以下4个。\n7种算法套中：\n第1、2种，算法是安全的，协议不太安全，但符合标准，整体算是安全的，可以不用参数控制 第2，3种，算法非常不安全，我们的openssl都完全不支持 第4，5种，算法不安全，如果要支持，需要参数控制 第7种，找不到 客户的要求，第三方工具能解密数据，因此只需至少支持其中1种即可，无需全都支持。\n客户提出的7种，本次支持2种。另外，还有2种客户未提出，但也满足条件，疑似是第7种，使用GCM加密模式，性能更高，本次也支持：\nAES128-SHA256 AES256-SHA256 AES128-GCM-SHA256 AES256-GCM-SHA384\n（代码中的定义分别为：TLS1_TXT_RSA_WITH_AES_128_SHA256、TLS1_TXT_RSA_WITH_AES_256_SHA256、TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256、TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384） 以下是vastbase libssl.so支持的60种完整算法套件，仅供参考：\n# Cipher Suite Protocol Kx Au Enc Mac 内核支持 1 AES128-GCM-SHA256 TLSv1.2 RSA RSA AESGCM(128) AEAD 满足条件，本次支持 2 AES128-SHA SSLv3 RSA RSA AES(128) SHA1 客户提出，不安全 3 AES128-SHA256 TLSv1.2 RSA RSA AES(128) SHA256 客户提出，本次支持 4 AES256-GCM-SHA384 TLSv1.2 RSA RSA AESGCM(256) AEAD 满足条件，本次可支持 5 AES256-SHA SSLv3 RSA RSA AES(256) SHA1 客户提出，不安全 6 AES256-SHA256 TLSv1.2 RSA RSA AES(256) SHA256 客户提出，本次支持 7 DHE-PSK-AES128-CBC-SHA SSLv3 DHEPSK PSK AES(128) SHA1 8 DHE-PSK-AES128-CBC-SHA256 TLSv1 DHEPSK PSK AES(128) SHA256 9 DHE-PSK-AES128-GCM-SHA256 TLSv1.2 DHEPSK PSK AESGCM(128) AEAD 10 DHE-PSK-AES256-CBC-SHA SSLv3 DHEPSK PSK AES(256) SHA1 11 DHE-PSK-AES256-CBC-SHA384 TLSv1 DHEPSK PSK AES(256) SHA384 12 DHE-PSK-AES256-GCM-SHA384 TLSv1.2 DHEPSK PSK AESGCM(256) AEAD 13 DHE-RSA-AES128-GCM-SHA256 TLSv1.2 DH RSA AESGCM(128) AEAD 已支持 14 DHE-RSA-AES128-SHA SSLv3 DH RSA AES(128) SHA1 15 DHE-RSA-AES128-SHA256 TLSv1.2 DH RSA AES(128) SHA256 16 DHE-RSA-AES256-GCM-SHA384 TLSv1.2 DH RSA AESGCM(256) AEAD 已支持 17 DHE-RSA-AES256-SHA SSLv3 DH RSA AES(256) SHA1 18 DHE-RSA-AES256-SHA256 TLSv1.2 DH RSA AES(256) SHA256 19 DHE-RSA-CHACHA20-POLY1305 TLSv1.2 DH RSA CHACHA20/POLY1305(256) AEAD 20 ECDHE-ECDSA-AES128-GCM-SHA256 TLSv1.2 ECDH ECDSA AESGCM(128) AEAD 已支持 21 ECDHE-ECDSA-AES128-SHA TLSv1 ECDH ECDSA AES(128) SHA1 22 ECDHE-ECDSA-AES128-SHA256 TLSv1.2 ECDH ECDSA AES(128) SHA256 23 ECDHE-ECDSA-AES256-GCM-SHA384 TLSv1.2 ECDH ECDSA AESGCM(256) AEAD 已支持 24 ECDHE-ECDSA-AES256-SHA TLSv1 ECDH ECDSA AES(256) SHA1 25 ECDHE-ECDSA-AES256-SHA384 TLSv1.2 ECDH ECDSA AES(256) SHA384 26 ECDHE-ECDSA-CHACHA20-POLY1305 TLSv1.2 ECDH ECDSA CHACHA20/POLY1305(256) AEAD 27 ECDHE-PSK-AES128-CBC-SHA TLSv1 ECDHEPSK PSK AES(128) SHA1 28 ECDHE-PSK-AES128-CBC-SHA256 TLSv1 ECDHEPSK PSK AES(128) SHA256 29 ECDHE-PSK-AES256-CBC-SHA TLSv1 ECDHEPSK PSK AES(256) SHA1 30 ECDHE-PSK-AES256-CBC-SHA384 TLSv1 ECDHEPSK PSK AES(256) SHA384 31 ECDHE-PSK-CHACHA20-POLY1305 TLSv1.2 ECDHEPSK PSK CHACHA20/POLY1305(256) AEAD 32 ECDHE-RSA-AES128-GCM-SHA256 TLSv1.2 ECDH RSA AESGCM(128) AEAD 33 ECDHE-RSA-AES128-SHA TLSv1 ECDH RSA AES(128) SHA1 34 ECDHE-RSA-AES128-SHA256 TLSv1.2 ECDH RSA AES(128) SHA256 已支持 35 ECDHE-RSA-AES256-GCM-SHA384 TLSv1.2 ECDH RSA AESGCM(256) AEAD 已支持 36 ECDHE-RSA-AES256-SHA TLSv1 ECDH RSA AES(256) SHA1 37 ECDHE-RSA-AES256-SHA384 TLSv1.2 ECDH RSA AES(256) SHA384 38 ECDHE-RSA-CHACHA20-POLY1305 TLSv1.2 ECDH RSA CHACHA20/POLY1305(256) AEAD 39 PSK-AES128-CBC-SHA SSLv3 PSK PSK AES(128) SHA1 40 PSK-AES128-CBC-SHA256 TLSv1 PSK PSK AES(128) SHA256 41 PSK-AES128-GCM-SHA256 TLSv1.2 PSK PSK AESGCM(128) AEAD 42 PSK-AES256-CBC-SHA SSLv3 PSK PSK AES(256) SHA1 43 PSK-AES256-CBC-SHA384 TLSv1 PSK PSK AES(256) SHA384 44 PSK-AES256-GCM-SHA384 TLSv1.2 PSK PSK AESGCM(256) AEAD 45 PSK-CHACHA20-POLY1305 TLSv1.2 PSK PSK CHACHA20/POLY1305(256) AEAD 46 RSA-PSK-AES128-CBC-SHA SSLv3 RSAPSK RSA AES(128) SHA1 47 RSA-PSK-AES128-CBC-SHA256 TLSv1 RSAPSK RSA AES(128) SHA256 48 RSA-PSK-AES128-GCM-SHA256 TLSv1.2 RSAPSK RSA AESGCM(128) AEAD 49 RSA-PSK-AES256-CBC-SHA SSLv3 RSAPSK RSA AES(256) SHA1 50 RSA-PSK-AES256-CBC-SHA384 TLSv1 RSAPSK RSA AES(256) SHA384 51 RSA-PSK-AES256-GCM-SHA384 TLSv1.2 RSAPSK RSA AESGCM(256) AEAD 52 RSA-PSK-CHACHA20-POLY1305 TLSv1.2 RSAPSK RSA CHACHA20/POLY1305(256) AEAD 53 SRP-AES-128-CBC-SHA SSLv3 SRP SRP AES(128) SHA1 54 SRP-AES-256-CBC-SHA SSLv3 SRP SRP AES(256) SHA1 55 SRP-RSA-AES-128-CBC-SHA SSLv3 SRP RSA AES(128) SHA1 56 SRP-RSA-AES-256-CBC-SHA SSLv3 SRP RSA AES(256) SHA1 57 TLS_AES_128_CCM_8_SHA256 TLSv1.3 any any AESCCM8(128) AEAD TLS版本过高 58 TLS_AES_128_CCM_SHA256 TLSv1.3 any any AESCCM(128) AEAD TLS版本过高 59 TLS_AES_256_GCM_SHA384 TLSv1.3 any any AESGCM(256) AEAD TLS版本过高 60 TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 any any CHACHA20/POLY1305(256) AEAD TLS版本过高 2.2 功能说明 2.2.1 使用流程 前置条件：生成证书 此处介绍基于openssl工具，生成自签名证书的流程，与之前版本相比，无任何区别。\n创建存放私钥与证书的文件夹\nmkdir certs cd certs mkdir ./demoCA ./demoCA/newcerts ./demoCA/private echo \u0026#39;01\u0026#39;\u0026gt;./demoCA/serial touch ./demoCA/index.txt 配置openssl工具\n从Vastbase安装包中，获取openssl工具以及openss配置文件。假设Vastbae安装包存放在$GAUSSHOME目录。\ncp $GAUSSHOME/bin/openssl ./ chmod +x ./openssl export PATH=`pwd`:$PATH which openssl # 确保openssl来源于Vastbase安装包，避免因版本不同造成证书不可用 openssl version cp $GAUSSHOME/share/sslcert/gsql/openssl.cnf ./ export OPENSSL_CONF=`pwd`/openssl.cnf 创建CA私钥、CA证书\nopenssl genrsa -out demoCA/private/cakey.pem 2048 openssl req -new -config openssl.cnf -key demoCA/private/cakey.pem -subj /C=CN/ST=BJ/L=HaiDian/O=VAST/OU=SEC/CN=CA -out cacert.req openssl ca -selfsign -config openssl.cnf -batch -keyfile demoCA/private/cakey.pem -in cacert.req -out demoCA/cacert.pem 创建数据库私钥、数据库证书\nopenssl genrsa -out server.key 2048 openssl req -new -config openssl.cnf -key server.key -subj /C=CN/ST=BJ/L=HaiDian/O=VAST/OU=SEC/CN=server -out server.req openssl ca -config openssl.cnf -days 3650 -batch -in server.req -out server.crt 创建应用端私钥、应用端证书\nopenssl genrsa -out client.key 2048 openssl req -new -config openssl.cnf -key client.key -subj /C=CN/ST=BJ/L=HaiDian/O=VAST/OU=SEC/CN=client -out client.req openssl ca -config openssl.cnf -days 3650 -batch -in client.req -out client.crt 设置私钥与证书文件权限\nchmod 600 client* server* ca* demoCA/ca* 场景一：配置可解密的TLS算法套件 创建新用户\nvsql -d vastbase -c \u0026#34;CREATE USER u1 PASSWORD \u0026#39;u1.password\u0026#39;;\u0026#34; 配置SSL证书\n此处，假设数据库的数据目录为$VBDATA。\nexport VBDATA=$GAUSSHOME/data vb_guc set -D $VBDATA -c \u0026#34;ssl=on\u0026#34; vb_guc set -D $VBDATA -c \u0026#34;require_ssl=on\u0026#34; vb_guc set -D $VBDATA -c \u0026#34;ssl_cert_file=\u0026#39;`pwd`/server.crt\u0026#39;\u0026#34; vb_guc set -D $VBDATA -c \u0026#34;ssl_key_file=\u0026#39;`pwd`/server.key\u0026#39;\u0026#34; vb_guc set -D $VBDATA -c \u0026#34;ssl_ca_file=\u0026#39;`pwd`/demoCA/cacert.pem\u0026#39;\u0026#34; 接下来，需配置TLS协议采用的默认算法套件\n之前版本，ssl_ciphers取值范围如下： ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-GCM-SHA256 DHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-SM4-CBC-SM3 4个仅tassl支持的国密算法套件 本版本，新增4个取值范围 AES128-SHA256\nAES256-SHA256\nAES128-GCM-SHA256\nAES256-GCM-SHA384\nvb_guc set -D $VBDATA -c \u0026#34;ssl_ciphers=\u0026#39;AES128-SHA256\u0026#39;\u0026#34; 开启远程登录\nvb_guc set -D $VBDATA -c \u0026#34;listen_addresses=\u0026#39;*\u0026#39;\u0026#34; 开启登录防火墙\n在pg_hba.conf中，添加一行配置，确保该配置在所有host配置的第1行\nvb_guc set -D $VBDATA -h \u0026#34;host all all 0.0.0.0/0 sha256\u0026#34; 重启数据库，使配置生效\n应用端配置私钥与证书\n应用端通过环境变量或连接参数配置私钥与证书。\nexport PGSSLMODE=verify-ca export PGSSLCERT=`pwd`/client.crt export PGSSLKEY=`pwd`/client.key export PGSSLROOTCERT=`pwd`/demoCA/cacert.pem 应用端连接数据库\nvsql -h localhost -p 5432 -d vastbase -U u1 -W \u0026#39;u1.password\u0026#39; -r # 预期结果：连接成功，启动TLS协议，使用的算法为AES128-SHA256（vsql会显示采用的算法套件） 场景二：第三方工具解密TLS流量 按场景一配置数据库\n使用tcpdump监听数据库端口，准备抓包\n需要root用户执行，接下来抓包的数据将输出到vsql.pcap中\ntcpdump -i any -w ./vsql.pcap \u0026#39;tcp port 5432\u0026#39; vsql通过TLS连接数据库\nvsql -h localhost -p 5432 -d vastbase -U u1 -W \u0026#39;u1.password\u0026#39; -r 此时，步骤2会在后台抓取vsql与vastbase传输的所有数据，并输出到vsql.pcap中\nwindows机器下载vsql.pcap\nwindows机器下载server.key文件\n即ssl_key_file参数配置的文件\nwindows安装wireshark工具\nwireshark直接打开vsql.pcap\n效果如下图所示，可看到TLS握手过程，包括：选择算法套件、生成密钥流程等。此时，传输的数据是密文格式\nwireshark导入server.key\n以此点击：\n编辑 首选项 Protocols TLS：协议有点多，得好好找一下 RSA keys list Edit 点“+”号 配置： IP address：0.0.0.0 Port: 5432 Protocol：（不填） Key File：下载的server.key\n保存配置 此时，vsql.pcap会自动刷新成为以下内容：\n场景三：第三方工具解密JDBC TLS流量 JDBC无任何改动，当vastbase配置新算法套件时，JDBC也能正常使用TLS协议\n扩展场景：其他组件使用TLS协议 在使用TLS协议时，数据库端ssl_ciphers参数控制使用哪种算法套件，客户端无控制参数。\n此次修改，仅修改服务端，未修改客户端。vsql默认可使用新增算法套件。\n其他数据库工具/组件，可能会采用TLS协议访问数据库，当数据库端配置新增的算法套件时，其他数据库组件无需修改，可直接使用新增的算法套件。\nobs dcf 异常场景 无。此次修改ssl_ciphers的取值范围，新增的4个参数，直接传递给libssl.so，无异常场景。\n2.2.2 配置参数和文件 修改1个GUC ssl_ciphers的取值范围 修改前： ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-GCM-SHA256 DHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-SM4-CBC-SM3 4个仅tassl支持的国密算法套件 修改后：新增4个取值 AES128-SHA256 AES256-SHA256 AES128-GCM-SHA256 AES256-GCM-SHA384 2.2.3 数据相关性 无\n2.3 接口信息 修改1个GUC ssl_ciphers的取值范围。\n2.4 正反向行为 2.4.1 生效说明 ssl_ciphers 可配置为新的取值 vsql使用tls连接时，vsql可显示采用的算法套件为新增的算法套件 使用tcpdump工具抓包，wireshark工具解析，可查看算法套件 使用第三方工具，可解密网络流量 2.4.2 提示信息 未新增。vsql已支持打印tls协议的算法套件名称。\n2.4.3 约束和依赖 无\n2.5 安全性 2.5.1 权限控制 无\n2.5.2 审计 无\n2.6 影响范围 2.6.1 对已有UDT,UDF, ECPG的影响 如果采用tls协议访问数据库，当ssl_ciphers配置为新增的算法套件时，仍然可以正常使用tls。\n2.6.2 对系统函数的影响 无\n2.6.3 对系统CATALOG的影响 无\n2.6.4 对xlog日志格式、数据格式的影响 无\n2.6.5 与其他功能交互时的行为表现 无\n2.6.6 版本兼容性 旧版本驱动、旧版本vsql，可通过tls正常访问新版本数据库。\n2.6.7 用户行为变更 修改1个GUC ssl_ciphers的取值范围 修改前： ECDHE-ECDSA-AES256-GCM-SHA384 ECDHE-RSA-AES256-GCM-SHA384 DHE-RSA-AES256-GCM-SHA384 ECDHE-ECDSA-AES128-GCM-SHA256 DHE-RSA-AES128-GCM-SHA256 ECDHE-RSA-AES128-SHA256 ECDHE-ECDSA-SM4-CBC-SM3 4个仅tassl支持的国密算法套件 修改后：新增4个取值。如客户需使用第三方流量审计工具，需配置为新的取值，新的取值中密码生成协议为RSA协议，支持解密TLS流量。 AES128-SHA256 AES256-SHA256 AES128-GCM-SHA256 AES256-GCM-SHA384 2.7 指标相关 2.7.1 关键资源指标 无\n2.7.2 系统性指标 无\n2.7.3 性能指标 无\n2.8 测试建议 无\n2.8 其他说明 无\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/10-requirement-ssl/","summary":"\u003ch1 id=\"1-简介\"\u003e1 简介\u003c/h1\u003e\n\u003ch2 id=\"11-目的\"\u003e1.1 目的\u003c/h2\u003e\n\u003cp\u003e在应用与数据库传输数据时，为避免攻击者对数据进行窃听、篡改、伪造、重放等攻击，Vastbase支持采用TLS协议保障数据机密性与完整性。\u003cbr\u003e\n通过TLS协议，应用传输数据指至服务端路程如下：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e建立连接：与数据建立TCP连接\u003c/li\u003e\n\u003cli\u003e生成密钥(TLS)：采用TLS协议协商生成密钥(连接级)\u003c/li\u003e\n\u003cli\u003e加密数据(TLS)：使用密钥加密数据(SQL等)\u003c/li\u003e\n\u003cli\u003e发送数据：通过TCP协议，发送数据密文至数据库\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e客户可能采用第三方工具，截取网络流量，获取传输中的SQL等数据，进行流量审计。但是，在使用TLS协议的情况下，网络中的数据是密文形式，无法进行流量审计。为解决该问题，本文介绍如何让第三方工具获取密钥，以解密网络中的数据密文。\u003c/p\u003e\n\u003ch2 id=\"12-适用范围\"\u003e1.2 适用范围\u003c/h2\u003e\n\u003cp\u003e本文适用于3.0.8 psu4以之后版本。未来本需求将同步至2.2.15版本。\u003c/p\u003e\n\u003ch2 id=\"13-术语定义首字母缩写词和缩略语\"\u003e1.3 术语定义、首字母缩写词和缩略语\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eSSL: Secure Sockets Layer，于保障网络通信安全的加密协议，早期协议，存在设计缺陷，目前由TLS协议替代。但是，SSL也可不特指SSL协议，可泛指所有通信安全加密协议。同时，由于历史原因，以及前向兼容，数据库中的很多参数与接口采用SSL命令，实际使用的是TLS协议。无需纠结TLS与SSL差异，vastbase中SSL等于TLS。\u003c/li\u003e\n\u003cli\u003eTLS: Transport Layer Security，更安全的传输加密协议。早期版本1.0,1.1已不安全，主流版本为1.2,1.3。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"13-参考资料\"\u003e1.3 参考资料\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e原始需求：\u003ca href=\"https://www.tapd.cn/tapd_fe/60475194/story/detail/1160475194001084569\"\u003ehttps://www.tapd.cn/tapd_fe/60475194/story/detail/1160475194001084569\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eopenssl支持的所有cipers： \u003ca href=\"https://docs.openssl.org/3.0/man1/openssl-ciphers/\"\u003ehttps://docs.openssl.org/3.0/man1/openssl-ciphers/\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003essl与tls原理：博客写了一点点，没整理\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-tls协议支持第三方流量审计\"\u003e2 TLS协议支持第三方流量审计\u003c/h1\u003e\n\u003ch2 id=\"21-功能简述\"\u003e2.1 功能简述\u003c/h2\u003e\n\u003cp\u003e【需求现状】\u003cbr\u003e\n目前，大部分第三方流量审计工具，可在一些特定场景下，解密由TLS协议加密后的数据。以vastbase为例，使用TLS协议分为以下阶段：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e生成证书、私钥文件\u003c/li\u003e\n\u003cli\u003evastbase端配置证书、私钥文件\u003c/li\u003e\n\u003cli\u003evsql端配置证书、私钥文件\u003c/li\u003e\n\u003cli\u003evsql连接vastbase\u003cbr\u003e\n4.1 建立tcp连接\u003cbr\u003e\n4.2 使用证书校验对方身份\u003cbr\u003e\n4.3 双发协商选择算法套件：包括密钥生成协议、加密算法等\u003cbr\u003e\n4.4 双方协商生成密钥\u003c/li\u003e\n\u003cli\u003evsql与vastbase传输数据\u003cbr\u003e\n5.1 发送数据前，使用密钥加密数据\u003cbr\u003e\n5.2 发送数据密文\u003cbr\u003e\n在4.3步骤中，可配置不同的密钥生成协议，对于其中一部分协议，在步骤4.4中，第三方工具可获取密钥，第步骤5.2中，第三方工具截取数据密文后，即可解密数据。\u003cbr\u003e\n但是，4.3步骤中，目前vastbase仅支持2种密钥生成协议，这2种协议都无法让第三方工具获取密钥。\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e【密钥生成协议】\u003cbr\u003e\n此处介绍2类常见的密钥生成协议：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e一、DHE密钥协商协议\u003cbr\u003e\nVastbase目前支持的2种协议，都属于此类协议\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eclient                                    server\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e+-------------------------------------------+-----------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e  \u0026lt;-------- 0. 双方随机约定一些参数 ------\u0026gt;  \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 1. 生成随机私钥 client_priv\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 2. 基于client_priv，计算公钥 client_pub\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 3. 发送公钥 client_pub ------------\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"p\"\u003e|\u003c/span\u003e 4. 接收公钥 client_pub\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"p\"\u003e|\u003c/span\u003e 5. 生成随机私钥 server_priv\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"p\"\u003e|\u003c/span\u003e 6. 基于server_priv，计算公钥 server_pub\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u0026lt;------------   \u003cspan class=\"p\"\u003e|\u003c/span\u003e 7. 发送公钥 server_pub\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 8. 接收公钥 server_pub\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 9. 基于client_priv，server_pub，计算密钥\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"p\"\u003e|\u003c/span\u003e 10. 基于server_priv，client_pub，计算密钥\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e（第9步和第10步，可以计算出相同的密钥）\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e简单举个例子\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eclient                                    server\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e+-------------------------------------------+-----------------------------------\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e  \u0026lt;----- 0. generate and send \u003cspan class=\"o\"\u003e(\u003c/span\u003e2,11\u003cspan class=\"o\"\u003e)\u003c/span\u003e ----\u0026gt; \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 1. generate \u003cspan class=\"m\"\u003e8\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 2. caculate \u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e8\u003c/span\u003e * 2\u003cspan class=\"o\"\u003e)\u003c/span\u003e % \u003cspan class=\"nv\"\u003e11\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e5\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 3. send \u003cspan class=\"m\"\u003e5\u003c/span\u003e ----------\u0026gt;  \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"p\"\u003e|\u003c/span\u003e 4. receive \u003cspan class=\"m\"\u003e5\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"p\"\u003e|\u003c/span\u003e 5. generate \u003cspan class=\"m\"\u003e10\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"p\"\u003e|\u003c/span\u003e 6. caculate \u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e10\u003c/span\u003e * 2\u003cspan class=\"o\"\u003e)\u003c/span\u003e % \u003cspan class=\"nv\"\u003e11\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e9\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u0026lt;------------   \u003cspan class=\"p\"\u003e|\u003c/span\u003e 7. send \u003cspan class=\"m\"\u003e9\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 8. receive \u003cspan class=\"m\"\u003e9\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 9. \u003cspan class=\"nv\"\u003ekey\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e8\u003c/span\u003e * 9\u003cspan class=\"o\"\u003e)\u003c/span\u003e % \u003cspan class=\"nv\"\u003e11\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e6\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"p\"\u003e|\u003c/span\u003e 10. \u003cspan class=\"nv\"\u003ekey\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"m\"\u003e10\u003c/span\u003e * 5\u003cspan class=\"o\"\u003e)\u003c/span\u003e % \u003cspan class=\"nv\"\u003e11\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e6\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e攻击者：截获网络流量，获取2,11,5,9，无法计算出密钥为6\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e二、RSA密钥交换协议\u003cbr\u003e\n该协议支持第三方工具解密流量，客户选择的工具已适配该协议。TLS还支持其他PSK、SRP等协议，但是，由于这些协议比较少见，且客户选择的工具未适配，本次不适配其他协议。\u003c/p\u003e","title":"海量 10 需求 SSL协议"},{"content":"1 简介 1.1 目的 逻辑复制是一种在多个数据库实例之间复制数据的功能，通常用于从一个数据库实例中，将针对指定表的insert、delete、update等写操作，复制到其他另一个数据库实例。在数据库术语中，统一称逻辑复制的发送方为发布端，称接收方为订阅端。Oracle、Postgresql、Vastbase等数据库产品，均提供逻辑复制功能。\n当前版本，逻辑复制性能较低，以tpcc场景为例，发布端40w tmpc时，订阅端的复制速度约10m/s。在滚动升级等场景，通过逻辑复制在不同实例间同步大量数据，要求逻辑复制性能达到70-100m/s。\n发布端、订阅端均存在性能瓶颈，均需要优化。但是，由于交付时间较短，以及订阅端方案仍有瑕疵等因素，本版本交付发布端性能优化，下版本交付订阅端性能优化。\n1.2 适用范围 本文主要用于向开发、测试等角色，介绍G100 3.0.9 psu2及之后版本，逻辑复制的性能优化的设计方向与使用方法。\n1.3 术语定义、首字母缩写词和缩略语 发布端：逻辑复制场景，发送数据方。 订阅端：逻辑复制场景，接收数据方。 1.3 参考资料 Vastbase G100产品文档中逻辑复制使用介绍：https://docs.vastdata.com.cn/zh_CN/VastbaseG100/V3.0.8/1/f5c2ae8eb9744d429ad39c02438addf6 2 G100审计功能重构 2.1 功能简述 需求背景：逻辑复制使用 使用逻辑复制的流程如下：\n发布端：配置逻辑复制\n# 设置wal日志详细级别，设计身份等参数，重启集群 gs_guc set -D $PGDATA -c \u0026#39;wal_level=logical\u0026#39; gs_guc set -D $PGDATA -h \u0026#34;host all all 0.0.0.0/0 md5\u0026#34; gs_guc set -D $PGDATA -h \u0026#34;host replication all 0.0.0.0/0 md5\u0026#34; vb_ctl restart -D $PGDATA 发布端：创建表\nCREATE TABLE pt1(c1 INT,c2 TEXT); CREATE TABLE pt2(c1 INT, c2 TEXT); 发布端：创建发布，即指定哪些表需复制\nCREATE PUBLICATION pub1 FOR TABLE pt1,pt2; 发布端：创建逻辑复制槽，用于存储复制状态等信息\nSELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); 发布端：创建用户。订阅端通过该用户连接发布端，以进行数据传输\nCREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; GRANT ALL ON pt1,pt2 TO pu1; 订阅端：创建表，需与发布端表结构一致\nCREATE TABLE pt1(c1 INT,c2 TEXT); CREATE TABLE pt2(c1 INT, c2 TEXT); 订阅端：创建订阅信息\nCREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=127.0.0.1 port=5432 dbname=pubdb user=pu1 password=pu1.12345\u0026#39; PUBLICATION pub1 WITH (create_slot = false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = true); 复制数据\n发布端操作数据时，逻辑复制会自动复制操作、数据等至订阅端。\n-- 发布端变更数据 INSERT INTO pt1 VALUES (1, \u0026#39;data1\u0026#39;); SELECT * FROM pt1; 逻辑复制自动同步数据，订阅端数据与发布端保持一致。\n-- 订阅端：预期查询结果与发布端保持一致 SELECT * FROM pt1; 需求背景：逻辑复制原理 逻辑复制功能，本质是复制解码之后的wal。此处，如下图所示，以一个实际场景为例，梳理完整的复制流程：\n上图中，关键流程如下：\n发布端 (1) 生成wal\n在发布端，应用执行insert、delete、update等语句，产生wal (2) 解码wal\n启用逻辑复制时，发布端会启动一个独立的wal-sender线程，持续读取wal，解码wal，即提取wal中的操作、数据等关键信息，最终生成logical-wal (3) 发送logical-wal\nwal-sender线程持续将logical-wal发送给订阅端 订阅端 (4) 接收loigcal-wal\n在订阅端，持续接收logical-wal (5) 重放logical-wal\n从logical-wal提取操作、数据等关键信息，将其看做单条insert、delete、update等语句并执行。 本需求主要优化上述流程中的两个阶段：(2)解码wal、(3)发送logical-wal\n需求概述：一、并行解码 当前版本，发布端支持并行解码，但是，不可用于逻辑复制场景，订阅端只能是工具，不能是数据实例。本需求将修改并行解码，以用于逻辑复制场景。\n本需求的第一个修改如下：\n修改前：逻辑复制场景，只能1个线程并行解码wal 修改后：逻辑复制场景，支持[1，32]个线程解码wal 需求概述：二、流复制协议 当前版本，发布端解码wal生成logical-wal之后，会暂时缓存logical-wal，同一事务的所有logical-wal缓存在一起。当处理到事务commit/abort的wal时，才统一发送本事务的所有logical-wal。\n从订阅端的角度看，发布端依次地、串行地发送事务的logical-wal。为确保事务正确性，订阅端无法并行回放logical-wal。\npg-14以及之后版，支持流复制协议，设计思想是发送为完成事务的logical-wal，让订阅端会同时存在多个未提交事务的logical-wal，让其并行回放。本需求引入流复制协议，并进行优化。\n本需求的第二个修改如下：\n修改前：只能使用事务复制协议，1次复制1个完整的事务。 修改后： 新增混合流复制协议（与pg保持一致）：1次复制1个完整的事务，或者1个不完整的事务 原理：发布端缓存事务logical-wal，当缓存大小达到阈值时，发送logical-wal最多的事务的所有loigcal-wal，即使该事务未commit或abort 新增完全流复制协议（性能远高于pg）：1次发送1条logical-wal，即与事务无关。 不缓存logical-wal，生成logical-wal后，直接发送logial-wal。 需求概述：下版本工作计划 当前版本，订阅端只有1个线程回放logical-wal，无法使用处理流复制协议。下一版本，订阅端支持多线程并行回放logical-wal，并行回放的前提条件是发布端使用流复制协议发送logical-wal。\n2.2 功能说明 2.2.1 使用流程 场景一、使用混合流复制协议 todo\n场景二、使用完全流复制协议 todo\n2.2.2 配置参数和文件 CREATE/ALTER SUBSCRIPTION语法中，主动指定参数，控制是否启用流复制协议 pg_recvlogical工具中，主动指定参数，控制是否使用流复制协议 2.2.3 数据相关性 无\n2.3 接口信息 修改CREATE/ALTER SUBSCRIPTION语法\n修改前\nCREATE SUBSCRIPTION subname CONNECTION \u0026#39;连接参数\u0026#39; PUBLICATION pubname WITH (参数) 修改后\nCREATE SUBSCRIPTION subname CONNECTION \u0026#39;连接参数\u0026#39; PUBLICATION pubname WITH (参数) 修改pg_recvlogical工具\n修改前 修改后 2.4 正反向行为 2.4.1 生效说明 2.4.2 提示信息 2.4.3 约束和依赖 无\n2.5 安全性 2.5.1 权限控制 已有语法新增参数，不涉及权限变更\n2.5.2 审计 已有语法新增参数，无需单独适配审计\n2.6 影响范围 2.6.1 对已有UDT,UDF, ECPG的影响 无\n2.6.2 对系统函数的影响 无\n2.6.3 对系统CATALOG的影响 无\n2.6.4 对xlog日志格式、数据格式的影响 无\n2.6.5 与其他功能交互时的行为表现 逻辑复制协议：todo\n2.6.6 版本兼容性 旧版本升级：todo\n2.6.7 用户行为变更 修改CREATE/ALTER SUBSCRIPTION语法 修改pg_recvlogical工具 2.7 指标相关 2.7.1 关键资源指标 CPU： 内存： IO： 磁盘： 2.7.2 系统性指标 无\n2.7.3 性能指标 使用pg_recvlogial工具测试，发送速度大于70m/s\n2.8 测试建议 无法端到端使用逻辑复制，只能使用pg_recvlogical验证，建议等下版本合入订阅端优化后，再详细测试。\n2.9 其他说明 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/11-requirement-logical-replication/","summary":"\u003ch1 id=\"1-简介\"\u003e1 简介\u003c/h1\u003e\n\u003ch2 id=\"11-目的\"\u003e1.1 目的\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003e逻辑复制\u003c/strong\u003e是一种在多个数据库实例之间复制数据的功能，通常用于从一个数据库实例中，将针对指定表的insert、delete、update等写操作，复制到其他另一个数据库实例。在数据库术语中，统一称逻辑复制的发送方为\u003cstrong\u003e发布端\u003c/strong\u003e，称接收方为\u003cstrong\u003e订阅端\u003c/strong\u003e。Oracle、Postgresql、Vastbase等数据库产品，均提供逻辑复制功能。\u003c/p\u003e\n\u003cp\u003e当前版本，逻辑复制性能较低，以tpcc场景为例，发布端40w tmpc时，订阅端的复制速度约10m/s。在滚动升级等场景，通过逻辑复制在不同实例间同步大量数据，要求逻辑复制性能达到70-100m/s。\u003c/p\u003e\n\u003cp\u003e发布端、订阅端均存在性能瓶颈，均需要优化。但是，由于交付时间较短，以及订阅端方案仍有瑕疵等因素，本版本交付发布端性能优化，下版本交付订阅端性能优化。\u003c/p\u003e\n\u003ch2 id=\"12-适用范围\"\u003e1.2 适用范围\u003c/h2\u003e\n\u003cp\u003e本文主要用于向开发、测试等角色，介绍G100 3.0.9 psu2及之后版本，逻辑复制的性能优化的设计方向与使用方法。\u003c/p\u003e\n\u003ch2 id=\"13-术语定义首字母缩写词和缩略语\"\u003e1.3 术语定义、首字母缩写词和缩略语\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e发布端：逻辑复制场景，发送数据方。\u003c/li\u003e\n\u003cli\u003e订阅端：逻辑复制场景，接收数据方。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"13-参考资料\"\u003e1.3 参考资料\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eVastbase G100产品文档中逻辑复制使用介绍：\u003ca href=\"https://docs.vastdata.com.cn/zh_CN/VastbaseG100/V3.0.8/1/f5c2ae8eb9744d429ad39c02438addf6\"\u003ehttps://docs.vastdata.com.cn/zh_CN/VastbaseG100/V3.0.8/1/f5c2ae8eb9744d429ad39c02438addf6\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-g100审计功能重构\"\u003e2 G100审计功能重构\u003c/h1\u003e\n\u003ch2 id=\"21-功能简述\"\u003e2.1 功能简述\u003c/h2\u003e\n\u003ch3 id=\"需求背景逻辑复制使用\"\u003e需求背景：逻辑复制使用\u003c/h3\u003e\n\u003cp\u003e使用逻辑复制的流程如下：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\n\u003cp\u003e发布端：配置逻辑复制\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 设置wal日志详细级别，设计身份等参数，重启集群\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$PGDATA\u003c/span\u003e -c \u003cspan class=\"s1\"\u003e\u0026#39;wal_level=logical\u0026#39;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$PGDATA\u003c/span\u003e -h \u003cspan class=\"s2\"\u003e\u0026#34;host all all 0.0.0.0/0 md5\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003egs_guc \u003cspan class=\"nb\"\u003eset\u003c/span\u003e -D \u003cspan class=\"nv\"\u003e$PGDATA\u003c/span\u003e -h \u003cspan class=\"s2\"\u003e\u0026#34;host replication all 0.0.0.0/0 md5\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003evb_ctl restart -D \u003cspan class=\"nv\"\u003e$PGDATA\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e发布端：创建表\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ept1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ept2\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e发布端：创建发布，即指定哪些表需复制\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePUBLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epub1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFOR\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ept1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"n\"\u003ept2\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e发布端：创建逻辑复制槽，用于存储复制状态等信息\u003c/p\u003e","title":"海量 11 需求 逻辑复制性能优化"},{"content":"1 透明加密 1.1 功能简述 关于透明加密的基本概念，请看需求文档。\n用户使用透明加密的示例如下：\nCREATE TABLE t1 (c1 TEXT, c2 TEXT); CREATE ENCRYPTION KEY tde_key WITH (source=local, password=\u0026#39;pass.123\u0026#39;); CREATE ENCRYPTION POLICY ep1 FRO t1 KEY tde_key; INSERT INTO t1 VALUES (\u0026#39;data1\u0026#39;, \u0026#39;data2\u0026#39;); INSERT INTO t1 VALUES (\u0026#39;data1\u0026#39;, \u0026#39;data2\u0026#39;); SELECT * FROM t1; 1.2 实现方案 1.2.1 整体架构 透明加密的核心目标，是通过数据加密方案，解决攻击者绕过数据库安全机制，直接从磁盘窃取数据的问题。\n在加密数据后，需要确保不影响内核在数据上进行计算。因此，需要在存储层底层，对数据进行加密。另外，为确保存储底层能够识别哪些数据加密，哪些数据不加密，以及使用什么算法加密等，上层需传递加密信息。透明加密逻辑架构如下：\n1.2.2 工作流程 为适配存储底层设计，同时兼顾加密性能，以Page为粒度进行加密，并且，在Page中，存储加密信息。\n1.2.3 详细流程 一、启动进程 在启动进程阶段，故障恢复时，如果回放到属于加密表的xlog，涉及到解密Page，因此，需在故障恢复前加载密钥。\nmain # 1. 启动数据库进程（基于pg-16代码） PostmasterMain # 2. 启动postmaster进程 SelectConfigFiles # 3. 读取GUC文件 \u0026#39;tde_load_encryption_key\u0026#39; # 4. 读取密钥文件（后文介绍密钥如何生成） SysLogger_Start StartupDataBase # 5. 开始故障恢复 StartupProcessMain StartupXLOG ReadControlFile PerformWalRecovery for loop: ReadRecord # 6. 读取xlog ApplyWalRecord # 7. 重放xlog GetRmgr.rm_redo ... heap_xlog_insert XLogReadBufferForRedo XLogReadBufferForRedoExtended XLogReadBufferExtended ReadBufferWithoutRelcache ReadBuffer_common smgrread # 8. 读取数据文件 # 需解密，后文统一介绍 ServerLoop for loop: ConnCreate BackendStartup BackendRun PostgresMain # 9. 启动postgres进程 StartCheckpointer StartBackgroundWriter StartChildProcess AuxiliaryProcessMain BackgroundWriterMain # 10. 启动bgwriter进程 二、生成密钥 当前版本，所有表，使用同一个数据密钥。因此，暂时无需新增系统表，存储密钥对象。\nPostgresMain # 1. 启动postgres进程 for loop: exec_simple_query(\u0026#39;CREATE ENCRYPTION KEY ..\u0026#39;) # 2. 接收创建密钥的SQL pg_parse_query # 3. 语法解析 PortalRun PortalRunUtility ProcessUtility standard_ProcessUtility \u0026#39;CreateEncryptionKey(password)\u0026#39; # 4. 执行DDL \u0026#39;master_key = generate_master_key\u0026#39; # 5. 随机生成主密钥 \u0026#39;RAND_bytes\u0026#39; \u0026#39;data_key = generate_data_key(password)\u0026#39; # 6. 基于password派生数据密钥 \u0026#39;PBKDF2\u0026#39; \u0026#39;write_key(master_key, data_key)\u0026#39; # 7. 存储主密钥、数据密钥 \u0026#39;XlogInsert(master_key, data_key)\u0026#39; # 8. 生成xlog 三、为表设置加密属性 PostgresMain # 1. 启动postgres进程 for loop: exec_simple_query(\u0026#39;CREATE ENCRYPTION POLICY FOR t1 ..\u0026#39;) # 2. 接收为表设置加密属性的SQL pg_parse_query # 3. 语法解析 PortalRun PortalRunUtility ProcessUtility standard_ProcessUtility \u0026#39;CreateEncryptionPolicy\u0026#39; \u0026#39;heap_open(vb_encryption_policy)\u0026#39; \u0026#39;simple_heap_insert\u0026#39; # 4. 向vb_encryption_policy系统表中，存储加密策略：加密算法、MAC算法、密钥轮次 \u0026#39;heap_open(vb_secure_class)\u0026#39; \u0026#39;simple_heap_insert\u0026#39; # 5. 向vb_secure_class系统表中，存储加密对象：对象类型、对象oid、对象name、对象加密策略 四、存储数据 阶段一：组织数据\nPostgresMain # 1. 启动postgres进程 for loop: exec_simple_query(\u0026#39;INSERT INTO t1 VALUES(\u0026#39;data\u0026#39;)\u0026#39;) # 2. 接收为表设置加密属性的SQL pg_parse_query # 3. 语法解析 PortalRun PortalRunMulti ProcessQuery ExecutorStart standard_ExecutorStart InitPlan # 4. 初始化计划 ExecInitNode ExecInitModifyTable ExecInitResultRelation ExecGetRangeTableRelation # 5. 初始化relation结构体 table_open relation_open RelationIdGetRelation RelationBuildDesc ScanPgRelation # 6. 从pg_class系统表中获取表元数据 systable_beginscan(pg_class) \u0026#39;read_relation_encryption_policy\u0026#39; # 7. 从vb_secure_class系统表中判断表是否需要加密 \u0026#39;systable_beginscan(vb_secure_class)\u0026#39; \u0026#39;read_encryption_policy\u0026#39; # 8. 从vb_encryption_policy系统表中获取加密信息：加密算法等 \u0026#39;systable_beginscan(vb_encryption_policy)\u0026#39; ExecutorRun standard_ExecutorRun ExecutePlan ExecProcNode ExecModifyTable ExecInsert table_tuple_insert heap_insert(relation) # 9. 调用存储接口，存储数据 RelationGetBufferForTuple # 10. 读取用于存放数据的Page ReadBufferBI ReadBuffer ReadBufferExtended ReadBuffer_common smgread # 11. 情况1：从磁盘读取已有Page \u0026#39;解密Page：下文介绍\u0026#39; BufferGetPage if PageIsNew: # 12. 情况2：需要初始化新的Page \u0026#39;if reltaion-\u0026gt;encrypt:\u0026#39; \u0026#39;generate_page_tail\u0026#39; # 13. 格式化relation结构体中的加密信息，用于写入Page尾部 PageInit # 14. 初始化Page \u0026#39;set_page_tail\u0026#39; # 15. 在Page尾部写入加密信息 \u0026#39;page_set_encrypt_flag\u0026#39; # 16. 在Page头部标记Page需加密 RelationPutHeapTuple MarkBufferDirty XLogInsert(XLOG_HEAP_INIT_PAGE) # 17. 生成xlog XLogRecordAssemble # 18. 封装xlog if \u0026#39;XLOG_HEAP_INIT_PAGE\u0026#39; and \u0026#39;page_set_encrypt_flag\u0026#39;: \u0026#39;copy_page_tail_to_wal\u0026#39; # 19. 如果Page是新生成的，且有加密标记，在xlog中携带加密信息 XLogInsertRecord 其中，Page的格式设计如下：\n由于存在密钥轮转的场景，表中不同的page，可能使用不同轮次的密钥。每个page额外存储一份密钥，虽然占用空间，但是，可以避免密钥轮转时旧密钥被清理，导致无法解密的情况。\n阶段二：存储数据\nBackgroundWriterMain # 1. 启动bgworker进程 for loop: BgBufferSync # 2. 扫描shared buffer StrategySyncStart SyncOneBuffer # 3. 存储Page FlushBuffer smgrwrite # 4. 将Page写入磁盘 if \u0026#39;page_set_encrypt_flag\u0026#39; \u0026#39;encrypt_page\u0026#39; # 5. 如果Page头部有加密标记，则加密Page \u0026#39;read_encrypt_info_from_page_tail\u0026#39; 五、读取数据 PostgresMain # 1. 启动postgres进程 for loop: exec_simple_query(\u0026#39;SELECT * FROM t1\u0026#39;) # 2. 接收为表设置加密属性的SQL pg_parse_query # 3. 语法解析 PortalRun ExecSeqScan PortalRunSelect ExecutorRun standard_ExecutorRun ExecutePlan ExecProcNode ExecScan # 4. 扫描数据 ExecScanFetch SeqNext heap_beginscan heap_getnext heapgettup heapgetpage # 5. 读取Page ReadBufferExtended ReadBuffer_common smgread # 6. 从磁盘读取Page \u0026#39;if page_set_encrypt_flag:\u0026#39; \u0026#39;decrypt_page\u0026#39; # 7. 如果Page头部有加密标记，则解密Page \u0026#39;read_encrypt_info_from_page_tail\u0026#39; 1.3 接口说明 新增密钥管理语法\nCREATE ENCRYPTION KEY $key_name (source = local, password = $password) ALTER ENCRYPTION KEY $key_nam ROTATION; DROP ENCRYPTION KEY $key_name; 新增加密策略语法\nCREATE ENCRYPTION POLICY $pollicy_name [FOR [TABLE] $table_name [, $table_name ...]] KEY $key_name [ALGORITHEM {aes_256_ct | aes_256_gcm | aes_256_cbc} ] -- 默认：aes_256_ct [MAC ALGORITHM {sha256}] -- 默认：空 ALTER ENCRYPTION POLICY $pollicy_name [ADD [TABLE] $table_name [, $table_name ...]] [REMOVE [TABLE] $table_name [, $table_name ...]] [ALGORITHEM {aes_256_ct | aes_256_gcm | aes_256_cbc} ] DROP ENCRYPTION POLICY $pollicy_name; 新增系统表vb_encryption_key\n-- 表结构： keyoid | keyname | keyinfo -------+---------+--------- 新增系统表vb_encryption_policy\n-- 表结构： polname | polkey | polalgo | polmacalgo ---------+---------+------------+------------ 新增系统表vb_secure_class\n-- 表结构： relid | relname | encryption_policy | access_policy ------+---------+-------------------+--------------- 1.4 内存管理 新增全局内存上下文，用于存放密钥明文等信息，当前版本，密钥只有1个，占用内存空间可忽略。\n加密Page、解密Page时，在Page上原地加密，无需额外的内存。\n1.5 安全 使用ENCRYPTION KEY、ENCRYPTION POLICY语法时，需特权用户，例如superuser，sysadmin等，三权分立场景，需安全管理员\nENCRYPTION KEY、ENCRYPTION POLICY语法作为通用DDL审计\n1.6 性能 只有在存储、读取加密表的Page时，才需加密与解密，与IO相比，加密、解密开销占比低。加密集群中所有用户表，使用aes_256_ctr算法，整体性能劣化低于5%。\n1.7 专利 本版本无\n未来，加密wal日志，可参考分组密码ctr加密模式的设计原理，让加密wal日志性能劣化极低。\n1.8 升级管理 新增系统表，新增wal类型，无其他变更\n1.9 其他说明 无\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/13-design-tde/","summary":"\u003ch1 id=\"1-透明加密\"\u003e1 透明加密\u003c/h1\u003e\n\u003ch2 id=\"11-功能简述\"\u003e1.1 功能简述\u003c/h2\u003e\n\u003cp\u003e关于透明加密的基本概念，请看需求文档。\u003cbr\u003e\n用户使用透明加密的示例如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eENCRYPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etde_key\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"k\"\u003esource\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003elocal\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epassword\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;pass.123\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eENCRYPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ePOLICY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eep1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eFRO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etde_key\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;data1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;data2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;data1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;data2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eSELECT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eFROM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"12-实现方案\"\u003e1.2 实现方案\u003c/h2\u003e\n\u003ch3 id=\"121-整体架构\"\u003e1.2.1 整体架构\u003c/h3\u003e\n\u003cp\u003e透明加密的核心目标，是通过数据加密方案，解决攻击者绕过数据库安全机制，直接从磁盘窃取数据的问题。\u003cbr\u003e\n在加密数据后，需要确保不影响内核在数据上进行计算。因此，需要在存储层底层，对数据进行加密。另外，为确保存储底层能够识别哪些数据加密，哪些数据不加密，以及使用什么算法加密等，上层需传递加密信息。透明加密逻辑架构如下：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"1-struct\" loading=\"lazy\" src=\"/images/ProjectDocs/13-design-tde/1-struct.png\"\u003e\u003c/p\u003e\n\u003ch3 id=\"122-工作流程\"\u003e1.2.2 工作流程\u003c/h3\u003e\n\u003cp\u003e为适配存储底层设计，同时兼顾加密性能，以Page为粒度进行加密，并且，在Page中，存储加密信息。\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"2-flow\" loading=\"lazy\" src=\"/images/ProjectDocs/13-design-tde/2-flow.png\"\u003e\u003c/p\u003e\n\u003ch3 id=\"123-详细流程\"\u003e1.2.3 详细流程\u003c/h3\u003e\n\u003ch4 id=\"一启动进程\"\u003e一、启动进程\u003c/h4\u003e\n\u003cp\u003e在启动进程阶段，故障恢复时，如果回放到属于加密表的xlog，涉及到解密Page，因此，需在故障恢复前加载密钥。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003emain\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 1. 启动数据库进程（基于pg-16代码）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ePostmasterMain\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 2. 启动postmaster进程\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eSelectConfigFiles\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 3. 读取GUC文件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"s1\"\u003e\u0026#39;tde_load_encryption_key\u0026#39;\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 4. 读取密钥文件（后文介绍密钥如何生成）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eSysLogger_Start\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eStartupDataBase\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 5. 开始故障恢复\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"n\"\u003eStartupProcessMain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eStartupXLOG\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eReadControlFile\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003ePerformWalRecovery\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"n\"\u003eloop\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eReadRecord\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 6. 读取xlog\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eApplyWalRecord\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 7. 重放xlog\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                \u003cspan class=\"n\"\u003eGetRmgr\u003c/span\u003e\u003cspan class=\"o\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003erm_redo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                    \u003cspan class=\"o\"\u003e...\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                        \u003cspan class=\"n\"\u003eheap_xlog_insert\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                            \u003cspan class=\"n\"\u003eXLogReadBufferForRedo\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                \u003cspan class=\"n\"\u003eXLogReadBufferForRedoExtended\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"n\"\u003eXLogReadBufferExtended\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                        \u003cspan class=\"n\"\u003eReadBufferWithoutRelcache\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                            \u003cspan class=\"n\"\u003eReadBuffer_common\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                                \u003cspan class=\"n\"\u003esmgrread\u003c/span\u003e  \u003cspan class=\"c1\"\u003e# 8. 读取数据文件\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                                    \u003cspan class=\"c1\"\u003e# 需解密，后文统一介绍\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eServerLoop\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003efor\u003c/span\u003e \u003cspan class=\"n\"\u003eloop\u003c/span\u003e\u003cspan class=\"p\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eConnCreate\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eBackendStartup\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eBackendRun\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003ePostgresMain\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 9. 启动postgres进程\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eStartCheckpointer\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                \u003cspan class=\"n\"\u003eStartBackgroundWriter\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                    \u003cspan class=\"n\"\u003eStartChildProcess\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"n\"\u003eAuxiliaryProcessMain\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                            \u003cspan class=\"n\"\u003eBackgroundWriterMain\u003c/span\u003e \u003cspan class=\"c1\"\u003e# 10. 启动bgwriter进程\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch4 id=\"二生成密钥\"\u003e二、生成密钥\u003c/h4\u003e\n\u003cp\u003e当前版本，所有表，使用同一个数据密钥。因此，暂时无需新增系统表，存储密钥对象。\u003c/p\u003e","title":"海量 透明加密 设计"},{"content":"1 简介 1.1 目的 透明加密特性提供数据加密功能，核心原理是在数据库将数据存储至磁盘时，先加密再存储。\n本需求将从0设计透明加密特性，在保障功能、性能、易用性、可用性、可维护性、可扩展性等的前提下，让特性达到商用标准。\n1.2 适用范围 Vastbase V5版本。\n1.3 术语定义、首字母缩写词和缩略语 TDE：Transparent Data Encryption，透明数据加密，由数据库提供的数据加密特性 1.4 参考资料 oracle 透明加密特性：https://docs.oracle.com/en/database/oracle/oracle-database/26/dbtde/preface.html sql server 透明加密特性：https://learn.microsoft.com/en-us/sql/relational-databases/security/encryption/transparent-data-encryption?view=sql-server-ver17 oceanbase 透明加密特性：https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004475958 kingbase 透明加密特性：https://docs.kingbase.com.cn/cn/KES-V9R1C10/safe/transparent-data-Encyption dm8 透明加密特性：https://eco.dameng.com/document/dm/zh-cn/pm/storage-encryption.html#7.1.1%20%E5%85%A8%E5%BA%93%E5%8A%A0%E5%AF%86 gaussdb 透明加密特性：https://support.huaweicloud.com/intl/zh-cn/fg-gaussdb-dist-v8/gaussdb-18-0019.html 2 透明加密 2.1 功能简述 一、基本原理 通常，用户将数据传输给数据库后，数据库将数据存储到磁盘。攻击者可能利用多种数据库内部或外部漏洞，例如操作系统漏洞等，绕过数据库安全机制，直接从磁盘读取数文件，窃取用户数据。\n透明加密，是一种由数据库提供的加密特性，可有效解决攻击者从磁盘窃取数据的问题。开启透明加密后，数据库将数据存储到磁盘时，先加密数据，再存储数据密文；数据库从磁盘读取数据时，先解密数据密文，再进行其他计算。用户访问透明加密表时，包括存储、读取数据等，与访问普通表无任何区别，加密和解密过程由数据库自动完成，即对用户透明。\n二、竞品分析 几乎所有商用关系数据库中，都支持透明加密特性，包括oracle, sql server, oceanbase, kingbase, dm8等，postgresql不支持透明加密特性。\n使用透明加密时，通常包括3个阶段：\n定义用于加密的密钥 使用SQL语法，定义哪些对象需加密，不同产品，定义加密对象的粒度不同 使用SQL语法，访问透明加密表，以及进行其他运维等操作 各产品中，定义加密对象的SQL语法如下：\n-- 一、oracle CREATE TABLE t1(c1 INT, c2 TEXT ENCRYPT); CREATE TABLESPACE ts1 DATAFILE .. ENCRYPTION USING \u0026#39;AES192\u0026#39; ENCRYPT; -- 二、sql server CREATE DATABASE ENCRYPTION KEY WITH ALGORITHM = AES_256 .. ALTER DATABASE db1 SET ENCRYPTION ON; -- 三、oceanbase CREATE TABLESPACE ts1 encryption = \u0026#39;y\u0026#39;; -- mysql cmpt CREATE TABLESPACE ts1 ENCRYPTION USING \u0026#39;aes-256\u0026#39;; -- oracle cmpt -- 四、kingbase CREATE TABLESPACE ts .. WITH (ENCRYPTION = TRUE); CREATE TABLE ts .. ENCRYPTED BY \u0026#39;this is a key\u0026#39;; -- 五、dm8 intdb .. ENCRYPT_NAME .. CREATE TABLESPACE .. ENCRYPT WITH .. CREATE TABLE t1 (c1 INT, c2 INT ENCRYPT WITH ..); -- 六、gaussdb CREATE TABLE t1 .. WITH (enable_tde=on); 各产品中，按定义加密对象的粒度，区别如下：\n产品 加密粒度 加密范围 oracle tablespace, column relfile, redo sql server database relfile, transaction log oceanbase tablespace relfile, clog kingbase tabpespace, table relfile, wal dm8 cluster, tablespace, coulumn relfile, redo gaussdb table relfile, wal 三、实现难点 在第1版本的特性中，出于工作量考虑，部分功能无法满足。\n加密范围\n当用户执行SQL时，例如INSERT INTO t1 VALUES ('data1')，在磁盘上，以下多类文件中，都可能存在数据data1，本版本只支持加密部分文件中的数据：\nrelation file（支持） toast file (支持) index file (支持) materialized view file (不支持) double write file (如果有，可以支持) catalog file (pg_stats) （不支持） wal file （不支持） 物理备份 物理复制流 逻辑复制流 … 密钥管理\n大部分数据库的加密方案中，数据库只存储密钥密文，高级别的密钥，由第三方密钥管理服务存储。\n但是，为考虑易用性、可测试性、可扩展性等，本版本暂时只支持数据库本机管理密钥。\n2.2 功能说明 2.2.1 使用流程 场景一、配置透明加密 -- 1. 创建数据密钥 CREATE ENCRYPTION KEY tde_key WITH (source=local, password=\u0026#39;pass.123\u0026#39;); -- 集群中所有表，都使用同1个密钥加密 -- 集群中，暂时只允许存在1个密钥，CREATE多余密钥报错 -- 参考openGauss gs_guc encrypt命令，生成密钥，并简单加密存储 -- 未来计划：全密态主密钥、数据密钥，审计日志加密密钥，系统表password加密密钥（fdw, replication等）等其他特性， 可统一使用该语法，统一管理密钥 -- 2. 查看数据密钥 SELECT * FROM vb_encryption_key; keyoid | keyname | keyinfo --------+----------+------------- 17000 |tde_key | type=local -- password单独加密存储 场景二、为表设置加密属性 -- 1. 创建表 CREATE TABLE t1 (c1 TEXT, c2 TEXT)； -- 2. 创建加密策略 CREATE ENCRYPTION POLICY ep1 FOR public.t1 KEY tde_key ALGORITHEM aes_256_ctr MAC ALGORITHM sha256; -- ALGORITHEM： 默认aes_256_ctr，可选aes_256_gcm，aes_256_cbc -- MAC ALGORITHM：默认无，可选sha256 -- 未来计划： 可指定密钥来源，指定硬件加密，指定密钥自动乱转等 -- 暂不支持国密算法 -- 设置初衷：规范化多个对象安全特性 -- (1) 审计 -- CREATE AUDIPT POLICY ap1 OPERATE select,insert,... -- (2) 强制访问控制 -- CREATE ACCESS POLICY acp1 FOR t1 .. -- (3) 防篡改 -- CRATE LEDGER POLICY lp1 FOR .. -- (4) 脱敏 -- CREATE MASK POLLICY mp1 FOR .. -- (5) 全密态 -- CREATE ENCRYPTION POLICY ep1 FOR .. -- 3. 查看表加密策略 SELECT * FROM vb_encryption_policy; polname | polkey | polalgo | polmacalgo ---------+---------+------------+------------ ep1 | tde_key |aes_256_ctr | sha256 -- 4. 查看加密对象 SELECT * FROM vb_secure_class; relid | relname | encryption_policy | access_policy ------+---------+-------------------+--------------- 17001 | t1 | ep1 | -- 5. 向表中存储数据（数据存储至） INSERT INTO t1 VALUES (\u0026#39;data11\u0026#39;, \u0026#39;data12\u0026#39;); -- 6. 查看表文件路径 SELECT setting || \u0026#39;/\u0026#39; || pg_relation_filepath(\u0026#39;t1\u0026#39;) FROM pg_settings WHERE name = \u0026#39;data_directory\u0026#39;; -- 示例输出 ?column? ------------------------------------------------------- /path/to/data_directory/base/16386/16387 -- 7. 验证数据加密存储 \\! hexdump -C /path/to/data_directory/base/16386/16387 -- 预期输出：文件中，查看不到明文数据 (\u0026#39;data11\u0026#39;, \u0026#39;data12\u0026#39;) -- 8. 从表中查询数据 SELECT * FROM t1; -- 预期输出：查询到数据明文，用户无法直观感受到自动解密过程 -- 9. 清理环境 DROP TABLE t1; 场景三、为表修改加密属性 -- 1. 创建非加密表 CREATE TABLE t1 (c1 TEXT, c2 TEXT)； -- 2. 为表修改加密属性 CREATE ENCRYPTION POLICY ep1 KEY tde_key ALGORITHEM aes_256_ctr MAC ALGORITHM sha256; ALTER ENCRYPTION POLICY ep1 ADD public.t1; -- 预期：表中新生成的page，数据将被加密，旧数据不会立刻被加密 -- 3. 立即加密旧数据 VACUUM FULL t1; -- 5. 为表取消加密属性 ALTER ENCRYPTION POLICY ep1 REMOVE public.t1; -- 提示用户：旧数据仍然出于加密状态，用VACUUM FULL等语法，可立即解密旧数据 -- 预期：表中新生成的page，数据不再被加密，旧数据仍然处于加密状态 -- 6. 立即解密旧数据 VACUUM FULL t1; -- 7. 为表修改其他加密属性 ALTER ENCRYPTION POLICY ep1 ALGORITHEM aes_256_cbc; -- 8. 清理环境 DROP TABLE t1; 场景四、轮转密钥 -- 1. 创建表 CREATE TABLE t1 (c1 TEXT, c2 TEXT); INSERT INTO t1 VALUES (\u0026#39;data11\u0026#39;, \u0026#39;data12\u0026#39;); -- 2. 加密表 CREATE ENCRYPTION POLICY ep1 FOR t1; -- 3. 轮转密钥 ALTER ENCRYPTION KEY tde_key ROTATION; -- 预期：表中新写入的数据，将使用新密钥加密 -- 4. 重启 或 不重启集群 -- 5. 查询旧数据 SELECT * FROM t1; -- 预期：旧数据仍然使用旧密钥，但是可正常解密 -- 8. 清理环境 DROP TABLE t1; 场景五、为索引设置加密属性 基表加密时，索引也会默认加密\n扩展场景一、为其他类型表设置加密属性 加密toast表\n-- 1. 创建表 CREATE TABLE t1 (c1 INT, c2 TEXT); -- 包含TEXT等可变长度的列 CREATE ENCRYPTION POLICY ep1 KEY tde_key FOR t1; -- 2. 存储超长数据 INSERT INTO t1 VALUES (1, REPEAT(\u0026#39;a\u0026#39;, 3000)); -- 3. 查看toast表的oid SELECT reltoastrelid FROM pg_class WHERE relname = \u0026#39;t1\u0026#39;; -- 4. 查看toast表的物理文件 SELECT setting || \u0026#39;/\u0026#39; || pg_relation_filenode(xxx) FROM pg_settings WHERE name = \u0026#39;data_directory\u0026#39;; -- 预期：t1对应toast表，文件中，数据被加密存储 加密分区表\n预期：每个分区对应的文件中，数据被加密存储\n临时表\n预期：临时文件中，数据被加密存储\n扩展场景二、主备加密一致性 主机加密数据\nCREATE TABLE t1 (c1 INT, c2 TEXT); -- 包含TEXT等可变长度的列 CREATE ENCRYPTION POLICY ep1 KEY tde_key FOR t1; INSERT INTO t1 VALUES (generate_series(1, 2000), \u0026#39;cipher\u0026#39;); ALTER ENCRYPTION POLICY ep1 REMOTE t1; INSERT INTO t1 VALUES (generate_series(1, 2000), \u0026#39;plain\u0026#39;); 备机数据需与主机一致\n在备机上，数据文件需与主机严格一致。\n解释：大部分加密场景中，加密数据会产生膨胀，导致文件中page容量变小。例如，主机page 1加密，数据容量为7.9k，备机page 1不加密，数据容量为8k。发生主备切换后，可能出现1个节点的page 1有容量，可以写入数据，另一个阶段的page 1容量不够，无法进行redo。 扩展场景三、加密其他文件 双写文件（如果有）\n需要加密 wal文件\n本版本暂不支持加密 异常场景一、关闭透明加密 如果使用第三方密钥服务，可能出现密钥服务异常，影响数据库集群状态的问题，需关闭透明加密以降低影响范围。\n关闭透明加密后，可能出现很多功能问题。比如：无法向表中写数据、无法从表中读数据、无法故障恢复等。\n本版本无复杂场景，不会出现这些问题。\n异常场景二、密钥异常 执行CREATE ENCRYPTION KEY tde_key语法，会生成密钥文体，存放在数据目录下，同时生成wal日志。基于主备物理复制、物理备份等方式，保证密钥安全。\n2.2.2 配置参数和文件 新增密钥文件\n在数据目录下，新增文件夹 /vb_sec，新增文件 /vb_sec/key_info，用于存储数据密钥\n当执行CREATE ENCRYPTION KEY时，生成密钥文件。 2.2.3 数据相关性 新增wal类型：当执行CREATE ENCRYPTION KEY时，生成密钥文件，产生redo log，用于向备机同步密钥文件。\n2.3 接口信息 新增密钥管理语法\nCREATE ENCRYPTION KEY $key_name (source = local, password = $password) ALTER ENCRYPTION KEY $key_nam ROTATION; DROP ENCRYPTION KEY $key_name; 新增加密策略语法\nCREATE ENCRYPTION POLICY $pollicy_name [FOR [TABLE] $table_name [, $table_name ...]] KEY $key_name [ALGORITHEM {aes_256_ct | aes_256_gcm | aes_256_cbc} ] -- 默认：aes_256_ct [MAC ALGORITHM {sha256}] -- 默认：空 ALTER ENCRYPTION POLICY $pollicy_name [ADD [TABLE] $table_name [, $table_name ...]] [REMOVE [TABLE] $table_name [, $table_name ...]] [ALGORITHEM {aes_256_ct | aes_256_gcm | aes_256_cbc} ] DROP ENCRYPTION POLICY $pollicy_name; 新增系统表vb_encryption_key\n-- 表结构： keyoid | keyname | keyinfo -------+---------+--------- 新增系统表vb_encryption_policy\n-- 表结构： polname | polkey | polalgo | polmacalgo ---------+---------+------------+------------ 新增系统表vb_secure_class\n-- 表结构： relid | relname | encryption_policy | access_policy ------+---------+-------------------+--------------- 2.4 正反向行为 2.4.1 生效说明 查看系统表，判断密钥、策略等是否设置成功\n查看表物理文件，判断数据是否加密成功\n2.4.2 提示信息 加密解密异常时，日志中会记录相关错误信息\n2.4.3 约束和依赖 无\n2.5 安全性 2.5.1 权限控制 使用ENCRYPTION KEY、ENCRYPTION POLICY语法时，需特权用户，例如superuser，sysadmin等，三权分立场景，需安全管理员\n2.5.2 审计 ENCRYPTION KEY、ENCRYPTION POLICY语法作为通用DDL审计\n2.6 影响范围 2.6.1 对已有UDT,UDF, ECPG的影响 无\n2.6.2 对系统函数的影响 未新增\n2.6.3 对系统CATALOG的影响 关于新增系统表的详细信息，请看上文接口信息章节：\n新增系统表vb_encryption_key 新增系统表vb_encryption_policy 新增系统表vb_secure_class 2.6.4 对xlog日志格式、数据格式的影响 在执行CRETE/ALTER/DROP ENCRYPTION KEY时，参数wal，新增wal类型\n2.6.5 与其他功能交互时的行为表现 无\n2.6.6 版本兼容性 前向兼容：本版本首次支持透明加密，不涉及兼容性 后向兼容：设计阶段，已考虑将来可能接收的需求： 加密算法：支持国密sm4等算法 密钥管理：支持对接第三方密钥管理服务 加密组件：支持对接第三方加密机 加密范围：支持加密wal日志 2.6.7 用户行为变更 无\n2.7 指标相关 2.7.1 关键资源指标 CPU：开启透明加密，数据存储时，需加密数据，占用CPU。tpcc场景，加密全部表，CPU占用率升高10%以内。 内存：额外占用内存可忽略，加密存储时，在page上原地加密即可，无需额外申请内存 IO：无占用 2.7.2 系统性指标 无\n2.7.3 性能指标 tpcc场景，加密全部表、索引，与不加密相比，使用默认加密算法aes_256_ctr，性能劣化5%以内。\n2.8 测试建议 无\n2.8 其他说明 无\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/13-requirement-tde/","summary":"\u003ch1 id=\"1-简介\"\u003e1 简介\u003c/h1\u003e\n\u003ch2 id=\"11-目的\"\u003e1.1 目的\u003c/h2\u003e\n\u003cp\u003e透明加密特性提供数据加密功能，核心原理是在数据库将数据存储至磁盘时，先加密再存储。\u003cbr\u003e\n本需求将从0设计透明加密特性，在保障功能、性能、易用性、可用性、可维护性、可扩展性等的前提下，让特性达到商用标准。\u003c/p\u003e\n\u003ch2 id=\"12-适用范围\"\u003e1.2 适用范围\u003c/h2\u003e\n\u003cp\u003eVastbase V5版本。\u003c/p\u003e\n\u003ch2 id=\"13-术语定义首字母缩写词和缩略语\"\u003e1.3 术语定义、首字母缩写词和缩略语\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eTDE：Transparent Data Encryption，透明数据加密，由数据库提供的数据加密特性\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"14-参考资料\"\u003e1.4 参考资料\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eoracle 透明加密特性：\u003ca href=\"https://docs.oracle.com/en/database/oracle/oracle-database/26/dbtde/preface.html\"\u003ehttps://docs.oracle.com/en/database/oracle/oracle-database/26/dbtde/preface.html\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003esql server 透明加密特性：\u003ca href=\"https://learn.microsoft.com/en-us/sql/relational-databases/security/encryption/transparent-data-encryption?view=sql-server-ver17\"\u003ehttps://learn.microsoft.com/en-us/sql/relational-databases/security/encryption/transparent-data-encryption?view=sql-server-ver17\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eoceanbase 透明加密特性：\u003ca href=\"https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004475958\"\u003ehttps://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004475958\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003ekingbase 透明加密特性：\u003ca href=\"https://docs.kingbase.com.cn/cn/KES-V9R1C10/safe/transparent-data-Encyption\"\u003ehttps://docs.kingbase.com.cn/cn/KES-V9R1C10/safe/transparent-data-Encyption\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003edm8 透明加密特性：\u003ca href=\"https://eco.dameng.com/document/dm/zh-cn/pm/storage-encryption.html#7.1.1%20%E5%85%A8%E5%BA%93%E5%8A%A0%E5%AF%86\"\u003ehttps://eco.dameng.com/document/dm/zh-cn/pm/storage-encryption.html#7.1.1%20%E5%85%A8%E5%BA%93%E5%8A%A0%E5%AF%86\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003egaussdb 透明加密特性：\u003ca href=\"https://support.huaweicloud.com/intl/zh-cn/fg-gaussdb-dist-v8/gaussdb-18-0019.html\"\u003ehttps://support.huaweicloud.com/intl/zh-cn/fg-gaussdb-dist-v8/gaussdb-18-0019.html\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-透明加密\"\u003e2 透明加密\u003c/h1\u003e\n\u003ch2 id=\"21-功能简述\"\u003e2.1 功能简述\u003c/h2\u003e\n\u003ch3 id=\"一基本原理\"\u003e一、基本原理\u003c/h3\u003e\n\u003cp\u003e通常，用户将数据传输给数据库后，数据库将数据存储到磁盘。攻击者可能利用多种数据库内部或外部漏洞，例如操作系统漏洞等，绕过数据库安全机制，直接从磁盘读取数文件，窃取用户数据。\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e透明加密\u003c/strong\u003e，是一种由数据库提供的加密特性，可有效解决攻击者从磁盘窃取数据的问题。开启透明加密后，数据库将数据存储到磁盘时，先加密数据，再存储数据密文；数据库从磁盘读取数据时，先解密数据密文，再进行其他计算。用户访问透明加密表时，包括存储、读取数据等，与访问普通表无任何区别，加密和解密过程由数据库自动完成，即对用户透明。\u003c/p\u003e\n\u003ch3 id=\"二竞品分析\"\u003e二、竞品分析\u003c/h3\u003e\n\u003cp\u003e几乎所有商用关系数据库中，都支持透明加密特性，包括oracle, sql server, oceanbase, kingbase, dm8等，postgresql不支持透明加密特性。\u003cbr\u003e\n使用透明加密时，通常包括3个阶段：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e定义用于加密的密钥\u003c/li\u003e\n\u003cli\u003e使用SQL语法，定义哪些对象需加密，不同产品，定义加密对象的粒度不同\u003c/li\u003e\n\u003cli\u003e使用SQL语法，访问透明加密表，以及进行其他运维等操作\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e各产品中，定义加密对象的SQL语法如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 一、oracle\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eTEXT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eENCRYPT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eTABLESPACE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ets1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eDATAFILE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eENCRYPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSING\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;AES192\u0026#39;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eENCRYPT\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 二、sql server\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eENCRYPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eKEY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eALGORITHM\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eAES_256\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eALTER\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eDATABASE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edb1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eSET\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eENCRYPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eON\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 三、oceanbase\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eTABLESPACE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ets1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eencryption\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;y\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- mysql cmpt\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eTABLESPACE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ets1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eENCRYPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eUSING\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;aes-256\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"c1\"\u003e-- oracle cmpt\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 四、kingbase\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eTABLESPACE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ets\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eENCRYPTION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTRUE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ets\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eENCRYPTED\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eBY\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;this is a key\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 五、dm8\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eintdb\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eENCRYPT_NAME\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eTABLESPACE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eENCRYPT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ec2\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eENCRYPT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 六、gaussdb\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e..\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eWITH\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eenable_tde\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e\u003cspan class=\"k\"\u003eon\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e各产品中，按定义加密对象的粒度，区别如下：\u003c/p\u003e","title":"海量 透明加密 需求"},{"content":"1 强制访问控制 1.1 功能简述 从实现的角度看，当用户执行SQL时，强制访问控制主要实现以下功能：\nCREATE ACCESS POLICY ..：在系统表中，记录ACCESS POLICY，以及其中的LABLE等信息 CREATE TABLE ..：创建表时，如果设置acess_policy字段，则自动为表新增1列隐藏列，列名为access_label INSERT ..：向表插入数据时，根据当前用户的write_label，自动为数据生成access_label列的值。 SELECT ..：从表查询数据时，根据当前用户的read_label，自动为查询语句添加过滤条件has_mac_permission(access_label, read_label) 另外，如果为表设置访问策略，需在索引中同时设置访问策略：\nCREATE INDEX ..：自动为索引新增1列，列名为access_label 对于一些其他语法，也许单独适配，包括：\nCOPY ..：自动修改旧数据的access_label值 1.2 实现方案 1.2.1 整体流程 本文重点从源码角度，介绍强制访问控制策略如何基于隐藏列，实现强制访问控制，包括：创建、填充、匹配隐藏列等流程。\n核心功能的大致流程如下：\nUser Vastbase Disk +---------------------------------------------------+---------------------------------------------------------+ # 管理员 | 1. CREATE ACCESS POLICY .. LEVEL .. LABEL .. --\u0026gt; | | 2. 存储access policy至系统表vb_access_policy --\u0026gt; | 3. 存储access level至系统表vb_access_level --\u0026gt; | 4. 存储access label至系统表vb_access_label --\u0026gt; | 5. CREATE TABLE .. (access_policy=..) --\u0026gt; | | 6. 识别是否设置access_policy | 7. 自动添加隐藏列access_label | 8. 存储access_policy至系统表pg_class --\u0026gt; | 9. 存储accessl_label定义至系统表pg_attribute --\u0026gt; | 10. CREATE USER .. ACCESS POLICY .. READ LABEL .. WRITE LABEL --\u0026gt; | | 11. 存储access_policy, read_label, write_label至系统表pg_authid --\u0026gt; # 普通用户 | 12. vsql -U username -W password --\u0026gt; | | 14. set read_label = .. / write_label = .. --\u0026gt; | | 15. 查询pg_authid，判断read_label/write_label是否合法 \u0026lt;-- | 16. 设置临时的read_label/write_label | 17. 如何用户未自动设置read_label/write_label，自动根据pgauthid设置 | 18. INSERT .. --\u0026gt; | | 19. 查询pg_class，判断表是否有access_policy \u0026lt;-- | 20. 自动为隐藏列赋值，取值为write_label | 21. SELECT .. --\u0026gt; | | 22. 查询pg_class，判断表是否有access_policy \u0026lt;-- | 23. 语义分析 | 24. 查询重写：自动新增过滤条件：WHERE has_mac_permission(access_label, read_label) | 24. 计划执行：扫描Tuple，根据过滤条件，过滤不满足权限检查的Tuple 1.2.2 详细流程 一、创建策略 当用户创建策略时，例如：\nCREATE ACCESS POLICY p1 LEVLE l1=10, l2=20, l3=30 MARK ma, mb LABEL lab1=l1, lab2=l2, laba1=l1:ma, labb1=l1:mb; 内核将access policly, level, mark, label等信息存储在多个系统表中。系统表定义如下：\n-- 存储访问控制策略 SELECT * FROM vb_access_policy; poloid | polname -------+--------- 17001 | p1 -- 存储LEVEL SELECT * FROM vb_access_level; polid | levname | levnum (int32类型) ------+---------+-------- 17001 | l1 | 10 17001 | l2 | 20 17001 | l3 | 30 -- 存储MARK SELECT * FROM vb_access_mark; polid | marname | marval (uint32类型) ------+---------+----------- 17001 | ma | 0x00000001 17001 | mb | 0x00000002 -- 存储LABEL SELECT * FROM vb_access_label; polid | labname | levname | marname | labval (uint64类型,高32位存储levle值，低32位存储mark值) ------+---------+---------+---------+-------------------- 17001 | lab1 | l1 | ma | 0x0000011000000001 二、创建表 用户创建表时，例如：\nCREATE TABLE t1(c1 INT, c2 TEXT) WITH (access_policy = p1); 内核判断如果用户设置了access_policy，则自动为表新增1列隐藏列，列名为access_label，存储每行数据的访问控制标签，等价于用户执行：\nCREATE TABLE t1(c1 INT, c2 TEXT，access_label UINT64) (access_policy = p1); 在代码中，关键实现流程如下：\n@pg.16 PostgresMain exec_simple_query(\u0026#39;CREATE TABLE t1(c1 INT, c2 TEXT) WITH (access_policy = p1);\u0026#39;) # 1. 定义表，启用强制访问控制 pg_parse_query # 2. 语法解析 PortalStart PortalRun PortalRunMulti PortalRunUtility ProcessUtility standard_ProcessUtility # 3. 执行DDL ProcessUtilitySlow transformCreateStmt # 3.1 语义分析与预处理 foreach(CreateStmt.tableElts) # 格式化用户定义的列 transformColumnDefinition lappend(CreateStmtContext.columns) if CreateStmt.options has \u0026#39;access_policy\u0026#39; # 如何设置访问策略，自动新增隐藏列 \u0026#39;makeNode(ColumnDef)\u0026#39; # 列名：access_label, 类型：uint64 \u0026#39;transformColumnDefinition\u0026#39; \u0026#39;lappend(CreateStmtContext.columns)\u0026#39; DefineRelation # 3.2 在系统表中存储表信息 MergeAttributes BuildDescForRelation heap_create_with_catalog AddNewRelationTuple(\u0026#39;pg_class\u0026#39;, CreateStmt.options) # 在pg_class中，存储access_policy的取值 \u0026#39;AddNewAttributeTuples(\u0026#39;pg_attribute\u0026#39;, CreateStmtContext.columns)\u0026#39; # 在pg_attribute中，存储新增的隐藏列access_label 三、创建用户 四、登录集群 五、插入数据 用户插入数据时，例如：\nINSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;); 内核判断如果为表设置了access_policy，则在物化行数据阶段，自动填充隐藏列的值，等价于用户执行：\nINSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;, $write_label); -- write_label：会话级GUC参数write_label的取值 在代码中，关键实现流程如下：\n@pg.16 PostgresMain exec_simple_query(\u0026#39;INSERT INTO t1 VALUES (1, \u0026#39;data1\u0026#39;);\u0026#39;) # 1. 执行INSET语法 pg_parse_query # 2. 语法解析 pg_analyze_and_rewrite_fixedparams parse_analyze_fixedparams # 3. 语义分析 pg_rewrite_query # 4. 查询重写 pg_plan_queries # 5. 计划生成 pg_plan_query PortalStart PortalRun # 6. 计划执行 PortalRunMulti ProcessQuery ExecutorStart standard_ExecutorStart InitPlan # 6.1 初始化计划 ExecInitNode ExecInitModifyTable ExecInitResultRelation ExecGetRangeTableRelation # 初始化relation结构体 table_open relation_open RelationIdGetRelation RelationBuildDesc \u0026#39;ScanPgRelation\u0026#39; # 从pg_class系统表中获取表的access_policy信息 systable_beginscan(pg_class) ExecutorRun ExecProcNode ExecModifyTable ExecInsert # 6.2 执行insert算子 ExecMaterializeSlot # 物化行数据 (1, \u0026#39;data1\u0026#39;)，生成tuple tts_heap_materialize \u0026#39;if Relation.access_policy\u0026#39; # 修改tuple，为access_label列赋值，取值为guc参数write_label \u0026#39;mac_insert_tuple_label\u0026#39; \u0026#39;heap_modify_tuple\u0026#39; 六、查询数据 用户查询数据时，例如：\nSELECT * FROM t1 WHERE c1 \u0026gt; 1; 内核判断如果为表设置了access_policy，则在查询重写阶段，自动新增权限判断过滤条件，等价于用户执行：\nSELECT * FROM t1 WHERE has_mac_permission(access_label, $read_label) AND c1 \u0026gt; 1; -- access_label：t1中的隐藏列 -- read_label：会话级GUC参数read_label的取值 在代码中，关键实现流程如下：\n@pg.16 PostgresMain exec_simple_query(\u0026#39;SELECT * FROM t1 WHERE c1 \u0026gt; 1;\u0026#39;) # 1 执行SELECT语法 pg_parse_query # 2 语法解析 pg_analyze_and_rewrite_fixedparams parse_analyze_fixedparams # 3 语义分析 pg_rewrite_query # 4 查询重写 QueryRewrite RewriteQuery # 4.1 重写INSERT/UPDATE/DELETE/... fireRIRrules # 4.2 重写SELECT table_open get_row_security_policies # 4.2.1 为表设置行级访问控制策略 get_policies_for_relation add_security_quals RangeTblEntry-\u0026gt;securityQuals \u0026#39;if Relation.access_policy:\u0026#39; # 4.2.3 为表设置强制访问策略 \u0026#39;mac_set_relation_quals\u0026#39; \u0026#39;RangeTblEntry-\u0026gt;securityQuals += has_mac_permission(access_label, read_label)\u0026#39; pg_plan_queries # 5 计划生成 pg_plan_query planner standard_planner subquery_planner pull_up_subqueries preprocess_qual_conditions grouping_planner query_planner build_simple_rel # 5.1 初始化表的过滤条件 \u0026#39;RelOptInfo.baserestrictinfo = securityQuals\u0026#39; make_one_rel set_base_rel_pathlists # 5.2 查找扫描路径：查找所有Scan类型 set_rel_pathlist set_plain_rel_pathlist create_seqscan_path get_cheapest_fractional_path create_plan create_plan_recurse create_scan_plan create_seqscan_plan # 5.3 生成扫描算子 \u0026#39;SeqScan.qual = RelOptInfo.qual\u0026#39; PortalStart PortalRun # 6 计划执行 PortalRunSelect ExecutorRun standard_ExecutorRun ExecutePlan ExecProcNode ExecScan # 6.1 执行scan算子 ExecScanFetch # 扫描tuple ExecQual # 执行过滤条件 ExecEvalExprSwitchContext \u0026#39;has_mac_permission(tuple.access_label, $read_label)\u0026#39; # 判断tuple是否满足过滤条件 七、更新数据 八、创建索引 1.3 接口说明 新增SQL语法：ACCESS POLICY\nCREATE ACCESS POLICY $policy_name [LEVEL $level_name=$level_number [, $level_name=$level_number ...]] [MARK $mark_name [, $mark_name ...]] LABEL $label_name={$level_name | $mark_name | $level_name:$mark_name [, ...]} ALTER ACCESS POLICY $policy_name [ADD LEVEL $level_name=$level_number [, $level_name=$level_number ...]] [ALTER LEVEL $level_name=$level_number [, $level_name=$level_number ...]] [DROP LEVEL $level_name [, $level_name ...]] [ADD MARK ..] [ALTER MARK ..] [DROP MARK ..] [ADD LABEL ..] [ALTER LABEL ..] [DROP LABEL ..] DROP ACCESS POLICY [IF EXISTS] $policy_name [, $policy_name]; 扩展SQL语法：CREATE/ATLER USER\nCREATE/ALTER USER $user_name [ACCESS POLICY $policy_name WRITE $label_list READ $label_list] 扩展SQL语法：CREATE/ALTER TABLE\nCREATE TABLE $table_name .. WITH (access_policy = $policy_name); ALTER TABLE $table_name .. WITH (access_policy = none); 新增会话级GUC参数write_label\n新增会话级GUC参数read_label\n新增系统表vb_access_policy\n新增系统表vb_access_level\n新增系统表vb_access_mark\n新增系统表vb_access_label\n扩展系统表pg_authid：新增2列rolaccpol，rolacclab\n新增系统函数has_mac_permission(uint64, uint64)\n1.4 内存管理 未新增共享内存。只在query的内存上下中，临时存储与访问策略相关的信息，所有新申请内存的生命周期与query内存上下文一致。\n1.5 安全 强制访问控制，与自主访问控制、行级访问控制共存，即当主体访问客体时，同时生效。\n审计新增的DDL语法：CREATE/ALTER/DROP ACCESS POLICY。\n1.6 性能 tpcc场景，为所有表设置访问策略，与不设置相比，性能劣化不高于5%\n1.7 专利 无\n1.8 升级管理 对系统元数据影响：\n新增2个GUC：write_label、read_label 新增4个系统表：vb_access_policy、vb_access_level、vb_access_mark、vb_access_label 修改系统表：pg_authid：新增2列rolaccpol，rolacclab\n对用户表影响： 无：当前版本，仅支持CRETE TABLE阶段设置访问策略 1.9 其他说明 无\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/14-design-mac/","summary":"\u003ch1 id=\"1-强制访问控制\"\u003e1 强制访问控制\u003c/h1\u003e\n\u003ch2 id=\"11-功能简述\"\u003e1.1 功能简述\u003c/h2\u003e\n\u003cp\u003e从实现的角度看，当用户执行SQL时，强制访问控制主要实现以下功能：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eCREATE ACCESS POLICY ..：在系统表中，记录ACCESS POLICY，以及其中的LABLE等信息\u003c/li\u003e\n\u003cli\u003eCREATE TABLE ..：创建表时，如果设置acess_policy字段，则自动为表新增1列隐藏列，列名为access_label\u003c/li\u003e\n\u003cli\u003eINSERT ..：向表插入数据时，根据当前用户的write_label，自动为数据生成access_label列的值。\u003c/li\u003e\n\u003cli\u003eSELECT ..：从表查询数据时，根据当前用户的read_label，自动为查询语句添加过滤条件has_mac_permission(access_label, read_label)\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e另外，如果为表设置访问策略，需在索引中同时设置访问策略：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eCREATE INDEX ..：自动为索引新增1列，列名为access_label\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003e对于一些其他语法，也许单独适配，包括：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003eCOPY ..：自动修改旧数据的access_label值\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"12-实现方案\"\u003e1.2 实现方案\u003c/h2\u003e\n\u003ch3 id=\"121-整体流程\"\u003e1.2.1 整体流程\u003c/h3\u003e\n\u003cp\u003e本文重点从源码角度，介绍强制访问控制策略如何基于隐藏列，实现强制访问控制，包括：创建、填充、匹配隐藏列等流程。\u003cbr\u003e\n核心功能的大致流程如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eUser                                              Vastbase                        Disk\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e+---------------------------------------------------+---------------------------------------------------------+\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 管理员\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 1. CREATE ACCESS POLICY .. LEVEL .. LABEL .. --\u0026gt;  \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 2. 存储access policy至系统表vb_access_policy --\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 3. 存储access level至系统表vb_access_level --\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 4. 存储access label至系统表vb_access_label --\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 5. CREATE TABLE .. \u003cspan class=\"o\"\u003e(\u003c/span\u003e\u003cspan class=\"nv\"\u003eaccess_policy\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e..\u003cspan class=\"o\"\u003e)\u003c/span\u003e --\u0026gt;         \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 6. 识别是否设置access_policy\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 7. 自动添加隐藏列access_label\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 8. 存储access_policy至系统表pg_class --\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 9. 存储accessl_label定义至系统表pg_attribute --\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 10. CREATE USER ..\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    ACCESS POLICY .. READ LABEL ..  WRITE LABEL --\u0026gt; \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 11. 存储access_policy, read_label, write_label至系统表pg_authid --\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 普通用户\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 12. vsql -U username -W password --\u0026gt;              \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 14. \u003cspan class=\"nb\"\u003eset\u003c/span\u003e \u003cspan class=\"nv\"\u003eread_label\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e .. / \u003cspan class=\"nv\"\u003ewrite_label\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e ..  --\u0026gt;   \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 15. 查询pg_authid，判断read_label/write_label是否合法 \u0026lt;--\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 16. 设置临时的read_label/write_label\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 17. 如何用户未自动设置read_label/write_label，自动根据pgauthid设置\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 18. INSERT ..  --\u0026gt;                                \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 19. 查询pg_class，判断表是否有access_policy \u0026lt;--\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 20. 自动为隐藏列赋值，取值为write_label\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e 21. SELECT .. --\u0026gt;                                 \u003cspan class=\"p\"\u003e|\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 22. 查询pg_class，判断表是否有access_policy \u0026lt;--\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 23. 语义分析\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 24. 查询重写：自动新增过滤条件：WHERE has_mac_permission\u003cspan class=\"o\"\u003e(\u003c/span\u003eaccess_label, read_label\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                                                    \u003cspan class=\"p\"\u003e|\u003c/span\u003e 24. 计划执行：扫描Tuple，根据过滤条件，过滤不满足权限检查的Tuple\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"122-详细流程\"\u003e1.2.2 详细流程\u003c/h3\u003e\n\u003ch4 id=\"一创建策略\"\u003e一、创建策略\u003c/h4\u003e\n\u003cp\u003e当用户创建策略时，例如：\u003c/p\u003e","title":"海量 mac 设计"},{"content":"1 简介 1.1 目的 本文主要包括以下关键内容：\n介绍访问控制的基本概念 调研其他厂商实现强制控制的方式 设计Vastbase强制访问控制特性，介绍如何使用强制访问特性 1.2 适用范围 Vastbase V5版本。\n1.3 术语定义、首字母缩写词和缩略语 MAC：Mandatory Access Control，强制访问控制，主体访问客体时，基于主体、客体属性，强制控制访问权限。 DAC：Discretionary Access Control，自主访问控制，数据拥有者可自行设置访问权限。 1.4 参考资料 oracle 强制访问控制（标签访问控制 RLS）：https://docs.oracle.com/en/database/oracle/oracle-database/26/olsag/part1.html#GUID-C20C62AE-2A30-45F9-AEEA-52A0D3286FBA oceanbase 强制访问控制（兼容oracle）：https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004475944 kingbase 强制访问控制：https://bbs.kingbase.com.cn/kingbase-doc/v8.6.7.24/safety/safety-guide/label-and-mac.html dm 强制访问控制：https://eco.dameng.com/document/dm/zh-cn/pm/mandatory-access-control.html GB/T-20009-数据库管理系统安全评估准则：https://drive.weixin.qq.com/s?k=AHUAfwdSAA82aDcvvD postgresql 行级访问控制 RLS：https://www.postgresql.org/docs/current/ddl-rowsecurity.html 2 强制访问控制 2.1 功能简述 一、基本概念 访问控制的定义：对主体访问客体的行为，系统按照安全策略进行限制与管理的安全机制。\n按安全策略分类，可将访问控制分为很多类，其中，常见的策略有：\n自主访问控制DAC：客体的拥有者，可自行向其他主体赋予访问权限。 强制访问控制MAC：系统为主体、客体分配安全标签，通过主体、客体的安全标签控制访问权限，很多情况下，即使客体的拥有者也无法向其他主体赋予访问权限。 角色访问控制RBAC：不在本文讨论范围。 在数据库领域，主体通常指数据库用户，客体通常指数据库对象，例如DATABASE、SCHEMA、TABLE、COLUMN、ROW、FUNCTION等。\n自主访问控制比较成熟，几乎所有关系数据库，都提供自主访问控制特性，例如，TABLE（客体）的属主（主体），可通过GRANT .. TO ..等语法，为其他用户（主体）赋予权限。\n强制访问控制理论比较成熟，但是，除oracle支持强制访问控制，以及oceanbase等几款产品兼容oracle强制访问控制之外，大部分关系数据库不支持强制访问控制。\n实现强制访问控制时，通常将主体、客体的安全标签，简化为安全等级，当主体访问客体时，比较主体、客体等级高低，以判断访问权限。在机密性场景，遵循不上读、不下写原则。在完整性场景，遵循不下读、不上写原则。\n本需求将从0设计强制访问控制特性，在保障功能、性能、易用性、可用性、可维护性、可扩展性等的前提下，让特性达到商用标准。\n二、竞品分析 oracle支持强制访问控制，客体是ROW，即行级强制访问控制。oceanbase、kingbase、dm的访问控制，与oracle一致。sql server、postgresql等其他产品不支持强制访问控制。\noracle强制访问控制使用示例如下：\n-- 1 定义策略 SA_SYSDBA.CREATE_POLICY(policy_name =\u0026gt; \u0026#39;p1\u0026#39;, column_name =\u0026gt; \u0026#39;lab_col1\u0026#39;) -- 2 定义级别 SA_COMPONENTS.CREATE_LEVEL(policy_name =\u0026gt; \u0026#39;p1\u0026#39;, level_num =\u0026gt; 1, short_name =\u0026gt; \u0026#39;x1\u0026#39;, long_name =\u0026gt; \u0026#39;x1\u0026#39;); SA_COMPONENTS.CREATE_LEVEL(\u0026#39;p1\u0026#39;, 20, \u0026#39;x2\u0026#39;, \u0026#39;x2\u0026#39;); SA_COMPONENTS.CREATE_LEVEL(\u0026#39;p1\u0026#39;, 30, \u0026#39;x3\u0026#39;, \u0026#39;x3\u0026#39;); -- 3 定义组件 SA_COMPONENTS.CREATE_LEVEL(policy_name =\u0026gt;\u0026#39;p1\u0026#39;, comp_num =\u0026gt; 100, short_name =\u0026gt; \u0026#39;sec\u0026#39;, long_name =\u0026gt; \u0026#39;security\u0026#39;); SA_COMPONENTS.CREATE_LEVEL(\u0026#39;p1\u0026#39;, 200, \u0026#39;stg\u0026#39;, \u0026#39;storage\u0026#39;); -- 4 创建标签 SA_SYSDBA.CREATE_LABEL(policy_name =\u0026gt; \u0026#39;p1\u0026#39;, label_tag =\u0026gt; \u0026#39;sec_normal\u0026#39;, label_value =\u0026gt; \u0026#39;x1:security\u0026#39;, data_label =\u0026gt; TRUE); SA_SYSDBA.CREATE_LABEL(\u0026#39;p1\u0026#39;, \u0026#39;sec_leader\u0026#39;, \u0026#39;x3:security\u0026#39;, false); -- 5 为主体设置属性 SA_USER_ADMIN.SET_LEVELS(policy_name =\u0026gt; \u0026#39;p1\u0026#39;, user_name =\u0026gt; \u0026#39;user1\u0026#39;, max_level =\u0026gt; \u0026#39;x2\u0026#39;, min_level =\u0026gt; \u0026#39;x1\u0026#39;, default_level =\u0026gt; \u0026#39;x1\u0026#39;, row_level =\u0026gt; \u0026#39;x1\u0026#39;); SA_USER_ADMIN.SET_COMPARTMENTS(policy_name =\u0026gt; \u0026#39;p1\u0026#39;, user_name =\u0026gt; \u0026#39;user1\u0026#39;, read_comps =\u0026gt; \u0026#39;sec\u0026#39;, write_comps =\u0026gt; \u0026#39;sec\u0026#39;, default_comps =\u0026gt; \u0026#39;sec\u0026#39;, row_comps =\u0026gt; \u0026#39;sec\u0026#39;); -- 6 为客体设置属性 CREATE TABLE t1(c1 INT); SA_USER_ADMIN.APPLY_TABLE_POLICY(policy_name=\u0026gt; \u0026#39;p1\u0026#39;, shema_name =\u0026gt; \u0026#39;s1\u0026#39;, table_name =\u0026gt; \u0026#39;t1\u0026#39;, table_options =\u0026gt; \u0026#39;READ_CONTROL, WRITE_CONTROL, CHECK_CONTROL\u0026#39;, label_function =\u0026gt; \u0026#39;f_create_t1_label(level, comp)\u0026#39;); -- 7 插入数据（主动定义标签） INSERT INTO t1 (c1, lab_col1) VALUES (1, CHAR_TO_LABEL(\u0026#39;p1\u0026#39;, \u0026#39;x1:sec\u0026#39;)); 三、实现思路 在数据库领域，除oracle外，没有其他可借鉴的方案。oracle的设计，太复杂，易用性太低。\n本需求将参考oracle的思想，简化oracle设计。\n2.2 功能说明 2.2.1 使用流程 场景一、基于等级的强制访问控制 -- 1. 定义访问策略 CREATE ACCESS POLICY p1 LEVLE l1=10, l2=20, l3=30 LABEL lab1=l1, lab2=l2; -- 2. 为表（客体）设置访问策略 CREATE TABLE t1 (c1 INT, c2 TEXT) WITH (access_policy = p1); -- 3. 为用户（主体）设置访问策略 CREATE USER u1 PASSWORD \u0026#39;u1.pass\u0026#39; ACCESS POLICY p1 WRITE LABEL lab1,lab2 -- 第1个标签是默认标签 READ LABEL lab1,lab2; -- 4. 为主体设置临时标签 SET write_label = lab1; SET read_label = lab1; -- 5. 写数据 INSERT INTO t1 VALUE (1, \u0026#39;a\u0026#39;); INSERT INTO t1 VALUE (2, \u0026#39;b\u0026#39;, lab2); -- 6. 读数据 SELECT *,access_label FROM t1; -- 预期输出 c1 | c2 | access_label -----+------+--------------- 1 | a | 1: -- 未主动指定label，使用默认的lab1 -- 还有一行不可见：(2, \u0026#39;b\u0026#39;, \u0026#39;2:\u0026#39;)，该行主动指定label为lab2，lab2的等级高于读等级read_label -- 内核会自动将本SQL语法改写为： -- SELECT *,access_label FROM t1 WHERE has_mac_permission(access_label, read_label); -- 7. 清理 DROP TABLE t1; DROP USER u1; DROP ACCESS POLICY p1; 场景二、基于标记的强制访问控制 -- 1. 定义访问策略 CREATE ACCESS POLICY p1 MARK ma, mb LABEL laba=ca, labb=cb; -- 2. 为表（客体）设置访问策略 CREATE TABLE t1 (c1 INT, c2 TEXT) WITH (access_policy = p1); -- 3. 为用户（主体）设置访问策略 CREATE USER u1 PASSWORD \u0026#39;u1.pass\u0026#39; ACCESS POLICY p1 WRITE LABEL laba,labb READ LABEL laba,labb; -- 4. 为主体设置临时标签 SET write_label = laba; SET read_label = laba; -- 5. 写数据 INSERT INTO t1 VALUE (1, \u0026#39;a\u0026#39;); INSERT INTO t1 VALUE (2, \u0026#39;b\u0026#39;, labb); -- 6. 读数据 SELECT *,access_label FROM t1; -- 预期输出 c1 | c2 | access_label -----+------+--------------- 1 | a | :ma -- 未主动指定label，使用默认的laba -- 还有一行不可见：(2, \u0026#39;b\u0026#39;, \u0026#39;:mb\u0026#39;)，该行主动指定label为lab2，lab2的标记为labb，读标记为laba -- 7. 清理 DROP TABLE t1; DROP USER u1; DROP ACCESS POLICY p1; 场景三、基于等级与标记的强制访问控制 -- 1. 定义访问策略 CREATE ACCESS POLICY p1 LEVLE l1=10, l2=20, l3=30 MARK ma, mb LABEL lab1=l1, lab2=l2, laba1=l1:ma, labb1=l1:mb; -- 用户读数据时，不仅要比较level的大小，还要比较mark是否相等 -- 详细步骤省略 场景四、查看访问控制策略 -- 1 创建访问策略 CREATE ACCESS POLICY p1 LEVLE l1=10, l2=20, l3=30 MARK ma, mb LABEL lab1=l1, lab2=l2, laba1=l1:ma, labb1=l1:mb; -- 2 查看访问控制策略 SELECT * FROM vb_access_policy; poloid | polname -------+--------- 17001 | p1 -- 3 查看 LEVEL SELECT * FROM vb_access_level; polid | levname | levelnum ------+---------+-------- 17001 | l1 | 10 17001 | l2 | 20 17001 | l3 | 30 -- 4 查看 MARK SELECT * FROM vb_access_mark; polid | mark ------+------ 17001 | ma 17001 | mb -- 5 查看 LABEL SELECT * FROM vb_access_label; polid | labbel | levelname | mark ------+--------+-----------+------- 17001 | lab1 | l1 | ma -- 6 为表（客体）设置访问策略 CREATE TABLE t1 (c1 INT, c2 TEXT) WITH (access_policy = p1); -- 7 查看表（客体）的访问策略 SELECT relname,reloptions FROM pg_class WHERE relname = \u0026#39;t1\u0026#39;; relname | reloptions --------+------------------ t1 | access_policy=p1 -- 8 为用户（主体）设置访问策略 CREATE USER u1 PASSWORD \u0026#39;u1.pass\u0026#39; ACCESS POLICY p1 WRITE LABEL laba,labb READ LABEL laba,labb; -- 9 查看用户（主体）设置访问策略 SELECT * FROM pg_authid; rolname | rolaccpol | rolacclab --------+-----------+--------------------- u1 | p1 | lab1:lab2,lab1:lab2 场景五：修改访问控制策略 -- 1 创建访问策略 CREATE ACCESS POLICY p1 LEVLE l1=10, l2=20, l3=30 MARK ma, mb LABEL lab1=l1, lab2=l2, laba1=l1:ma, labb1=l1:mb; -- 2. 为表（客体）设置访问策略 CREATE TABLE t1 (c1 INT, c2 TEXT) WITH (access_policy = p1); INSERT INTO t1 VALUES(1,\u0026#39;lab1\u0026#39;); -- 3. 为用户（主体）设置访问策略 CREATE USER u1 PASSWORD \u0026#39;u1.pass\u0026#39; ACCESS POLICY p1 WRITE LABEL lab1,lab2 READ LABEL lab1,lab2; -- 3 新增 LEVEL (1次只允许新增、修改、删除单个LEVEL、MARK、LABEL) ALTER ACCESS POLICY p1 ADD LEVLE l4=40; -- 4 修改 LEVEL ALTER ACCESS POLICY p1 ALTER LEVLE l1=15; -- 5 删除 LEVEL ALTER ACCESS POLICY p1 DROP LEVLE l3; ALTER ACCESS POLICY p1 DROP LEVLE l1 CASCADE; -- 预期：同时删除lab1。如果不带CASCADE，由于lab1依赖l1，会删除失败 -- 本示例场景中，以前，u1使用了lab1，现在，u1执行SELECT时，不能用访问控制策略了，INSERT时，使用lab2。 -- 5 新增 MARK ALTER ACCESS POLICY p1 ADD MARK mc,md; -- 6 删除 MARK ALTER ACCESS POLICY p1 DROP MARK mc; -- 7 新增 LABEL ALTER ACCESS POLICY p1 ADD LABEL lab3=l3; -- 8 修改 LABEL ALTER ACCESS POLICY p1 ALTER LABEL lab1=l2; -- 9 删除 LABEL ALTER ACCESS POLICY p1 DROP LABEL lab1; -- 在表中，存储的是label的值，即level与mark，即使删除label，仍然可以正常比较levle与mark 场景六：删除访问策略 扩展场景一：explain 扩展场景二：index_scan 扩展场景三：subquery 扩展场景六：sublink 扩展场景四：join 扩展场景五：view 扩展场景六：copy 扩展场景七：vb_dump 异常场景一：边界场景 -- 1 LEVEL 超过最大值 100 CREATE ACCESS POLICY p1 LEVLE l1=101; -- 2 LEVEL 数量超过限制 100个 CREATE ACCESS POLICY p1 LEVLE l1=1, l2=2, [此处省略98个], l101=101; -- 3 MARK 数量超过限制 100个 CREATE ACCESS POLICY p1 MARK m1, m2, [此处省略98个], m101; -- 3 LABEL 数量超过限制 100个 -- 4 ... 异常场景二：逻辑错误 -- 1 不存在的 LEVEL 和 MARK CREATE ACCESS POLICY p1 LEVLE l1=1 MARK ma LABEL lab2=l2, labb=mb; -- 2 重复的 LEVLE, MARK, LABEL CREATE ACCESS POLICY p1 LEVLE l1=1,l1=2,l2=1 -- 名称不能重复，取值可以重复 MARK ma,ma LABEL lab1=l1,lab1=l2; -- 3 不存在的策略 CREATE USER u1 .. ACCESS POLICY p_not_exist ..; CREATE TABLE t1 .. SECURED BY (access_policy=p_not_exist); -- 4 重复的策略 CREATE USER u1 .. ACCESS POLICY p1 ACCESS POLICY p2; CREATE TABLE t1 .. SECURED BY (access_policy=p1, access_policy=p2); -- 5 .. 2.2.2 配置参数和文件 新增GUC参数write_label\n会话级，默认为空，控制用户向表中写数据时，为数据赋予的标签 新增GUC参数read_label\n会话级，默认为空，控制用户从表中读数据时，使用的标签 2.2.3 数据相关性 无\n2.3 接口信息 新增SQL语法：ACCESS POLICY\nCREATE ACCESS POLICY $policy_name [LEVEL $level_name=$level_number [, $level_name=$level_number ...]] [MARK $mark_name [, $mark_name ...]] LABEL $label_name={$level_name | $mark_name | $level_name:$mark_name [, ...]} ALTER ACCESS POLICY $policy_name [ADD LEVEL $level_name=$level_number [, $level_name=$level_number ...]] [ALTER LEVEL $level_name=$level_number [, $level_name=$level_number ...]] [DROP LEVEL $level_name [, $level_name ...]] [ADD MARK ..] [ALTER MARK ..] [DROP MARK ..] [ADD LABEL ..] [ALTER LABEL ..] [DROP LABEL ..] DROP ACCESS POLICY [IF EXISTS] $policy_name [, $policy_name]; 扩展SQL语法：CREATE/ATLER USER\nCREATE/ALTER USER $user_name [ACCESS POLICY $policy_name WRITE $label_list READ $label_list] 扩展SQL语法：CREATE/ALTER TABLE\nCREATE TABLE $table_name .. WITH (access_policy = $policy_name); ALTER TABLE $table_name .. WITH (access_policy = none); 新增会话级GUC参数write_label\n新增会话级GUC参数read_label\n新增系统表vb_access_policy\n新增系统表vb_access_level\n新增系统表vb_access_mark\n新增系统表vb_access_label\n扩展系统表pg_authid：新增2列rolaccpol，rolacclab\n新增系统函数has_mac_permission(uint64, uint64)\n2.4 正反向行为 2.4.1 生效说明 直接通过SQL语法，可创建、设置访问策略。并通过查看系统表，判断是否操作成功，相关系统表包括：vb_access_policy、vb_access_level、vb_access_mark、vb_access_label、pg_class、pg_authid\nSELECT、UPDATE、DELETE表时，判断查询结果、操作结果，判断访问控制是否生效。\n2.4.2 提示信息 2.4.3 约束和依赖 为表设置访问策略：当前版本，只支持在创建表阶段，设置访问策略，不支持为已存在的表设置访问策略。 修改表的访问策略：只支持取消表的访问策略，不支持修改表的访问策略 2.5 安全性 2.5.1 权限控制 强制访问控制，与自主访问控制、行级访问控制共存，即当主体访问客体时，同时生效。\n2.5.2 审计 审计新增的DDL语法：CREATE/ALTER/DROP ACCESS POLICY。\n2.6 影响范围 2.6.1 对已有UDT,UDF, ECPG的影响 无\n2.6.2 对系统函数的影响 无\n2.6.3 对系统CATALOG的影响 新增vb_access_policy 新增vb_access_level 新增vb_access_mark 新增vb_access_label 扩展pg_authid：新增2列rolaccpol，rolacclab 2.6.4 对xlog日志格式、数据格式的影响 无\n2.6.5 与其他功能交互时的行为表现 与自主访问控制、行级访问控制交互：三者同时生效，互不影响\n2.6.6 版本兼容性 本版本第1次支持，新创建表时，支持设置访问策略，不支持为存量表设置访问策略。\n2.6.7 用户行为变更 新增SQL语法：ACCESS POLICY 扩展SQL语法：CREATE/ATLER USER 扩展SQL语法：CREATE/ALTER TABLE 新增会话级GUC参数write_label 新增会话级GUC参数read_label 新增系统表vb_access_policy 新增系统表vb_access_level 新增系统表vb_access_mark 新增系统表vb_access_label 扩展系统表pg_authid：新增2列rolaccpol，rolacclab 2.7 指标相关 2.7.1 关键资源指标 CPU：\n内存：\n外存：\n2.7.2 系统性指标 2.7.3 性能指标 2.8 测试建议 2.8 其他说明 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/14-requirement-mac/","summary":"\u003ch1 id=\"1-简介\"\u003e1 简介\u003c/h1\u003e\n\u003ch2 id=\"11-目的\"\u003e1.1 目的\u003c/h2\u003e\n\u003cp\u003e本文主要包括以下关键内容：\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e介绍访问控制的基本概念\u003c/li\u003e\n\u003cli\u003e调研其他厂商实现强制控制的方式\u003c/li\u003e\n\u003cli\u003e设计Vastbase强制访问控制特性，介绍如何使用强制访问特性\u003c/li\u003e\n\u003c/ol\u003e\n\u003ch2 id=\"12-适用范围\"\u003e1.2 适用范围\u003c/h2\u003e\n\u003cp\u003eVastbase V5版本。\u003c/p\u003e\n\u003ch2 id=\"13-术语定义首字母缩写词和缩略语\"\u003e1.3 术语定义、首字母缩写词和缩略语\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eMAC：Mandatory Access Control，强制访问控制，主体访问客体时，基于主体、客体属性，强制控制访问权限。\u003c/li\u003e\n\u003cli\u003eDAC：Discretionary Access Control，自主访问控制，数据拥有者可自行设置访问权限。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"14-参考资料\"\u003e1.4 参考资料\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eoracle 强制访问控制（标签访问控制 RLS）：\u003ca href=\"https://docs.oracle.com/en/database/oracle/oracle-database/26/olsag/part1.html#GUID-C20C62AE-2A30-45F9-AEEA-52A0D3286FBA\"\u003ehttps://docs.oracle.com/en/database/oracle/oracle-database/26/olsag/part1.html#GUID-C20C62AE-2A30-45F9-AEEA-52A0D3286FBA\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eoceanbase 强制访问控制（兼容oracle）：\u003ca href=\"https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004475944\"\u003ehttps://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000004475944\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003ekingbase 强制访问控制：\u003ca href=\"https://bbs.kingbase.com.cn/kingbase-doc/v8.6.7.24/safety/safety-guide/label-and-mac.html\"\u003ehttps://bbs.kingbase.com.cn/kingbase-doc/v8.6.7.24/safety/safety-guide/label-and-mac.html\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003edm 强制访问控制：\u003ca href=\"https://eco.dameng.com/document/dm/zh-cn/pm/mandatory-access-control.html\"\u003ehttps://eco.dameng.com/document/dm/zh-cn/pm/mandatory-access-control.html\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eGB/T-20009-数据库管理系统安全评估准则：\u003ca href=\"https://drive.weixin.qq.com/s?k=AHUAfwdSAA82aDcvvD\"\u003ehttps://drive.weixin.qq.com/s?k=AHUAfwdSAA82aDcvvD\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003epostgresql 行级访问控制 RLS：\u003ca href=\"https://www.postgresql.org/docs/current/ddl-rowsecurity.html\"\u003ehttps://www.postgresql.org/docs/current/ddl-rowsecurity.html\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-强制访问控制\"\u003e2 强制访问控制\u003c/h1\u003e\n\u003ch2 id=\"21-功能简述\"\u003e2.1 功能简述\u003c/h2\u003e\n\u003ch3 id=\"一基本概念\"\u003e一、基本概念\u003c/h3\u003e\n\u003cp\u003e\u003cstrong\u003e访问控制\u003c/strong\u003e的定义：对主体访问客体的行为，系统按照安全策略进行限制与管理的安全机制。\u003cbr\u003e\n按安全策略分类，可将访问控制分为很多类，其中，常见的策略有：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e自主访问控制DAC：客体的拥有者，可自行向其他主体赋予访问权限。\u003c/li\u003e\n\u003cli\u003e强制访问控制MAC：系统为主体、客体分配安全标签，通过主体、客体的安全标签控制访问权限，很多情况下，即使客体的拥有者也无法向其他主体赋予访问权限。\u003c/li\u003e\n\u003cli\u003e角色访问控制RBAC：不在本文讨论范围。\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e在数据库领域，主体通常指数据库用户，客体通常指数据库对象，例如DATABASE、SCHEMA、TABLE、COLUMN、ROW、FUNCTION等。\u003cbr\u003e\n自主访问控制比较成熟，几乎所有关系数据库，都提供自主访问控制特性，例如，TABLE（客体）的属主（主体），可通过\u003ccode\u003eGRANT .. TO ..\u003c/code\u003e等语法，为其他用户（主体）赋予权限。\u003cbr\u003e\n强制访问控制理论比较成熟，但是，除oracle支持强制访问控制，以及oceanbase等几款产品兼容oracle强制访问控制之外，大部分关系数据库不支持强制访问控制。\u003c/p\u003e\n\u003cp\u003e实现强制访问控制时，通常将主体、客体的安全标签，简化为安全等级，当主体访问客体时，比较主体、客体等级高低，以判断访问权限。在机密性场景，遵循不上读、不下写原则。在完整性场景，遵循不下读、不上写原则。\u003c/p\u003e\n\u003cp\u003e本需求将从0设计强制访问控制特性，在保障功能、性能、易用性、可用性、可维护性、可扩展性等的前提下，让特性达到商用标准。\u003c/p\u003e\n\u003ch3 id=\"二竞品分析\"\u003e二、竞品分析\u003c/h3\u003e\n\u003cp\u003eoracle支持强制访问控制，客体是ROW，即行级强制访问控制。oceanbase、kingbase、dm的访问控制，与oracle一致。sql server、postgresql等其他产品不支持强制访问控制。\u003cbr\u003e\noracle强制访问控制使用示例如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e-- 1 定义策略\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSA_SYSDBA\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_POLICY\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epolicy_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;p1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003ecolumn_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;lab_col1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 2 定义级别\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSA_COMPONENTS\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_LEVEL\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epolicy_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;p1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003elevel_num\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eshort_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;x1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003elong_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;x1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSA_COMPONENTS\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_LEVEL\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;p1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e20\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;x2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;x2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSA_COMPONENTS\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_LEVEL\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;p1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e30\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;x3\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;x3\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 3 定义组件\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSA_COMPONENTS\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_LEVEL\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epolicy_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;p1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ecomp_num\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e100\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eshort_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;sec\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003elong_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;security\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSA_COMPONENTS\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_LEVEL\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;p1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e200\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;stg\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;storage\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 4 创建标签\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSA_SYSDBA\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_LABEL\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epolicy_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;p1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003elabel_tag\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;sec_normal\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003elabel_value\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;x1:security\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edata_label\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTRUE\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSA_SYSDBA\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eCREATE_LABEL\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;p1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;sec_leader\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;x3:security\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003efalse\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 5 为主体设置属性\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSA_USER_ADMIN\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eSET_LEVELS\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epolicy_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;p1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003euser_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;user1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emax_level\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;x2\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003emin_level\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;x1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edefault_level\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;x1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erow_level\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;x1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSA_USER_ADMIN\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eSET_COMPARTMENTS\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epolicy_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;p1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003euser_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;user1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eread_comps\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;sec\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003ewrite_comps\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;sec\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003edefault_comps\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;sec\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003erow_comps\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;sec\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 6 为客体设置属性\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eCREATE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eTABLE\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"nb\"\u003eINT\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"n\"\u003eSA_USER_ADMIN\u003c/span\u003e\u003cspan class=\"p\"\u003e.\u003c/span\u003e\u003cspan class=\"n\"\u003eAPPLY_TABLE_POLICY\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003epolicy_name\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;p1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eshema_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;s1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003etable_name\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;t1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etable_options\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;READ_CONTROL, WRITE_CONTROL, CHECK_CONTROL\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003elabel_function\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"o\"\u003e=\u0026gt;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;f_create_t1_label(level, comp)\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"c1\"\u003e-- 7 插入数据（主动定义标签）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eINSERT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003eINTO\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003et1\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ec1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003elab_col1\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e\u003c/span\u003e\u003cspan class=\"k\"\u003eVALUES\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"mi\"\u003e1\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eCHAR_TO_LABEL\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;p1\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;x1:sec\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e));\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"三实现思路\"\u003e三、实现思路\u003c/h3\u003e\n\u003cp\u003e在数据库领域，除oracle外，没有其他可借鉴的方案。oracle的设计，太复杂，易用性太低。\u003cbr\u003e\n本需求将参考oracle的思想，简化oracle设计。\u003c/p\u003e","title":"海量 mac 需求"},{"content":"1 逻辑复制性能优化 1.1 功能简述 原理：\n假设，发布端执行INSERT INTO t1 VALUES(1,'data1')，更改1行数据，产生1条wal日志。逻辑复制功能将读取这条wal，解码并生成1条message，将message发送至订阅端。订阅端应用这条message，等价于重新执行INSERT INTO t1 VALUES(1,'data1')。 问题：\n308.1 psu1以及之前版本，逻辑复制性能较低。以tpcc场景为例，40w tmpc时，发布端产生wal日志速度约100m/s，订阅端的复制速度约10+m/s。 客户：\n滚动升级场景中，备机停机升级，主机持续执行业务，备机升级后使用逻辑复制追赶主机数据。长存客户场景，主机产生wal日志速度约40-50m/s，旧版本逻辑复制速度10+m/s，由于逻辑复制速度太慢，备机无法追赶主机，最终导致升级失败。 优化\n本需求设计与实现并行逻辑复制机制，大幅提高逻辑复制速度，在上述场景中，订阅端速度可达到70-90m/s。并行逻辑复制分为3个关键子机制： 发布端多线程并行解码 发布端与订阅端流复制传输协议 订阅端多线程并行应用 1.2 实现方案 本章分3个章节，分别介绍3个关键子机制。\n1.2.1 发布端并行解码机制 在旧版本中，发布端采用串行解码机制，只有1个walsender线程，串行执行：1次读取1条wal日志，解码1条wal生成1条message，缓存或发送message。\n旧版本代码中，发布端有实现并行解码的代码，但是，无法直接使用，订阅端只能是工具，不能是数据库实例，且存在大量问题。本需求基于旧版本并行解码，实现权限的并行解码机制。\n并行解码机制，将启动多个线程，包括1个reader、多个decoder、1个walsender，它们的功能如下：\nreader：1次读取1条wal日志，将wal发送给decoder decoder：1次接收1条reader发送的wal，解码生成message，将message发送给walsender walsender：1次接收1条decoder发送的message，将message发送给订阅端 线程架构图如下：\nlsn 1-10 d1 1 4 collect 阻塞 1 d2 2 5 2 d3 3 6 3 1.2.2 发布端与订阅端流复制协议 一、握手阶段 订阅端与发布端建立连接时，订阅端会根据CRETE SUBSCRIPTION语法设置的参数，生成连接命令，根据连接命令，发布端和订阅端决定采用哪种通信协议，究竟是采用事务复制协议（旧版本）还是流复制协议（新版本）。\n事务复制协议（旧版本） 订阅端发送的连接命令如下：\nSTART_REPLICATION SLOT \u0026#34;$slot_name\u0026#34; LOGICAL $start_lsn (proto_version \u0026#39;3\u0026#39;, publication_names \u0026#39;\u0026#34;$publication_name\u0026#34;\u0026#39;) 流复制协议（新版本） 如果CRETE SUBSCRIPTION时，指定worker_number\u0026gt;1，即启用并行逻辑复制机制，将使用新的连接命令，订阅端发送的连接命令如下：\nSTART_REPLICATION SLOT \u0026#34;$slot_name\u0026#34; LOGICAL $start_lsn (proto_version \u0026#39;3\u0026#39;, publication_names \u0026#39;\u0026#34;$publication_name\u0026#34;\u0026#39;， streaming \u0026#39;extreme\u0026#39;, parallel-decode-num \u0026#39;20\u0026#39;, max-recordbuffer-in-memory \u0026#39;100\u0026#39;, max-txn-in-memory \u0026#39;100\u0026#39;) 上述命令中新增了多个参数：\n新增streaming参数：表示使用 流复制协议 新增parallel-decode-num、max-recordbuffer-in-memory、max-txn-in-memory：表示让发布端使用 并行解码机制，流复制协议吞吐率高，必须采用并行解码机制 当然，如果CRETE SUBSCRIPTION时不主动指定worker_number\u0026gt;1，则仍然使用旧版本的连接命令与协议，本需求保留并隔离了旧版本的协议，与新版本互不影响。\n二、复制阶段 为方便理解，此处以一个实际的例子，介绍旧版本事务复制协议与新版本流复制协议的复制原理，并指出二者的区别。\n假如，发布端执行2个事务，事务执行顺序如下：\n时间 事务1 事务2 1 begin - 2 insert 1a - 3 - begin 4 - insert 2a 5 update 1b - 6 commit xid=1 - 7 - update 2b 8 - commit xid=2 事务复制协议（旧版本） 针对上述示例场景，逻辑复制处理流程如下：（先产生wal，再解码，中间有时间差，为方便理解，此处假设产生后立即解码）\n时间[2,4,5]：解码事务1和2的wal（begin不处理），不是commit对应的wal，都直接缓存 时间[6]：解码到commit xid=1，发送所有属于事务1的缓存。 一次性发送4条message，message类型分别为[B(自动生成), I, U, C]，分别对应时间[2,5,6]产生的日志。\n4条message统一格式如下：\n+-----+-------------------------------+=========+===================+ | \u0026#39;w\u0026#39; | dataStart | walEnd | sendTime | msgType | msgBody | +-----+-------------------------------+=========+===================+ |--------实际的message内容-----| B/I/U/C 其中，msgType分别是[B, I, U, C]，msgBody中是解码后的wal日志。’B’和’C’的message中，携带了事务的xid。’I’和’U’的message中，携带了数据。\n时间[7]：解码事务2的wal，不是commit对应的wal，直接缓存 时间[8]：解码到commit xid=2，发送所有属于事务2的缓存。 一次性发送4条message，类型分别为[B(自动生成), I, U, C]，分别对应时间[4,7,8]产生的日志。 格式同上 流复制协议（新版本） 针对上述示例场景，逻辑复制处理流程如下：\n时间[2，4，5，6，7，8]：解码事务1和2的wal（begin不处理），并直接发送 分别发送6条message，message类型全是’F’，’F’是新增的message类型，表示流式message。\n6条message统一格式如下：\n+-----+-------------------------------+^^^^^^^^^^^^^^^^^^^^^^^^^+=========+===================+ | \u0026#39;w\u0026#39; | dataStart | walEnd | sendTime | \u0026#39;F\u0026#39; | xid | msgLen | msgType | msgBody | +-----+-------------------------------+^^^^^^^^^^^^^^^^^^^^^^^^^+=========+===================+ |----------新增部分--------|-----旧版本的message内容------| B/I/U/C 在’F’ message中，新增了事务xid，后半段message与事务复制协议保持一致。\n使用流复制协议，有2个优点：\n提高吞吐：发布端启用并行解码，相同场景下，约40w tmpc时，事务复制协议吞吐为 80+m/s，流复制协议吞吐为 130+m/s 事务并行：从订阅端的角度看，在事务复制协议中，订阅端串行接收事务，无法判断事务2中，哪些操作在事务1commit之后的，无法实现事务并行。在流复制协议中，订阅端接收message的顺序，与发布端的wal日志顺序一致。属于事务2的操作，且在事务1commit之前的，可与事务1并行执行。 1.2.3 订阅端并行应用机制 整体架构 在旧版本中，订阅端采用串行应用机制，只有1个apply-worker线程，串行执行：接收message，应用message。\n本需求设计并行应用机制机制，订阅端启用多个线程，包括1个apply-leader和多个apply-worker，它们的功能如下：\napply-leader：使用流复制协议，接收来自发布端的message，接收顺序与发布端wal日志顺序一致。并且，维护各个事务的状态等信息，统一调度所有apply-worker，将message发送给apply-worker。 apply-worker：接收由apply-leader分发的message，并直接应用。多个apply-worker之间可并行应用，即事务并行应用。1个apply-worker，只处理1个事务的message，只有该事务commit/abort后，才处理新事务的message。 线程架构图如下：\n为方便理解，以一个简单示例，介绍并行的核心思路，例如，在发布端，以下2个事务同时执行：\n-- 前置条件 create table t(c1 text); ------------------------------------------------------------------------- -- 事务1 -- 事务2 ------------------------------------------------------------------------- begin; -- 1 (先开始) insert into t values(\u0026#39;1\u0026#39;); begin; insert into t values(\u0026#39;2\u0026#39;); insert into values (\u0026#39;3\u0026#39;); commit; insert into values (\u0026#39;4\u0026#39;) commit; 并行apply的核心思路如下：\nleader worker-1 worker-2 +-------------------------------+-------------------------------+---------------------------------------- 1. recv [xid=1, insert \u0026#39;1\u0026#39;] 2. send ----------------------\u0026gt; | 3. recv [xid=2, insert \u0026#39;2\u0026#39;] | 1. apply [xid=1, insert \u0026#39;1\u0026#39;] 4. send ------------------------------------------------------\u0026gt; | 5. recv [xid=1, insert \u0026#39;3\u0026#39;] | 1. apply [xid=2, insert \u0026#39;2\u0026#39;] 6. send ----------------------\u0026gt; | 7. recv [xid=2, insert \u0026#39;4\u0026#39;] | 2. apply [xid=1, insert \u0026#39;3\u0026#39;] 8. send ------------------------------------------------------\u0026gt; | 9. recv [xid=1, commit] | 2. apply [xid=2, insert \u0026#39;2\u0026#39;] 10. send ----------------------\u0026gt; | 11. recv [xid=2, comit ] | 3. apply [xid=1, commit] 12. send -----------------------------------------------------\u0026gt; | | 3. apply [xid=2, commit] 但是，在并行apply的过程中，会遇到各类问题，本文分别讨论各类问题的处理方式。\n一、数据一致性 在发布端，如果有多个事务同时执行，在订阅端，将启动多个apply-worker线程，每个线程对1个事务apply，达到并行apply的效果。\n但是，订阅端需确保事务apply顺序与发布端一致，否则，会造成发布端、订阅端数据不一致。例如，在发布端，以下2个事务同时执行：\n-- 前置条件 create table t(c1 text); ------------------------------------------------------------------------- -- @事务x1 @-- 事务2 ------------------------------------------------------------------------- begin; -- 1 (先开始) insert into t values(\u0026#39;1\u0026#39;); -- 2 begin; -- 3 insert into t values(\u0026#39;2\u0026#39;); -- 4 commit; -- 5 update t set c1 = \u0026#39;3\u0026#39; where c1 = \u0026#39;1\u0026#39;; -- 6 (读已提交) commit; -- 7 insert \u0026#39;1\u0026#39;; begin; -- 1 (先开始) insert into t values(\u0026#39;1\u0026#39;); -- 2 begin; -- 3 insert into t values(\u0026#39;2\u0026#39;); -- 4 update t set c1 = \u0026#39;3\u0026#39; where c1 = \u0026#39;1\u0026#39;; -- 5 (读已提交) commit; -- 6 commit; -- 7 todo：5发给worker-2，但是5没执行，worker-1先执行6（1非主键，旧版本也有问题）\ninsert \u0026#39;1\u0026#39;; begin; -- 1 (先开始) insert into t values(\u0026#39;1\u0026#39;); -- 2 begin; -- 3 insert into t values(\u0026#39;2\u0026#39;); -- 4 update t set c1 = \u0026#39;3\u0026#39; where c1 = \u0026#39;1\u0026#39;; -- 5 (读已提交) commit; -- 6 commit; -- 7 示例中，第[2, 5, 6]步的insert, commit, update存在依赖关系，假如，在订阅端，第6步比第5步先apply，则update读不到未commit得数据，update执行结果与发布端不一致。\n为解决此类问题，在订阅端，leader需通过调度机制，确保先apply上述示例中第5步的commit，再apply第6步的commit。\nleader worker-1 worker-2 +-------------------------------+-------------------------------+---------------------------------------- 1. recv [xid=1, insert \u0026#39;1\u0026#39;] 2. send ----------------------\u0026gt; | | 3. apply [xid=1, insert \u0026#39;1\u0026#39;] 4. recv [xid=2, insert \u0026#39;2\u0026#39;] 5. send ------------------------------------------------------\u0026gt; | | 6. apply [xid=2, insert \u0026#39;2\u0026#39;] 7. recv [xid=1, commit] 8. send ----------------------\u0026gt; | 9. wait commit # 遇到commit，则阻塞等待，直到worker成功apply这条commit | 10. apply [xid=1, commit] \u0026lt;-------------------------- | 11. send commit ok 12. recv [xid=2, update \u0026#39;1\u0026#39;] 13. send -----------------------------------------------------\u0026gt; | | 14. apply [xid=2, update \u0026#39;1\u0026#39;] 15. recv [xid=2, commit] 16. send -----------------------------------------------------\u0026gt; | 17. wait commit | 18. apply [xid=2, commit] 二、并行调度 在流复制协议中，每条msg都携带xid。apply-leader接收到msg时，需根据xid，找到负责该事务的worker。在该过程中，leader需解决以下问题：\n事务缓存：比如worker数量较少，事务较多，无法为每个事务都分配worker，多余事务的msg将被缓存 线程调度：1个worker处理1个事务，当这个事务处理结束，leader会优先给worker分配缓存中的事务 线程预留：如果1个事务未分配到worker，所有该事务的msg被缓存，突然，收到了该事务的commit。为避免该问题，需要始终预留1个worker，用于处理缓存中的事务突然commit的情况。 leader的调度流程如下：\nleader worker +-------------------------------------------------------------------+------------------------- 1. 初始化hash表，用于记录所有事务的回放状态 2. 始终保留1个worker | 1. 阻塞等待leader发送msg 3. 从发布端接收msg 4. 从msg获取xid 5. 判断消息类型： if \u0026#39;I\u0026#39; or \u0026#39;U\u0026#39; or \u0026#39;D\u0026#39;: 从hash表查找事务状态 hash.find(xid) if 未找到xid：（新事务） 申请1个空闲worker if 申请成功： 发送msg给worker worker.send(xid, msg) -----\u0026gt; (该worker将被xid对应的事务独占，直至xid对应的事务commit/rollback) | 2. 持续接收msg | 3. 应用msg 记录事务信息 hash.insert(xid, worker-id) elif 申请失败： 暂时缓存msg 记录事务信息 hash.insert(xid, cache-id) elif 找到xid：（已开始的事务） if [xid, worker-id]：(已有worker处理该事务) 发送msg给worker worker.send(xid, msg) -----------\u0026gt; elif [xid, cache-id]： 继续缓存msg cache.put(xid, msg) elif \u0026#39;C\u0026#39;: 从hash表查找事务状态 hash.find(xid) if [xid, worker-id]： 发送msg给worker worker.send(xid, msg) ----------\u0026gt; 阻塞等待worker提交事务 worker.wait() \u0026lt;---------- | 4. 如果是\u0026#39;C\u0026#39;msg，应用成功后，向leader反馈 让worker从缓存中读取1个事务的msg hash.next() hash.update(xid, cache-id -\u0026gt; worker-id) elif [xid, cache-id]： 让保留的worker从缓存中读取本事务的msg worker.read(xid, worker-id) elif \u0026#39;A\u0026#39;：（abort） 和\u0026#39;C\u0026#39;处理类似 三、流量控制 发布端walsender发送msg，订阅端leader接收msg，worker消耗msg，三者速度不一致，需进行流量控制。\nwalsender速度 \u0026gt; leader速度：walsend通过系统调用send()发送msg，msg会占满网络缓存区，导致send()阻塞在内核态。 leader速度 \u0026gt; worker速度：leader收到多余的msg后 msg是新事务：无空闲worker，leader缓存msg，缓存达到阈值时，leader暂时停止接收msg，直到有空闲worker消耗缓存。leader最多可缓存1000个事务，1个事务的msg，如果超过1000条，则物化到临时文件中。 msg属于worker中的事务：leader与worker的通信队列已满，leader暂时停止发送msg，直到worker消耗通信队列中的msg。通信队列最多可缓存1000个msg。 leader速度 \u0026lt; worker速度：worker未收到新msg，通过信号量阻塞等待。 四、续点重传 在复制过程中，需实时记录复制进度，当发生重启等情况，重新复制时，需确保不会apply重复数据，或者漏apply数据。断点主要由订阅端维护。\n假如，在发布端，3个事务同时执行：\n+-----+-------------+-------------+-------------+ | lsn | xid=1 | xid=2 | xid=3 | +-----+-------------+-------------+-------------+ | 1 | insert \u0026#39;11\u0026#39; | | | | 2 | | insert \u0026#39;21\u0026#39; | | | 3 | | | insert \u0026#39;31\u0026#39; | | 4 | commit | | | | 5 | | insert \u0026#39;22\u0026#39; | | | 6 | | commit | | | 7 | | | insert \u0026#39;32\u0026#39; | | 8 | | | commit | +-----+-------------+-------------+-------------+ todo: 发布端并发高：多测断点续传\nrestart_lsn: commit=50 worker-1 worker-2 worker-3 ----------------+--------------+----------- insert lsn=80 commit insert insert lsn=99 commit lsn=100 针对上述示例，假设订阅端apply lsn=7之后，发生故障：\nleader worker worker worker +---------------------------------------------+---------------------------------+---------------------------------+-------------------- | 1. recv [lsn=1, xid=1, insert \u0026#39;11\u0026#39;] ------\u0026gt; | 1. apply [lsn=1] lsn表示：在发布端，本条msg对应的wal的lsn | 2. recv [lsn=2, xid=2, insert \u0026#39;21\u0026#39;] ----------------------------------------\u0026gt; | 2. apply [lsn=2] | 3. recv [lsn=3, xid=3, insert \u0026#39;31\u0026#39;] --------------------------------------------------------------------------\u0026gt; | 3. apply [lsn=3] | 4. recv [lsn=4, xid=1, commit ] ------\u0026gt; | 5. apply [lsn=4, commit] | 6. write wal [commit, lsn=4] 所有commit对应的wal中，都会记录在发布端本条commit对应的lsn，这个lsn，就是断点，即只有commit的wal记录断点 | 7. recv [lsn=5, xid=2, insert \u0026#39;21\u0026#39;] ----------------------------------------\u0026gt; | 7. apply [lsn=5] ------- 8. checkpoint (上一次commit，对应的lsn=4) | 9. recv [lsn=6, xid=2, commit] ----------------------------------------\u0026gt; | 10. apply [lsn=6, commit] | 11. write wal [commit, lsn=6] | 12. recv [lsn=7, xid=3, insert \u0026#39;31\u0026#39;] -------------------------------------------------------------------------\u0026gt; | 12. apply [lsn=7] ------- 13. 发生故障，重启 # 重启 startup +--------------------------------------------------------+ | 1. read checkpoint [lsn=4], set breakpoint: [lsn=4] | 2. redo [commit, lsn=6], update breakpoint: [lsn=6] | 3. redo finish, breakpoint: lsn=6 # 重启后，订阅端向发布端发送断点 leader worker worker worker +---------------------------------------------+---------------------------------+---------------------------------+-------------------- | 1. start replication [lsn=6] | 2. recv [lsn=3, xid=3, insert \u0026#39;31\u0026#39;] --------------------------------------------------------------------------\u0026gt; | 2. apply [lsn=3] # 在断点前，所有未commit事务的msg，都会重发 | 3. recv [lsn=7, xid=3, insert \u0026#39;31\u0026#39;] --------------------------------------------------------------------------\u0026gt; | 3. apply [lsn=7] # 在断点后，则按序发送所有msg，开始正常的逻辑复制 | 4. recv [lsn=8, xid=3, commit] --------------------------------------------------------------------------\u0026gt; | 4. apply [lsn=8， commit] | 5. .... # 发布端，接收断点后，过滤无需重发的wal walsend +------------------------------------------- | 1. recv breakpoint [lsn=6] | 2. read [lsn=1, xid=1, insert \u0026#39;11\u0026#39;] | 3. cache {xid=1, lsn=1} | 4. read [lsn=2, xid=2, insert \u0026#39;21\u0026#39;] | 5. cache {xid=2, lsn=2} | 6. read [lsn=3, xid=2, insert \u0026#39;31\u0026#39;] | 7. cache {xid=3, lsn=3} | 8. read [lsn=4, xid=1, commit] | 9. commit lsn = 3 \u0026lt; breakpoint = 6, remove cache {xid=1, ..} | 10. read [lsn=5, xid=2, insert \u0026#39;21\u0026#39;] | 11. cache {xid=2, lsn=2, lsn=5} | 12. read [lsn=6, xid=2, commit] | 13. commit lsn = breakpoint = 6, remove cache {xid=2, ..} | 14. send all cache {xid=3, lsn=3} ----------------\u0026gt; # 处理至断点，一次性发送所有缓存，缓存中只剩下了未提交的事务 | 15. read [lsn=7, xid=3, insert \u0026#39;32\u0026#39;] | 16. send [lsn=7] -------\u0026gt; # 断点之后，读1条，发1条，不再需要缓存，开始正常逻辑复制 | 17. .... 1.3 接口说明 用户需调大3个guc的取值：max_replication_slots，max_background_workers，max_logical_replication_workers。 CREATE/ALTER SUBSCRIPTION语法：WITH子句中，新增worker_number参数，控制并行应用机制的并行度。 pg_subscription系统表：新增1列subwkrnum，int32类型 1.4 内存管理 无\n1.5 安全 对外接口中，只在已有CREATE/ALTER SUBSCRIPTION语法中新增参数，不涉及变更权限，无需重新适配审计。\n1.6 性能 之前，在优化发布端传输速度前，自测性能如下（实际性能应该高于一下数据，滚动升级场景，50并发，订阅端速度能稳定在80+m/s，峰值能到90-100m/s）：\n编号 tpcc并发数 tpmc (10min) tpmTotal 发布端速度 订阅端速度(2次抽样) 1 10 5.8w 12.9w 13.4 m/s 52.2 m/s 2 50 21.8w 48.6w 50.9 m/s {76.4, 77.3} m/s 3 100 33.3w 73.9w 77.5 m/s {74.0, 73.2} m/s 4 200 35.4w 78.7w 82.8 m/s {73.8, 70.7} m/s 5 300 36.3w 80.9w 84.9 m/s {66.4, 64.0} m/s 6 400 32.6w 72.6w 76.4 m/s {62.1, 60.8} m/s 测试环境：单机，kunpeng-920，128核，760G内存，tpcc 100 warehousee 发布端速度：tpcc运行10min，(结束lsn - 开始lsn) / 600s 订阅端速度：启动复制，抽样：(第130s的lsn - 第30s的lsn) / 100s，(第230s的lsn - 第130s的lsn) / 100s 1.7 专利 无\n1.8 升级管理 用户需调大3个guc的取值：max_replication_slots，max_background_workers，max_logical_replication_workers。 CREATE/ALTER SUBSCRIPTION语法中，需主动指定worker_number\u0026gt;0，才会启用并行逻辑解码，升级后逻辑复制默认行为不发生变化 pg_subscription系统表：新增1列subwkrnum，int32类型 1.9 其他说明 无\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/15-design-logical-replication/","summary":"\u003ch1 id=\"1-逻辑复制性能优化\"\u003e1 逻辑复制性能优化\u003c/h1\u003e\n\u003ch2 id=\"11-功能简述\"\u003e1.1 功能简述\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e原理：\u003cbr\u003e\n假设，发布端执行\u003ccode\u003eINSERT INTO t1 VALUES(1,'data1')\u003c/code\u003e，更改1行数据，产生1条wal日志。逻辑复制功能将读取这条wal，解码并生成1条message，将message发送至订阅端。订阅端应用这条message，等价于重新执行\u003ccode\u003eINSERT INTO t1 VALUES(1,'data1')\u003c/code\u003e。 \u003cimg alt=\"rep\" loading=\"lazy\" src=\"/images/ProjectDocs/15-design-logical-replication/rep.png\"\u003e\u003c/li\u003e\n\u003cli\u003e问题：\u003cbr\u003e\n308.1 psu1以及之前版本，逻辑复制性能较低。以tpcc场景为例，40w tmpc时，发布端产生wal日志速度约100m/s，订阅端的复制速度约10+m/s。\u003c/li\u003e\n\u003cli\u003e客户：\u003cbr\u003e\n滚动升级场景中，备机停机升级，主机持续执行业务，备机升级后使用逻辑复制追赶主机数据。长存客户场景，主机产生wal日志速度约40-50m/s，旧版本逻辑复制速度10+m/s，由于逻辑复制速度太慢，备机无法追赶主机，最终导致升级失败。\u003c/li\u003e\n\u003cli\u003e优化\u003cbr\u003e\n本需求设计与实现并行逻辑复制机制，大幅提高逻辑复制速度，在上述场景中，订阅端速度可达到70-90m/s。并行逻辑复制分为3个关键子机制：\n\u003col\u003e\n\u003cli\u003e发布端多线程并行解码\u003c/li\u003e\n\u003cli\u003e发布端与订阅端流复制传输协议\u003c/li\u003e\n\u003cli\u003e订阅端多线程并行应用\u003c/li\u003e\n\u003c/ol\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"12-实现方案\"\u003e1.2 实现方案\u003c/h2\u003e\n\u003cp\u003e本章分3个章节，分别介绍3个关键子机制。\u003c/p\u003e\n\u003ch3 id=\"121-发布端并行解码机制\"\u003e1.2.1 发布端并行解码机制\u003c/h3\u003e\n\u003cp\u003e在旧版本中，发布端采用串行解码机制，只有1个walsender线程，串行执行：1次读取1条wal日志，解码1条wal生成1条message，缓存或发送message。\u003c/p\u003e\n\u003cp\u003e旧版本代码中，发布端有实现并行解码的代码，但是，无法直接使用，订阅端只能是工具，不能是数据库实例，且存在大量问题。本需求基于旧版本并行解码，实现权限的并行解码机制。\u003c/p\u003e\n\u003cp\u003e并行解码机制，将启动多个线程，包括1个reader、多个decoder、1个walsender，它们的功能如下：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003ereader：1次读取1条wal日志，将wal发送给decoder\u003c/li\u003e\n\u003cli\u003edecoder：1次接收1条reader发送的wal，解码生成message，将message发送给walsender\u003c/li\u003e\n\u003cli\u003ewalsender：1次接收1条decoder发送的message，将message发送给订阅端\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e线程架构图如下：\u003c/p\u003e\n\u003cp\u003e\u003cimg alt=\"pa-pub\" loading=\"lazy\" src=\"/images/ProjectDocs/15-design-logical-replication/pa-pub.png\"\u003e\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003elsn 1-10\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        d1 \u003cspan class=\"m\"\u003e1\u003c/span\u003e \u003cspan class=\"m\"\u003e4\u003c/span\u003e  collect 阻塞 \u003cspan class=\"m\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        d2 \u003cspan class=\"m\"\u003e2\u003c/span\u003e \u003cspan class=\"m\"\u003e5\u003c/span\u003e               \u003cspan class=\"m\"\u003e2\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        d3 \u003cspan class=\"m\"\u003e3\u003c/span\u003e \u003cspan class=\"m\"\u003e6\u003c/span\u003e               \u003cspan class=\"m\"\u003e3\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch3 id=\"122-发布端与订阅端流复制协议\"\u003e1.2.2 发布端与订阅端流复制协议\u003c/h3\u003e\n\u003ch4 id=\"一握手阶段\"\u003e一、握手阶段\u003c/h4\u003e\n\u003cp\u003e订阅端与发布端建立连接时，订阅端会根据CRETE SUBSCRIPTION语法设置的参数，生成连接命令，根据连接命令，发布端和订阅端决定采用哪种通信协议，究竟是采用事务复制协议（旧版本）还是流复制协议（新版本）。\u003c/p\u003e\n\u003ch5 id=\"事务复制协议旧版本\"\u003e事务复制协议（旧版本）\u003c/h5\u003e\n\u003cp\u003e订阅端发送的连接命令如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eSTART_REPLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSLOT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;$slot_name\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eLOGICAL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003estart_lsn\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eproto_version\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;3\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epublication_names\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u0026#34;$publication_name\u0026#34;\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch5 id=\"流复制协议新版本\"\u003e流复制协议（新版本）\u003c/h5\u003e\n\u003cp\u003e如果CRETE SUBSCRIPTION时，指定worker_number\u0026gt;1，即启用并行逻辑复制机制，将使用新的连接命令，订阅端发送的连接命令如下：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"n\"\u003eSTART_REPLICATION\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eSLOT\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s2\"\u003e\u0026#34;$slot_name\u0026#34;\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eLOGICAL\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"err\"\u003e$\u003c/span\u003e\u003cspan class=\"n\"\u003estart_lsn\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"w\"\u003e    \u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eproto_version\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;3\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003epublication_names\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;\u0026#34;$publication_name\u0026#34;\u0026#39;\u003c/span\u003e\u003cspan class=\"err\"\u003e，\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003estreaming\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;extreme\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003eparallel\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003edecode\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003enum\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;20\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003emax\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003erecordbuffer\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ein\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ememory\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;100\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003emax\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003etxn\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"k\"\u003ein\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u003c/span\u003e\u003cspan class=\"n\"\u003ememory\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"s1\"\u003e\u0026#39;100\u0026#39;\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e上述命令中新增了多个参数：\u003c/p\u003e","title":"海量 15 设计 逻辑复制性能优化"},{"content":"1 简介 1.1 目的 逻辑复制是一种在多个数据库实例之间复制数据的功能，通常用于从一个数据库实例中，将针对指定表的insert、delete、update等写操作，复制到其他另一个数据库实例。在数据库术语中，统一称逻辑复制的发送方为发布端，称接收方为订阅端。Oracle、Postgresql、Vastbase等数据库产品，均提供逻辑复制功能。\n当前版本，逻辑复制性能较低。以tpcc场景为例，发布端40w tmpc时，产生wal日志速度约100+m/s，订阅端的复制速度约10+m/s。在滚动升级场景，主机和备机可能是不同的产品版本，主备复制数据时，不能使用物理复制，只能使用逻辑复制。在长存客户场景中，主机产生wal日志速度在50+m/s左右，备机使用逻辑复制，复制速度约10+m/s，备机将追赶不上主机进度，导致滚动升级失败。\n主a 备b 备c +-----------------------+---------------------------+----------------------------- |1 ==\u0026gt;执行业务 |2 开始滚动升级，暂停流复制 lag=400M |3 暂停流复制（物理复制） |4 创建逻辑复制槽 lsn1=1G |5 恢复流复制 |6 物理复制追赶，到逻辑复制槽 |6 开始单节点升级 |7 [升级] 停止进程 |8 [升级] 替换二进制等 |9 [升级] 启动进程 |10 单节点升级成功 |11 持续执行业务 lsn2=2G |12 创建订阅，启动逻辑复制，lsn1=1G |13 逻辑复制开始追赶（初始差距：lsn2-lsn1) |14 持续执行业务 lsn3=2.5G |15 逻辑复制持续追赶 lsn=1.6G |16 (可重置lag) |17 差距持续缩小（从lsn2-lsn1降低到lag） |18 发送停机命令 |19 停止业务 |20 差距持续缩小，从lag缩小至0 |21 停止进程成功 因此，需大幅提高逻辑复制速度，在长存客户场景中，逻辑复制速度至少需达到70+m/s。目前，发布端、订阅端均存在性能瓶颈，均需要优化。\n1.2 适用范围 G100 3.0.9 psu2及之后版本\n1.3 术语定义、首字母缩写词和缩略语 发布端：逻辑复制场景，发送数据方。 订阅端：逻辑复制场景，接收数据方。 1.4 参考资料 Vastbase G100产品文档中逻辑复制使用介绍：https://docs.vastdata.com.cn/zh_CN/VastbaseG100/V3.0.8/1/f5c2ae8eb9744d429ad39c02438addf6 oracle goldengate并行复制：https://oracle.hydrogen.sagittarius.connect.product.adaptavist.com/en/database/goldengate/core/26/coredoc/replicat-parallel-replicat.html#GUID-F1CD8E03-8DA1-4A78-95D3-C0516F1DA09A 2 逻辑复制性能优化 2.1 功能简述 一、逻辑复制使用示例 使用逻辑复制，可概括为3个阶段：\n一、配置参数\n通过GUC参数，配置wal日志级别，身份认证等参数\n--==[发布端]==-- gs_guc set -D $PGDATA -c \u0026#39;wal_level=logical\u0026#39; gs_guc set -D $PGDATA -h \u0026#34;host all all 0.0.0.0/0 md5\u0026#34; gs_guc set -D $PGDATA -h \u0026#34;host replication all 0.0.0.0/0 md5\u0026#34; vb_ctl restart -D $PGDATA --==[订阅端]==-- gs_guc set -D $PGDATA -c \u0026#39;max_replication_slots=16\u0026#39; gs_guc set -D $PGDATA -c \u0026#39;max_background_workers=16\u0026#39; gs_guc set -D $PGDATA -c \u0026#39;max_logical_replication_workers=16\u0026#39; 二、创建表\n--==[发布端]==-- CREATE TABLE pt1(c1 INT,c2 TEXT); CREATE TABLE pt2(c1 INT, c2 TEXT); --==[订阅端]==-- 表结构需要与发布端一致 CREATE TABLE pt1(c1 INT,c2 TEXT); CREATE TABLE pt2(c1 INT, c2 TEXT); 三、创建发布订阅\n--==[发布端]==-- -- 1. 创建发布：指定哪些表需复制 CREATE PUBLICATION pub1 FOR TABLE pt1,pt2; -- 2. 创建复制槽：存储复制状态等信息 SELECT pg_create_logical_replication_slot(\u0026#39;pslot1\u0026#39;, \u0026#39;pgoutput\u0026#39;); -- 3. 创建用户：订阅端通过该用户连接发布端，以进行数据传输 CREATE USER pu1 REPLICATION SYSADMIN LOGIN ENCRYPTED PASSWORD \u0026#39;pu1.12345\u0026#39;; GRANT ALL ON pt1,pt2 TO pu1; --==[订阅端]==-- -- 1. 创建订阅 CREATE SUBSCRIPTION sub1 CONNECTION \u0026#39;host=172.16.103.90 port=64001 dbname=pubdb user=pu1 password=pu1.12345\u0026#39; PUBLICATION pub1 WITH (create_slot=false, slot_name = \u0026#39;pslot1\u0026#39;, copy_data = false); -- 2. 单独存储访问发布端的用户密码 gs_guc generate -S \u0026#39;pu1.12345\u0026#39; -D $GAUSSHOME/bin -o subscription 四、复制数据\n--==[发布端]==-- -- 1. 变更数据 BEGIN; INSERT INTO pt1 VALUES (1, \u0026#39;data1\u0026#39;); UPDATE pt1 SET c2 = \u0026#39;data2\u0026#39; WHERE c1 = 1; COMMIT; SELECT * FROM pt1; --==[订阅端]==-- -- 1. 查询数据：预期查询结果与发布端保持一致 SELECT * FROM pt1; 二、逻辑复制基本原理 为清晰的理解本需求，需简单了解逻辑复制基本原理。逻辑复制，本质是复制解码之后的wal。此处，如下图所示，以一个实际场景为例，梳理完整的复制流程：\n上图中，关键流程如下：\n发布端 (1) 生成wal-record\n应用执行insert、delete、update、commit等语句，变更1行数据时，都会生成1条wal-reocrd，记录变更信息：变更类型、数据等。 (2) 解码wal-record\n启动1个wal-sender线程，按顺序读取insert、delete、update对应的wal-record，进行解码，即提取变更信息，生成logical-wal-record，并暂时缓存。 (3) 发送logical-wal-record\nwal-sender线程读取到commit对应的wal-record后，解密并发送缓存中所有属于本事务的logical-wal-record，即以事务为粒度发送。 订阅端 (4) 接收loigcal-wal-record\n启动1个apply-worker线程，持续接收事务的完全logical-wal-record。 (5) 重放logical-wal-record\napply-worker从logical-wal-record中，提取变更信息：变更类型、数据等，将其看做单条insert、delete、update、commit语句并执行。 针对上述流程，本需求设计并行逻辑复制机制，该机制主要包括3个子机制：\n(2) 解码wal-record：完善并行解码子机制，将1个wal-sender线程拆分为多个线程，实现多线程并行解码。 (3) 发送logical-wal-record：设计流复制协议，替换以事务为粒度的发送机制，改为以logical-wal-record为粒度的发送机制。 (5) 重放logical-wal-record：设计并行应用子机制，将1个apply-worker线程，拆分为多个apply-worker线程，实现并行应用。 2.2 功能说明 2.2.1 使用流程 场景一：使用并行逻辑复制机制 本需求重点在于提高逻辑复制性能，非功能类需求，对用户接口改动较少。为突出重点，避免内容冗余，本章只介绍新版本与旧版本逻辑复制相比，存在变化的使用流程。\n一、配置参数\n--==[发布端]==-- 无变化 --==[订阅端]==-- gs_guc set -D $PGDATA -c \u0026#39;max_replication_slots=400\u0026#39; gs_guc set -D $PGDATA -c \u0026#39;max_background_workers=400\u0026#39; gs_guc set -D $PGDATA -c \u0026#39;max_logical_replication_workers=400\u0026#39; 旧版本：在订阅端，旧版本只采用1个线程apply数据 新版本：在订阅端，并行应用子机制采用多线程apply数据，因此，需增大与最大线程数相关的guc取值。 二、创建表\n--==[发布端]==-- 无变化 --==[订阅端]==-- 无变化 三、创建发布订阅\n--==[发布端]==-- 无变化 --==[订阅端]==-- CREATE SUBSCRIPTION $subname CONNECTION \u0026#39;.. sslmode=disable\u0026#39; PUBLICATION $pubname WITH (worker_number=100); -- 以前：sslmode=prefer：发布端开了ssl，就走ssl，否则不走 -- 预期：worker_number\u0026gt;1时，启用并行逻辑复制 -- 查看worker_number取值 SELECT subwkrnum FORM pb_subscription; 旧版本：在订阅端，旧版本只采用1个线程apply数据 新版本： 多线程：在订阅端，并行应用子机制采用多线程apply数据，因此，需提前配置apply线程数。（理论上，假如发布端100个事务同时执行，worker_number=100时，复制性能最高；worker_number\u0026gt;100，复制性能与worker_number=100没区别;worker_number\u0026lt;100，取值越小则性能越低） ssl：开启ssl后，发布端、订阅端加密传输数据，传输性能低，约40+m/s，影响整体复制性能。为提高并发性能，需设置sslmode=disable。 四、复制数据\n--==[发布端]==-- 无变化 --==[订阅端]==-- 无变化（使用方式不变，复制速度变快） 在创建订阅时，如果设置了worker_number\u0026gt;1，则在复制数据时，同时启用：并行解码机制、流复制协议、并行应用机制。本需求未向用户提供额外接口。\n旧版本：tpcc中，tmpc约40w，发布端产生wal日志速度为100m/s，逻辑复制速度约10-15m/s 新版本：相同场景，发布端tpcc并发数低于400时，逻辑复制速度约70-90m/s 扩展场景一：集群启停 旧版本中，发布端、订阅端均只有1个线程参与复制。新版本中，发布端、订阅端均有多个线程参与复制，停止集群时，需确保所有线程正常停止。\n测试流程如下：\n一、配置参数 二、创建表 三、创建发布订阅 四、复制数据 五、进程停止 vb_ctl stop停止发布端 vb_ctl stop停止订阅端 扩展场景二：续点重传 旧版本中，订阅端只有1个apply-worker线程，该线程维护复制进度。新版本中，多个线程并行复制，修改了维护复制进度的机制，因此，新版本需对该场景进行覆盖测试。\n测试流程如下：\n一、配置参数 二、创建表 三、创建发布订阅 四、复制数据 五、进程重启\n在复制过程中，可手动构造以下几类场景： vb_ctl restart重启发布端，然后让订阅端重新建连 vb_ctl restart重启订阅端 kill -9异常终止发布端并重启，然后让订阅端重新建连 kill -9异常终止订阅端并重启\n预期结果：重启后，发布端与订阅端之间可正常复制数据，不会因重启导致数据丢失、数据重复等数据不一致的问题。 扩展场景三：初始快照复制 旧版本中，订阅端在初始快照复制阶段，只有1个apply-worker与复制线程进行交互，共同维护每个表的复制进度。新版本中，多个线程并行复制，修改了初始快照复制的机制，因此，新版本也需对该场景进行覆盖测试。\n测试流程如下：\n一、配置参数\n二、创建表\n三、创建发布订阅\n--==[发布端]==-- 无变化 --==[订阅端]==-- -- 1. 创建订阅：设置copy_data=true，启用初始快照复制机制 CREATE SUBSCRIPTION .. PUBLICATION .. WITH (worker_number=100, copy_data=true); 四、复制数据\n--==[发布端]==-- 无变化 --==[订阅端]==-- -- 1. 实时监测：查询系统表pg_subscription_rel，观察srsubstate列，当所有表的状态都变为\u0026#39;r\u0026#39;，则表示初始快照复制完成，否则，表示正在进行初始快照复制 SELECT * FROM pg_subscription_rel; -- 2. 增量复制：初始快照复制完成后，进行增量逻辑复制，即普通逻辑复制 -- 3. 校验数据：检查发布端、订阅端数据是否一致，确保初始快照复制机制未出问题（预期：发布端、订阅端数据一致） 扩展场景四：修改Subscription 在订阅端，修改subscription时，可能会触发启动、停止apply-worker线程，重置线程参数等，因此，需覆盖以下场景：\nALTER SUBSCRIPION DROP SUBSCRIPTION 2.2.2 配置参数和文件 用户需调大3个guc的取值：max_replication_slots，max_background_workers，max_logical_replication_workers。 CREATE SUBSCRIPTION语法：WITH子句中，新增worker_number参数，控制并行应用机制的最大并行度。 2.2.3 数据相关性 新增并行应用机制，启用多个apply-worker线程，线程数由guc参数max_replication_slots，max_background_workers，max_logical_replication_workers控制。\n2.3 接口信息 用户需调大3个guc的取值：max_replication_slots，max_background_workers，max_logical_replication_workers。 CREATE SUBSCRIPTION语法：WITH子句中，新增worker_number参数，控制并行应用机制的并行度。 pg_subscription系统表：新增1列subwkrnum，int32类型 2.4 正反向行为 2.4.1 生效说明 CREATE SUBSCRIPTION .. PUBLICATION .. WITH (worker_number=..); 语法中，worker_number取值较大时，与不设置worker_number相比，复制性能有较大提升。\n2.4.2 提示信息 在订阅端，观察wal日志的增长速度，可衡量复制速度。\n2.4.3 约束和依赖 并行应用机制：CREATE/ALTER SUBSCRIPTION .. PUBLICATION .. WITH (worker_number=..)语法中，worker_number最大取值为400。所有SUBSCRIPTION中的worker_number总和需小于3个guc的取值：max_replication_slots，max_background_workers，max_logical_replication_workers。（但是，g100存在bug，当3个guc取值超过500时，多个地方可能出现core） 2.5 安全性 2.5.1 权限控制 对外接口中，只在已有CREATE/ALTER SUBSCRIPTION语法中新增参数，不涉及变更权限。\n2.5.2 审计 对外接口中，只在已有CREATE/ALTER SUBSCRIPTION语法中新增参数，无需重新适配审计。\n2.6 影响范围 2.6.1 对已有UDT,UDF, ECPG的影响 无\n2.6.2 对系统函数的影响 无\n2.6.3 对系统CATALOG的影响 pg_subscription系统表，新增1列subwkrnum，存储并行应用机制中的apply-worker数量。\n2.6.4 对xlog日志格式、数据格式的影响 设计流复制协议，与旧版本复制协议区别如下：\n发布端发送时机 旧版本：读取与解码到commit对应的wal-record时，发送事务对应的所有logical-wal-record 新版本：实时发送logical-wal-record 发布端发送格式 旧版本：假如1个事务执行：begin, insert, update, commit，发布端解码到commit时，会一次性发送4条消息。4条消息类型分别是[‘B’, ‘I’, ‘U’, ‘C’]，每条消息统一格式如下：\n+-----+-------------------------------+---------+-------------------+ | \u0026#39;w\u0026#39; | dataStart | walEnd | sendTime | msgType | msgBody | +-----+-------------------------------+---------+-------------------+ msgType取值范围：{B, C, I, U, D, ..} 其中，\u0026#39;B\u0026#39; 消息携带事务id 新版本：假如1个事务执行：begin, insert, update, commit，发布端实时发送消息，不等待commit，发送3条’F’消息，’F’消息中会封装旧版本的’I’, ‘U’, ‘C’消息的内容，另外，每条’F’消息都携带事务信息。’F’消息的格式如下：\n# 新版本：新增msgType：\u0026#39;F\u0026#39; +-----+-------------------------------+*************************+---------+-------------------+ | \u0026#39;w\u0026#39; | dataStart | walEnd | sendTime | \u0026#39;F\u0026#39; | xid | msgLen | msgType | msgBody | +-----+-------------------------------+*************************+---------+-------------------+ msgType取值范围：{C, I, U, D, ..} 原来msgType处，设置为\u0026#39;F\u0026#39;类型，表示flow类型的消息，即流复制协议。不使用\u0026#39;S\u0026#39;，方便与pg的流复制协议区分。 每条消息，需额外携带xid信息。 2.6.5 与其他功能交互时的行为表现 无\n2.6.6 版本兼容性 订阅端与发布端建立连接时，订阅端会根据CRETE SUBSCRIPTION语法设置的参数，生成连接命令。\n旧版本，订阅端发送的连接命令如下：\nSTART_REPLICATION SLOT \u0026#34;$slot_name\u0026#34; LOGICAL $start_lsn (proto_version \u0026#39;3\u0026#39;, publication_names \u0026#39;\u0026#34;$publication_name\u0026#34;\u0026#39;) 新版本中，如果CRETE SUBSCRIPTION时，指定worker_number\u0026gt;1，即启用并行逻辑复制，订阅端发送的连接命令如下：\nSTART_REPLICATION SLOT \u0026#34;$slot_name\u0026#34; LOGICAL $start_lsn (proto_version \u0026#39;3\u0026#39;, publication_names \u0026#39;\u0026#34;$publication_name\u0026#34;\u0026#39;， streaming \u0026#39;extreme\u0026#39;, parallel-decode-num \u0026#39;20\u0026#39;, max-recordbuffer-in-memory \u0026#39;100\u0026#39;, max-txn-in-memory \u0026#39;100\u0026#39;) -- 新增streaming参数：表示使用 流复制协议 -- 新增parallel-decode-num、max-recordbuffer-in-memory、max-txn-in-memory：表示让发布端使用 并行解码机制 新版中，如果不主动指定worker_number\u0026gt;1，则仍然使用旧版本的机制、协议，本需求保留并隔离了旧版本的串行解码机制，完全不受并行解码机制影响。\n2.6.7 用户行为变更 新增支持并行逻辑复制机制，扩展CRETE SUBSCRIPTION语法，新增worker_number参数，用于控制并行复制的线程数，合理配置worker_number取值，可大幅提高逻辑复制速度。\n另外，如果worker_number设置的较大，则需提高订阅端max_replication_slots、max_background_workers、max_logical_replication_workers这3个guc参数的取值。\npg_subscription系统表新增1列subwkrnum。\n2.7 指标相关 2.7.1 关键资源指标 cpu：订阅端启动50-400个apply-worker线程，cpu占用率约5%-15%。 内存：发布端内存占用变小，修改前发布端缓存所有未提交事务，修改后发布端不缓存事务。订阅端内存占用变大，无空闲apply-worker时，发布端会缓存数据。 外存：订阅端无空闲apply-worker时，缓存的事务数量超过1000后，会物化数据。 2.7.2 系统性指标 无\n2.7.3 性能指标 之前，在优化发布端传输速度前，自测性能如下（实际性能应该高于以下数据，滚动升级场景，50并发，订阅端速度能稳定在80+m/s，峰值能到90-100m/s）：\n编号 tpcc并发数 tpmc (10min) tpmTotal 发布端速度 订阅端速度(2次抽样) 1 10 5.8w 12.9w 13.4 m/s 52.2 m/s 2 50 21.8w 48.6w 50.9 m/s {76.4, 77.3} m/s 3 100 33.3w 73.9w 77.5 m/s {74.0, 73.2} m/s 4 200 35.4w 78.7w 82.8 m/s {73.8, 70.7} m/s 5 300 36.3w 80.9w 84.9 m/s {66.4, 64.0} m/s 6 400 32.6w 72.6w 76.4 m/s {62.1, 60.8} m/s 测试环境：单机，kunpeng-920，128核，760G内存，tpcc 100 warehousee 发布端速度：tpcc运行10min，(结束lsn - 开始lsn) / 600s 订阅端速度：启动复制，抽样：(第130s的lsn - 第30s的lsn) / 100s，(第230s的lsn - 第130s的lsn) / 100s 2.8 测试建议 本次修改，几乎重写了逻辑复制大部分流程，发布端、订阅端、传输协议等修改率超过60%，因此，原有逻辑复制功能，可能都需要覆盖测试。\n2.8 其他说明 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/15-requirement-logical-replication/","summary":"\u003ch1 id=\"1-简介\"\u003e1 简介\u003c/h1\u003e\n\u003ch2 id=\"11-目的\"\u003e1.1 目的\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003e逻辑复制\u003c/strong\u003e是一种在多个数据库实例之间复制数据的功能，通常用于从一个数据库实例中，将针对指定表的insert、delete、update等写操作，复制到其他另一个数据库实例。在数据库术语中，统一称逻辑复制的发送方为\u003cstrong\u003e发布端\u003c/strong\u003e，称接收方为\u003cstrong\u003e订阅端\u003c/strong\u003e。Oracle、Postgresql、Vastbase等数据库产品，均提供逻辑复制功能。\u003c/p\u003e\n\u003cp\u003e当前版本，逻辑复制性能较低。以tpcc场景为例，发布端40w tmpc时，产生wal日志速度约100+m/s，订阅端的复制速度约10+m/s。在滚动升级场景，主机和备机可能是不同的产品版本，主备复制数据时，不能使用物理复制，只能使用逻辑复制。在长存客户场景中，主机产生wal日志速度在50+m/s左右，备机使用逻辑复制，复制速度约10+m/s，备机将追赶不上主机进度，导致滚动升级失败。\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e主a                     备b                         备c\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e+-----------------------+---------------------------+-----------------------------\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"nv\"\u003e1\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e\u0026gt;执行业务\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e2\u003c/span\u003e 开始滚动升级，暂停流复制 \u003cspan class=\"nv\"\u003elag\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e400M\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e3\u003c/span\u003e 暂停流复制（物理复制）\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e4\u003c/span\u003e 创建逻辑复制槽 \u003cspan class=\"nv\"\u003elsn1\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e1G\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e5\u003c/span\u003e 恢复流复制\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e6\u003c/span\u003e 物理复制追赶，到逻辑复制槽\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e6\u003c/span\u003e 开始单节点升级\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e7\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e升级\u003cspan class=\"o\"\u003e]\u003c/span\u003e 停止进程\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e8\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e升级\u003cspan class=\"o\"\u003e]\u003c/span\u003e 替换二进制等\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e9\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e升级\u003cspan class=\"o\"\u003e]\u003c/span\u003e 启动进程\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e10\u003c/span\u003e 单节点升级成功\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e11\u003c/span\u003e 持续执行业务 \u003cspan class=\"nv\"\u003elsn2\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e2G\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e12\u003c/span\u003e 创建订阅，启动逻辑复制，lsn1\u003cspan class=\"o\"\u003e=\u003c/span\u003e1G\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e13\u003c/span\u003e 逻辑复制开始追赶（初始差距：lsn2-lsn1\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e14\u003c/span\u003e 持续执行业务 \u003cspan class=\"nv\"\u003elsn3\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e2.5G\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e15\u003c/span\u003e 逻辑复制持续追赶 \u003cspan class=\"nv\"\u003elsn\u003c/span\u003e\u003cspan class=\"o\"\u003e=\u003c/span\u003e1.6G\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e16\u003c/span\u003e \u003cspan class=\"o\"\u003e(\u003c/span\u003e可重置lag\u003cspan class=\"o\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e17\u003c/span\u003e 差距持续缩小（从lsn2-lsn1降低到lag）\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e18\u003c/span\u003e 发送停机命令\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e19\u003c/span\u003e 停止业务\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e                        \u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e20\u003c/span\u003e 差距持续缩小，从lag缩小至0\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e|\u003c/span\u003e\u003cspan class=\"m\"\u003e21\u003c/span\u003e 停止进程成功\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e因此，需大幅提高逻辑复制速度，在长存客户场景中，逻辑复制速度至少需达到70+m/s。目前，发布端、订阅端均存在性能瓶颈，均需要优化。\u003c/p\u003e\n\u003ch2 id=\"12-适用范围\"\u003e1.2 适用范围\u003c/h2\u003e\n\u003cp\u003eG100 3.0.9 psu2及之后版本\u003c/p\u003e\n\u003ch2 id=\"13-术语定义首字母缩写词和缩略语\"\u003e1.3 术语定义、首字母缩写词和缩略语\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e发布端：逻辑复制场景，发送数据方。\u003c/li\u003e\n\u003cli\u003e订阅端：逻辑复制场景，接收数据方。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"14-参考资料\"\u003e1.4 参考资料\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003eVastbase G100产品文档中逻辑复制使用介绍：\u003ca href=\"https://docs.vastdata.com.cn/zh_CN/VastbaseG100/V3.0.8/1/f5c2ae8eb9744d429ad39c02438addf6\"\u003ehttps://docs.vastdata.com.cn/zh_CN/VastbaseG100/V3.0.8/1/f5c2ae8eb9744d429ad39c02438addf6\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003eoracle goldengate并行复制：\u003ca href=\"https://oracle.hydrogen.sagittarius.connect.product.adaptavist.com/en/database/goldengate/core/26/coredoc/replicat-parallel-replicat.html#GUID-F1CD8E03-8DA1-4A78-95D3-C0516F1DA09A\"\u003ehttps://oracle.hydrogen.sagittarius.connect.product.adaptavist.com/en/database/goldengate/core/26/coredoc/replicat-parallel-replicat.html#GUID-F1CD8E03-8DA1-4A78-95D3-C0516F1DA09A\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch1 id=\"2-逻辑复制性能优化\"\u003e2 逻辑复制性能优化\u003c/h1\u003e\n\u003ch2 id=\"21-功能简述\"\u003e2.1 功能简述\u003c/h2\u003e\n\u003ch3 id=\"一逻辑复制使用示例\"\u003e一、逻辑复制使用示例\u003c/h3\u003e\n\u003cp\u003e使用逻辑复制，可概括为3个阶段：\u003c/p\u003e","title":"海量 15 需求 逻辑复制性能优化"},{"content":"这里放一些可在线阅读的电子书（PDF）。写作台上传后会自动登记到书库。\nPostgreSQL 14 Internals (Parts 1–3, English)1.9 MB 在线阅读 下载 ","permalink":"https://my-blog.j8465383071.workers.dev/ebooks/","summary":"\u003cp\u003e这里放一些可在线阅读的电子书（PDF）。写作台上传后会自动登记到书库。\u003c/p\u003e\n\u003cul class=\"ebook-shelf\"\u003e\u003cli class=\"ebook-card\"\u003e\n    \u003cdiv class=\"ebook-card__meta\"\u003e\n      \u003cstrong class=\"ebook-card__title\"\u003ePostgreSQL 14 Internals (Parts 1–3, English)\u003c/strong\u003e\u003cspan class=\"ebook-card__size\"\u003e1.9 MB\u003c/span\u003e\u003c/div\u003e\n    \u003cdiv class=\"ebook-card__actions\"\u003e\n      \u003ca href=\"/ebooks/postgresql_internals-14_parts1-3_en.pdf\" target=\"_blank\" rel=\"noopener\"\u003e在线阅读\u003c/a\u003e\n      \u003ca href=\"/ebooks/postgresql_internals-14_parts1-3_en.pdf\" download\u003e下载\u003c/a\u003e\n    \u003c/div\u003e\n    \u003ciframe class=\"ebook-card__frame\" src=\"/ebooks/postgresql_internals-14_parts1-3_en.pdf\" title=\"PostgreSQL 14 Internals (Parts 1–3, English)\" loading=\"lazy\"\u003e\u003c/iframe\u003e\n  \u003c/li\u003e\u003c/ul\u003e","title":"电子书"},{"content":"G100学习笔记 1. page相关 1.1 page的关键数据结构 typedef struct { PageXLogRecPtr pd_lsn; /* 当前页的最后一次修改对应的WAL记录的LSN */ uint16 pd_checksum; /* 当前页的checksum校验和，用来维护页面的完整性，使用特定的算法生成固定大小的值，在写入时计算，读取时校验，读取时计算checksum，与本记录比对 */ uint16 pd_flags; /* 页状态标志位 */ uint16 pd_lower; /* } ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/g100%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/","summary":"\u003ch1 id=\"g100学习笔记\"\u003eG100学习笔记\u003c/h1\u003e\n\u003ch2 id=\"1-page相关\"\u003e1. page相关\u003c/h2\u003e\n\u003ch3 id=\"11-page的关键数据结构\"\u003e1.1 page的关键数据结构\u003c/h3\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-c\" data-lang=\"c\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003etypedef\u003c/span\u003e \u003cspan class=\"k\"\u003estruct\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003ePageXLogRecPtr\u003c/span\u003e \u003cspan class=\"n\"\u003epd_lsn\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 当前页的最后一次修改对应的WAL记录的LSN */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003euint16\u003c/span\u003e \u003cspan class=\"n\"\u003epd_checksum\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 当前页的checksum校验和，用来维护页面的完整性，使用特定的算法生成固定大小的值，在写入时计算，读取时校验，读取时计算checksum，与本记录比对 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003euint16\u003c/span\u003e \u003cspan class=\"n\"\u003epd_flags\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* 页状态标志位 */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"n\"\u003euint16\u003c/span\u003e \u003cspan class=\"n\"\u003epd_lower\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e \u003cspan class=\"cm\"\u003e/* \n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e}\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e","title":"G100学习笔记"},{"content":"Babelfish 编译环境搭建指南 适用环境：CentOS 7，离线环境，vastbase-server + sqlserver-extensions\n一、创建用户 # 创建用户并设置密码 useradd vast echo \u0026#34;vast:gauss@123\u0026#34; | chpasswd # 授予 sudo 权限（加入 wheel 组） usermod -aG wheel vast # 验证 id vast 二、配置环境变量 将以下内容写入 ~/.bash_profile，每次登录自动生效：\ncat \u0026gt;\u0026gt; ~/.bash_profile \u0026lt;\u0026lt; \u0026#39;EOF\u0026#39; # Babelfish 基础路径 export BABELFISH_HOME=~/vastbase-server/install export BINARYLIBS=~/vastbase-server/binarylibs export GCC_PATH=$BINARYLIBS/buildtools/gcc7.3 # 编译器 export CC=$GCC_PATH/gcc/bin/gcc export CXX=$GCC_PATH/gcc/bin/g++ # cmake（优先使用项目自带版本，放在 PATH 最前面） export PATH=$BINARYLIBS/buildtools/cmake/bin:$GCC_PATH/gcc/bin:$BABELFISH_HOME/bin:$PATH # 动态库路径 export LD_LIBRARY_PATH=$GCC_PATH/gcc/lib64:$BABELFISH_HOME/lib:$BINARYLIBS/kernel/dependency/openssl/comm/lib:$LD_LIBRARY_PATH # cmake 变量（防止 Makefile 调用系统旧版本） export cmake=$(which cmake) # PG 相关 export PG_CONFIG=$BABELFISH_HOME/bin/pg_config export PG_SRC=`pwd` EOF source ~/.bash_profile 验证工具版本：\ncmake --version # 应为 3.21.x gcc --version # 应为 7.3.x 三、配置系统动态库（需 root） 3.1 添加 OpenSSL 库路径 sudo bash -c \u0026#39;echo \u0026#34;/home/binarylibs/kernel/dependency/openssl/comm/lib\u0026#34; \u0026gt; /etc/ld.so.conf.d/vastbase-openssl.conf\u0026#39; sudo bash -c \u0026#39;echo \u0026#34;/home/vast/vastbase-server/binarylibs/buildtools/gcc7.3/gcc/lib64\u0026#34; \u0026gt;\u0026gt; /etc/ld.so.conf.d/vastbase-openssl.conf\u0026#39; sudo ldconfig 验证：\nldconfig -p | grep libcrypto ldconfig -p | grep libstdc++ 3.2 创建 antlr4 软链接 ln -s $BABELFISH_HOME/lib/libantlr4-runtime.so.4.13.2 $BABELFISH_HOME/lib/libantlr4-runtime.so 3.3 将 antlr4 头文件拷贝到系统目录（需 root） # 找到头文件位置 find ~/vastbase-server -path \u0026#34;*/antlr4*/*.h\u0026#34; 2\u0026gt;/dev/null | head -5 # 拷贝到系统 include sudo mkdir -p /usr/local/include/antlr4-runtime sudo cp -r /path/to/antlr4-runtime/include/* /usr/local/include/antlr4-runtime/ # 验证 ls /usr/local/include/antlr4-runtime/ 四、编译 vastbase-server（内核） cd ~/vastbase-server ./configure \\ CFLAGS=\u0026#34;-ggdb\u0026#34; \\ --prefix=$BABELFISH_HOME \\ --enable-debug \\ --with-ldap \\ --with-libxml \\ --with-pam \\ --with-uuid=ossp \\ --enable-nls \\ --with-libxslt \\ --with-icu \\ CC=$CC \\ CXX=$CXX make -j$(nproc) make install 五、编译 sqlserver-extensions（Babelfish 扩展） 5.1 编译顺序 必须按以下顺序编译安装：\n1. babelfishpg_money 2. babelfishpg_common 3. babelfishpg_tsql 4. babelfishpg_tds 5.2 通用编译命令 cd ~/sqlserver-extensions/contrib/\u0026lt;插件名\u0026gt; make \\ CFLAGS=\u0026#34;-I$BINARYLIBS/kernel/dependency/openssl/comm/include\u0026#34; \\ PG_CFLAGS=\u0026#34;-I$BINARYLIBS/kernel/dependency/openssl/comm/include\u0026#34; \\ PG_CXXFLAGS=\u0026#34;-I$BINARYLIBS/kernel/dependency/openssl/comm/include\u0026#34; \\ LDFLAGS=\u0026#34;-L$BINARYLIBS/kernel/dependency/openssl/comm/lib\u0026#34; \\ CC=$CC make install 5.3 babelfishpg_tsql 特殊处理 编译前需确保 antlr4 库和头文件就位：\ncd ~/sqlserver-extensions/contrib/babelfishpg_tsql # antlr4 runtime 软链接（如未创建） ls $BABELFISH_HOME/lib/libantlr4-runtime.so || \\ ln -s $BABELFISH_HOME/lib/libantlr4-runtime.so.4.13.2 $BABELFISH_HOME/lib/libantlr4-runtime.so make \\ CFLAGS=\u0026#34;-I$BINARYLIBS/kernel/dependency/openssl/comm/include\u0026#34; \\ PG_CXXFLAGS=\u0026#34;-I$BINARYLIBS/kernel/dependency/openssl/comm/include\u0026#34; \\ LDFLAGS=\u0026#34;-L$BINARYLIBS/kernel/dependency/openssl/comm/lib -L$BABELFISH_HOME/lib\u0026#34; \\ CC=$CC make install 六、初始化 Babelfish 数据库 6.1 初始化数据目录 initdb -D $PGDATA 6.2 启动数据库 pg_ctl start -D $PGDATA 6.3 执行初始化脚本 ./psql postgres \u0026lt;\u0026lt; \u0026#39;EOF\u0026#39; CREATE USER babelfish_user WITH SUPERUSER CREATEDB CREATEROLE PASSWORD \u0026#39;12345678\u0026#39; INHERIT; DROP DATABASE IF EXISTS babelfish_db; CREATE DATABASE babelfish_db OWNER babelfish_user; \\c babelfish_db; CREATE EXTENSION IF NOT EXISTS \u0026#34;babelfishpg_tds\u0026#34; CASCADE; GRANT ALL ON SCHEMA sys TO babelfish_user; ALTER USER babelfish_user CREATEDB; ALTER SYSTEM SET babelfishpg_tsql.database_name = \u0026#39;babelfish_db\u0026#39;; ALTER SYSTEM SET babelfishpg_tsql.migration_mode = \u0026#39;multi-db\u0026#39;; SELECT pg_reload_conf(); CALL sys.initialize_babelfish(\u0026#39;babelfish_user\u0026#39;); EOF 提示符变为 babelfish_db=\u0026gt; 表示初始化成功。\n七、安装 mssql-tools（用于 1433 端口测试） 离线环境需提前准备以下 rpm 包：\nmsodbcsql17-*.rpm mssql-tools-*.rpm # 需要 root 安装 su - root rpm -ivh msodbcsql17-17.10.6.1-1.x86_64.rpm rpm -ivh mssql-tools-17.9.1.1-1.x86_64.rpm 安装后测试连接：\nexport PATH=$PATH:/opt/mssql-tools/bin sqlcmd -S 127.0.0.1,1433 -U babelfish_user -P 12345678 八、常见问题排查 错误信息 原因 解决方案 cannot find -lantlr4-runtime antlr4 库未找到 创建软链接，添加 LD_LIBRARY_PATH libcrypto.so.1.1: No such file OpenSSL 库路径未配置 添加到 /etc/ld.so.conf.d 并 ldconfig GLIBCXX_3.4.21 not found 系统 libstdc++ 版本过低 将 gcc7.3/lib64 加入 LD_LIBRARY_PATH CMake 3.7 or higher required 使用了系统旧版 cmake export cmake=$(which cmake)，确保 PATH 中项目 cmake 在前 openssl/sha.h: No such file OpenSSL 头文件路径未指定 添加 CFLAGS/PG_CFLAGS Permission denied (cmake) 用户无权访问 root 目录下的工具 chmod 755 /root 或将工具迁移到 vast 用户目录 schema \u0026quot;sys\u0026quot; does not exist babelfishpg_tsql 加载失败 先解决库依赖问题，重新执行初始化脚本 cannot drop active babelfish database 重复执行初始化脚本 先断开所有连接再执行，或忽略（不影响结果） 九、SSH Key 配置（用于 Git） ssh-keygen -t rsa -b 4096 -C \u0026#34;your_email@example.com\u0026#34; # 一路回车使用默认路径 # 查看公钥，添加到 Git 平台 cat ~/.ssh/id_rsa.pub ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/babelfish_build/","summary":"\u003ch1 id=\"babelfish-编译环境搭建指南\"\u003eBabelfish 编译环境搭建指南\u003c/h1\u003e\n\u003cblockquote\u003e\n\u003cp\u003e适用环境：CentOS 7，离线环境，vastbase-server + sqlserver-extensions\u003c/p\u003e\u003c/blockquote\u003e\n\u003chr\u003e\n\u003ch2 id=\"一创建用户\"\u003e一、创建用户\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 创建用户并设置密码\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003euseradd vast\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003eecho\u003c/span\u003e \u003cspan class=\"s2\"\u003e\u0026#34;vast:gauss@123\u0026#34;\u003c/span\u003e \u003cspan class=\"p\"\u003e|\u003c/span\u003e chpasswd\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 授予 sudo 权限（加入 wheel 组）\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eusermod -aG wheel vast\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"c1\"\u003e# 验证\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eid vast\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003chr\u003e\n\u003ch2 id=\"二配置环境变量\"\u003e二、配置环境变量\u003c/h2\u003e\n\u003cp\u003e将以下内容写入 \u003ccode\u003e~/.bash_profile\u003c/code\u003e，\u003cstrong\u003e每次登录自动生效\u003c/strong\u003e：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ecat \u0026gt;\u0026gt; ~/.bash_profile \u003cspan class=\"s\"\u003e\u0026lt;\u0026lt; \u0026#39;EOF\u0026#39;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e# Babelfish 基础路径\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eexport BABELFISH_HOME=~/vastbase-server/install\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eexport BINARYLIBS=~/vastbase-server/binarylibs\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eexport GCC_PATH=$BINARYLIBS/buildtools/gcc7.3\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e# 编译器\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eexport CC=$GCC_PATH/gcc/bin/gcc\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eexport CXX=$GCC_PATH/gcc/bin/g++\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e# cmake（优先使用项目自带版本，放在 PATH 最前面）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eexport PATH=$BINARYLIBS/buildtools/cmake/bin:$GCC_PATH/gcc/bin:$BABELFISH_HOME/bin:$PATH\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e# 动态库路径\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eexport LD_LIBRARY_PATH=$GCC_PATH/gcc/lib64:$BABELFISH_HOME/lib:$BINARYLIBS/kernel/dependency/openssl/comm/lib:$LD_LIBRARY_PATH\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e# cmake 变量（防止 Makefile 调用系统旧版本）\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eexport cmake=$(which cmake)\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003e# PG 相关\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eexport PG_CONFIG=$BABELFISH_HOME/bin/pg_config\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eexport PG_SRC=`pwd`\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"s\"\u003eEOF\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"nb\"\u003esource\u003c/span\u003e ~/.bash_profile\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e验证工具版本：\u003c/p\u003e","title":"Babelfish搭建指南"},{"content":"基本概念 这里是融合版的一个需求，属于兼容性需求类别，主要实现的是一个黑名单，是要把一个列表中的多个插件不允许在MSSQL兼容安装包中出现，或只能在5432端口（PG模式）中使用，不能在1433端口（MSSQL模式）中使用。\n初步分析 根据需求列表，可以基本将需要修改的插件分为三类：\n禁止在双端口安装使用； 在5432端口允许使用，1433端口禁止安装使用； 双端口都允许使用； 其中，需求描述特别提到，允许在编译阶段进行修改，由此可以对应的提出三类插件的修改方案：\n在编译阶段不安装，也就是在contrib/Makefile中的SUBDIR安装插件，删除这些不允许在双端口安装的插件； 在hooks.c中增加一个名单，名单中包含这些允许在5432不允许在1433安装的插件，首先检测当前dialect是否为tsql，如果为tsql，检查是否是T_CreExtensionStmt，如果是则检查插件名单是否在这个名单之内，如果没有则放行，有则报错； 不做任何处理； 理论上，以上方案实施后，能够达到双端口不可用则直接无法找到插件，用户自行安装则不保证可能出现的任何问题；对于5432可用1433不可用，会进行报错；其他类型不做处理；应该可以达到需求描述的目的实现；\n边界考虑 由于删除了某些插件编译且对某些插件在一定场景进行了屏蔽，考虑数据库升级场景，如果以前使用过此插件，现在进行了屏蔽，可能导致升级失败； 灵活性 现在的屏蔽方式是使用直接修改编译文件与硬编码名单的方式实现，如果在一个版本内，由于某些特殊原因想启用已屏蔽的插件，则在当前版本是无法实现的。如果将名单作成guc参数，则可以提供灵活性，但是一旦被手动篡改，则无法预料可能产生的问题； ","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/forbid-extension/","summary":"\u003ch2 id=\"基本概念\"\u003e基本概念\u003c/h2\u003e\n\u003cp\u003e这里是融合版的一个需求，属于兼容性需求类别，主要实现的是一个黑名单，是要把一个列表中的多个插件不允许在MSSQL兼容安装包中出现，或只能在5432端口（PG模式）中使用，不能在1433端口（MSSQL模式）中使用。\u003c/p\u003e\n\u003ch2 id=\"初步分析\"\u003e初步分析\u003c/h2\u003e\n\u003cp\u003e根据需求列表，可以基本将需要修改的插件分为三类：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e禁止在双端口安装使用；\u003c/li\u003e\n\u003cli\u003e在5432端口允许使用，1433端口禁止安装使用；\u003c/li\u003e\n\u003cli\u003e双端口都允许使用；\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e其中，需求描述特别提到，允许在编译阶段进行修改，由此可以对应的提出三类插件的修改方案：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e在编译阶段不安装，也就是在contrib/Makefile中的SUBDIR安装插件，删除这些不允许在双端口安装的插件；\u003c/li\u003e\n\u003cli\u003e在hooks.c中增加一个名单，名单中包含这些允许在5432不允许在1433安装的插件，首先检测当前dialect是否为tsql，如果为tsql，检查是否是T_CreExtensionStmt，如果是则检查插件名单是否在这个名单之内，如果没有则放行，有则报错；\u003c/li\u003e\n\u003cli\u003e不做任何处理；\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e理论上，以上方案实施后，能够达到双端口不可用则直接无法找到插件，用户自行安装则不保证可能出现的任何问题；对于5432可用1433不可用，会进行报错；其他类型不做处理；应该可以达到需求描述的目的实现；\u003c/p\u003e\n\u003ch2 id=\"边界考虑\"\u003e边界考虑\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e由于删除了某些插件编译且对某些插件在一定场景进行了屏蔽，考虑数据库升级场景，如果以前使用过此插件，现在进行了屏蔽，可能导致升级失败；\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"灵活性\"\u003e灵活性\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e现在的屏蔽方式是使用直接修改编译文件与硬编码名单的方式实现，如果在一个版本内，由于某些特殊原因想启用已屏蔽的插件，则在当前版本是无法实现的。如果将名单作成guc参数，则可以提供灵活性，但是一旦被手动篡改，则无法预料可能产生的问题；\u003c/li\u003e\n\u003c/ul\u003e","title":"避免用户错误使用到pg插件"},{"content":"今天的每日一题：1202. 从根到叶的二进制数之和。\n简单来说，就是给定一颗层序遍历的数组，表示一颗树，例如：\n输入：root = [1,0,1,0,1,0,1] 输出：22 解释：(100) + (101) + (110) + (111) = 4 + 5 + 6 + 7 = 22 可以表示为：\n1 / \\ 0 1 / \\ / \\ 0 1 0 1 思路就是使用dfs来遍历这个树，代码为：\n/** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) {} * TreeNode(int x) : val(x), left(nullptr), right(nullptr) {} * TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {} * }; */ class Solution { public: int dfs(TreeNode *root, int val) { if (root == nullptr) return 0; val = val \u0026lt;\u0026lt; 1 | root-\u0026gt;val; if (root-\u0026gt;left == nullptr \u0026amp;\u0026amp; root-\u0026gt;right == nullptr) return val; return dfs(root-\u0026gt;left, val) + dfs(root-\u0026gt;right, val); } int sumRootToLeaf(TreeNode* root) { return dfs(root, 0); } }; 拿到这个题就知道用dfs，但是这个计算的方式确实没想到，二进制移位操作，并且使用局部变量保存临时结果，就不需要复杂的字符串拼接然后转换10进制了，例如上例：\n1. root-\u0026gt;val : 1 curr val : 1 goto dfs(root-\u0026gt;left, 1) 2. root-\u0026gt;left-\u0026gt;val : 10 curr val : 10 goto dfs(root-\u0026gt;left-\u0026gt;left, 10) 3. root-\u0026gt;left-\u0026gt;left-\u0026gt;val : 100 curr val : 100 return 100 4. goto 2 goto dfs(root-\u0026gt;left-\u0026gt;right, 10) curr val : 10 5. root-\u0026gt;left-\u0026gt;right-\u0026gt;val : 101 curr val : 101 return 101 6. goto 2 return 100 + 101 curr val : 10 7. goto 1 curr val : 1 goto dfs(root-\u0026gt;right, 1) 8. root-\u0026gt;right-\u0026gt;val : 11 curr val : 11 goto dfs(root-\u0026gt;right-\u0026gt;left, 11) 9. root-\u0026gt;right-\u0026gt;left-\u0026gt;val : 110 curr val : 110 return 110 10. goto 8 curr val : 11 goto dfs(root-\u0026gt;right-\u0026gt;right, 11) 11. root-\u0026gt;right-\u0026gt;right-\u0026gt;val : 111 curr val : 111 return 111 12. goto 7 curr val : 1 return 110 + 111 13 return 100 + 101 + 110 + 111 如此一来就可以得到最后的结果，虽然是一道easy，但还是想了很久，下次碰到类似题目，希望可以记住这样好的思路。\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/algorithm/dfs/","summary":"\u003cp\u003e今天的每日一题：1202. 从根到叶的二进制数之和。\u003c/p\u003e\n\u003cp\u003e简单来说，就是给定一颗层序遍历的数组，表示一颗树，例如：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e输入：root \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"o\"\u003e[\u003c/span\u003e1,0,1,0,1,0,1\u003cspan class=\"o\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e输出：22\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e解释：\u003cspan class=\"o\"\u003e(\u003c/span\u003e100\u003cspan class=\"o\"\u003e)\u003c/span\u003e + \u003cspan class=\"o\"\u003e(\u003c/span\u003e101\u003cspan class=\"o\"\u003e)\u003c/span\u003e + \u003cspan class=\"o\"\u003e(\u003c/span\u003e110\u003cspan class=\"o\"\u003e)\u003c/span\u003e + \u003cspan class=\"o\"\u003e(\u003c/span\u003e111\u003cspan class=\"o\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e4\u003c/span\u003e + \u003cspan class=\"m\"\u003e5\u003c/span\u003e + \u003cspan class=\"m\"\u003e6\u003c/span\u003e + \u003cspan class=\"nv\"\u003e7\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"m\"\u003e22\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e可以表示为：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"m\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e   / \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"se\"\u003e\u003c/span\u003e  \u003cspan class=\"m\"\u003e0\u003c/span\u003e   \u003cspan class=\"m\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e / \u003cspan class=\"se\"\u003e\\ \u003c/span\u003e / \u003cspan class=\"se\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"se\"\u003e\u003c/span\u003e\u003cspan class=\"m\"\u003e0\u003c/span\u003e  \u003cspan class=\"m\"\u003e1\u003c/span\u003e  \u003cspan class=\"m\"\u003e0\u003c/span\u003e  \u003cspan class=\"m\"\u003e1\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e思路就是使用dfs来遍历这个树，代码为：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-C++\" data-lang=\"C++\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e/**\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * Definition for a binary tree node.\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * struct TreeNode {\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *     int val;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *     TreeNode *left;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *     TreeNode *right;\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *     TreeNode() : val(0), left(nullptr), right(nullptr) {}\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e * };\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"cm\"\u003e */\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eclass\u003c/span\u003e \u003cspan class=\"nc\"\u003eSolution\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003epublic\u003c/span\u003e\u003cspan class=\"o\"\u003e:\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003edfs\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTreeNode\u003c/span\u003e \u003cspan class=\"o\"\u003e*\u003c/span\u003e\u003cspan class=\"n\"\u003eroot\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"n\"\u003eval\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eroot\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"k\"\u003enullptr\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"n\"\u003eval\u003c/span\u003e \u003cspan class=\"o\"\u003e=\u003c/span\u003e \u003cspan class=\"n\"\u003eval\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026lt;\u0026lt;\u003c/span\u003e \u003cspan class=\"mi\"\u003e1\u003c/span\u003e \u003cspan class=\"o\"\u003e|\u003c/span\u003e \u003cspan class=\"n\"\u003eroot\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eval\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003eif\u003c/span\u003e \u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eroot\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eleft\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"k\"\u003enullptr\u003c/span\u003e \u003cspan class=\"o\"\u003e\u0026amp;\u0026amp;\u003c/span\u003e \u003cspan class=\"n\"\u003eroot\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eright\u003c/span\u003e \u003cspan class=\"o\"\u003e==\u003c/span\u003e \u003cspan class=\"k\"\u003enullptr\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e            \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003eval\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"nf\"\u003edfs\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eroot\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eleft\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eval\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"o\"\u003e+\u003c/span\u003e \u003cspan class=\"n\"\u003edfs\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eroot\u003c/span\u003e\u003cspan class=\"o\"\u003e-\u0026gt;\u003c/span\u003e\u003cspan class=\"n\"\u003eright\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"n\"\u003eval\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"kt\"\u003eint\u003c/span\u003e \u003cspan class=\"nf\"\u003esumRootToLeaf\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eTreeNode\u003c/span\u003e\u003cspan class=\"o\"\u003e*\u003c/span\u003e \u003cspan class=\"n\"\u003eroot\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e \u003cspan class=\"p\"\u003e{\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e        \u003cspan class=\"k\"\u003ereturn\u003c/span\u003e \u003cspan class=\"n\"\u003edfs\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003eroot\u003c/span\u003e\u003cspan class=\"p\"\u003e,\u003c/span\u003e \u003cspan class=\"mi\"\u003e0\u003c/span\u003e\u003cspan class=\"p\"\u003e);\u003c/span\u003e    \n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e    \u003cspan class=\"p\"\u003e}\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"p\"\u003e};\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e拿到这个题就知道用dfs，但是这个计算的方式确实没想到，二进制移位操作，并且使用局部变量保存临时结果，就不需要复杂的字符串拼接然后转换10进制了，例如上例：\u003c/p\u003e","title":"深度优先遍历"},{"content":"基本概念 逻辑复制是数据同步的一种方式，逻辑二字主要指的是传输数据的格式，与之相对的是物理复制。\n逻辑数据格式 逻辑数据格式是指，能够由一定规则描述的，符合SQL直觉的一种数据格式，例如：\n[MsgType：Insert，Relation：test，New Tuple：[a, int, 100]] 从这种数据格式上，能够通过解析等方式，将数据还原为SQL语句，这也同时表现了逻辑复制的第一个特点：无视物理结构上的差异，可以在异构、跨版本的数据库之间进行数据同步。\n接上例，通过一定的解析步骤，我们总能够得到：\nInsert into test(a) values 100::int; 对于不同内核来说，可能在语法上稍有差异，但只需要修改一些解析方式，也能够得到自身看的懂、可以运行的命令。\n与物理复制的区别 逻辑复制的另外一个特点，是相对于另一种主流的数据同步方式：物理复制，来作为比较的。\n几乎所有的数据库内核，在进行数据存储的时候，都是采用随机写的方式，最大化利用性能优势，将数据存储在磁盘上。那么从物理上看，一个relation的所有数据，可能并不是连续的：他们可能分布在不同的page上，由指针进行连接。那么从磁盘角度看，一个page的分布，可能是这样的：\n-------------- Page Header -------------- Tuple 1 for r1 -------------- Tuple 2 for r1 -------------- Tuple 1 for r2 -------------- Tuple 1 for r3 -------------- Tuple 2 for r2 -------------- 如此一来，想要在物理层面进行数据传输时，以page为单位，是无法将不同relation的tuple分开的，也就是细粒度不够。\n逻辑复制的另一个特点，是可以以表为单位，进行数据同步，由一个Reader完成。\nReader逐行的去读取物理中的tuple，筛选那些符合要求的tuple，进行下一步工作。\n逻辑复制提高的数据同步的细粒度，可以在库、表、甚至行上进行数据过滤，显然是一种更灵活的同步方式，在某些场景下，其效果更好，常见的有：\n应用场景\n某数据库使用厂商需要进行版本升级，但升级前后版本由于迭代问题，在物理存储上存在差异，导致无法进行直接替换； 某数据库使用厂商需要将原有的数据库数据迁移到一款新的数据库产品上，而这两个数据库的内核架构完全不同，物理存储存在本质差异； 某厂商部门之间使用的数据库产品不同，但部门之间存在协作，需要进行数据传递； \u0026hellip; 架构 如图所示，逻辑复制功能，是两个实例（或生产者与消费者）之间完成的数据同步，通常我们把作为数据源端的实例，称为发布端（Publisher），而准备接收数据并进行回放的实例称为订阅端（Subscriber）。\n发布端 发布端的组成部分，共分为以下几个部分：WALReader、Decoder、Sender，通常是由三个独立的线程，按照其角色完成不同的工作：\nWALReader：主要完成对Xlog日志的读取，即从磁盘上将当前已罗盘的Xlog record读取到内存，并发送给Decoder； Decoder：解码线程，由于WALReader发送来的数据，是物理层面的记录，Decoder会按照特定的规则，将物理信息转换为逻辑信息，从内存上看，使用一个结构体，保存Xlog record中的xid、LSN、DMLType等信息。同时，Decoder还需要将这些信息，按照约定好的协议（Protocol）将数据进行打包，其中应用最广泛的端到端协议是pgoutput（后面会介绍他的协议格式以及细节实现）。Decoder会将这些按照协议进行拼接的逻辑数据存储到私有内存中，当达到一定条件时，将数据发送给Sender线程执行发送。 Sender：将Decoder发送来的数据通过网络发送给订阅端。 发布端如何保证事务一致性 对于数据同步来说，最重要的是事务一致性，如果不能保证一致性，那么逻辑复制将是毫无意义的。而要保证事务一致性，通常主要责任在于发布端，发布端需要确保自己发送逻辑信息的顺序，是严格的，即使不能保证发送顺序一定与WAL日志写入顺序完全一致，但必须保证事务的最终一致性。为了保证事务一致性，在发布端，通常会有以下几个部分保证：\n严格按照commit顺序进行事务发送：事务的提交顺序非常重要，Decoder解码到一条逻辑数据时，并不会立刻发送给Sender，而是将条变更存储起来，直到解码到该事务对应的commit，才将整个事务完发送； 错误重发：当订阅端接收到一个事务的commit时，即代表这个事务经传输完毕，订阅端会发送一个确认LSN给发布端，发布端需要确认LSN是在当前处理LSN的前面，如果此时LSN发生错乱，发布端会立即这条返回的LSN开始，重新发送这些变更； commit时间确认：在Decoder将Xlog信息解码为逻辑协议信息时对于某些类型的消息，会携带commit timestampz，这是该事务提时的瞬时时间戳； 发布端对于内存的管理 在业务系统中，有时不可避免的会出现大事务，通常包含几M甚至百M的事务变更数据，在逻辑复制模块中，上文提到，通常是将所有事务存储于内存，当遇到该事务的commit时，才进行发送。对于这种大事务来说，如果多几条，可能很容易造成内存压力，引起CPU抖动，有影响系统整体性能的可能性。\n为了保证系统整体性能，当遇到这种大事务的时候，通常会设计一个内存阈值，当在内存中已经存储了多条事务变更时，一旦当前内存占用达到阈值，发布端会选择当前内存中一个最大的事务（不一定是完整的，只是transaction size最大）spill to disk；诚然，这会带来一定的IO开销，因为当我们读到被spill的事务的commit时，需要把它从磁盘上读出来，但相比于其带来的内存负荷，这是合理的取舍。\n发布端的性能瓶颈 通过这个架构，我们不难看出一个性能瓶颈，那就是整个流程，都是串行完成的：\nWALReader在串行的读取Xlog； Decoder在串行的对Xlog record进行解码； Sender在串行的发送解码好的逻辑信息； 根据测试，在每秒大约100MB/s的Xlog写入负载下，单线程解码的速度只有～9MB/s，这对于一些使用逻辑复制的场景来说，是不可接受的，因为差异如此大的性能，如果在数据源端负载不停的情况下，数据同步端将永远没有追赶上的可能性，Lag会累积越来越大，最终将导致不得不停止业务负载，等待同步，这对于一些实时性要求高的业务来说是完全不可接受的。\n所以单线程解码的瓶颈，立即成为制约整个逻辑复制模块的关键点。\n发布端并行解码 由于单线程解码的性能无法满足使用要求，所以多线程并行解码，就成为一个解决问题的途径。\n并行解码的本质，是依靠Reader本身读取的快速性能（仅有Read操作，性能几乎完全取决于物理磁盘性能），快速的读取Xlog record，并将其传递给并行的解码线程。\n但是这里有一个关键的问题：我们应该如何进行分发？线程之间相互独立，彼此不可能知道对方的状态（除非使用线程间通信，然而这样并行的优势会被大大缩小），如果将事务变更随机发送，由于线程的调度问题，有的线程快，有的线程慢，那么保证事务一致性是一个非常困难的问题。或许增加一个收集（Collector）线程，来将所有的解码信息进行整合，并按照事务顺序进行重排序是一个方案，然而重排序的代价非常大，会十分影响高并发的性能。\n对于这个问题，OG使用的方式是对HASH XID，将所有相同XID事务变更都交给同一个线程处理，由此来保证事务内的相对顺序是严格的。而事务间的相对顺序，则交由单线程的Sender保证：当Deocder完成本事务的处理，发送给Sender后，Sender内部会按照commit的顺序，对事务进行排序，严格按照提交顺序发送，确保事务一致性。\n订阅端 在数据同步端，订阅端，基本是由两个部分组成：recieve与apply。\nreceive：负责接收发布端传输的逻辑信息（或心跳信息），发送相应的确认LSN与心跳reply，通常发布端发送的逻辑信息是一个batch，其中包含了一个事务的所有变更操作，receive负责将这写batch拆解为一个个独立的变更操作，并将这些独立的变更发送给apply。 apply：对receive发来的每条独立的变更进行回放，通常是Insert、Update、Delete操作，apply负责解析这些逻辑数据中的关键部分，例如：Insert信息中通常包含relation信息，new tuple信息等等，apply将这些信息重组为对应的内存变量，发送给heap_insert。 订阅端的性能瓶颈 从功能实现上看，事务一致性大多数是由发布端保证的，只要发布端\n","permalink":"https://my-blog.j8465383071.workers.dev/posts/database/logical_replication/","summary":"\u003ch2 id=\"基本概念\"\u003e基本概念\u003c/h2\u003e\n\u003cp\u003e逻辑复制是数据同步的一种方式，逻辑二字主要指的是传输数据的格式，与之相对的是物理复制。\u003c/p\u003e\n\u003ch3 id=\"逻辑数据格式\"\u003e逻辑数据格式\u003c/h3\u003e\n\u003cp\u003e逻辑数据格式是指，能够由一定规则描述的，符合SQL直觉的一种数据格式，例如：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"o\"\u003e[\u003c/span\u003eMsgType：Insert，Relation：test，New Tuple：\u003cspan class=\"o\"\u003e[\u003c/span\u003ea, int, 100\u003cspan class=\"o\"\u003e]]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e从这种数据格式上，能够通过解析等方式，将数据还原为SQL语句，这也同时表现了逻辑复制的第一个特点：\u003cstrong\u003e无视物理结构上的差异，可以在异构、跨版本的数据库之间进行数据同步\u003c/strong\u003e。\u003c/p\u003e\n\u003cp\u003e接上例，通过一定的解析步骤，我们总能够得到：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-sql\" data-lang=\"sql\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e\u003cspan class=\"k\"\u003eInsert\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003einto\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"n\"\u003etest\u003c/span\u003e\u003cspan class=\"p\"\u003e(\u003c/span\u003e\u003cspan class=\"n\"\u003ea\u003c/span\u003e\u003cspan class=\"p\"\u003e)\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"k\"\u003evalues\u003c/span\u003e\u003cspan class=\"w\"\u003e \u003c/span\u003e\u003cspan class=\"mi\"\u003e100\u003c/span\u003e\u003cspan class=\"p\"\u003e::\u003c/span\u003e\u003cspan class=\"nb\"\u003eint\u003c/span\u003e\u003cspan class=\"p\"\u003e;\u003c/span\u003e\u003cspan class=\"w\"\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e对于不同内核来说，可能在语法上稍有差异，但只需要修改一些解析方式，也能够得到自身看的懂、可以运行的命令。\u003c/p\u003e\n\u003ch3 id=\"与物理复制的区别\"\u003e与物理复制的区别\u003c/h3\u003e\n\u003cp\u003e逻辑复制的另外一个特点，是相对于另一种主流的数据同步方式：物理复制，来作为比较的。\u003c/p\u003e\n\u003cp\u003e几乎所有的数据库内核，在进行数据存储的时候，都是采用随机写的方式，最大化利用性能优势，将数据存储在磁盘上。那么从物理上看，一个relation的所有数据，可能并不是连续的：他们可能分布在不同的page上，由指针进行连接。那么从磁盘角度看，一个page的分布，可能是这样的：\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" class=\"chroma\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--------------\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003ePage Header\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--------------\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eTuple \u003cspan class=\"m\"\u003e1\u003c/span\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e r1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--------------\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eTuple \u003cspan class=\"m\"\u003e2\u003c/span\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e r1\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--------------\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eTuple \u003cspan class=\"m\"\u003e1\u003c/span\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e r2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--------------\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eTuple \u003cspan class=\"m\"\u003e1\u003c/span\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e r3\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--------------\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003eTuple \u003cspan class=\"m\"\u003e2\u003c/span\u003e \u003cspan class=\"k\"\u003efor\u003c/span\u003e r2\n\u003c/span\u003e\u003c/span\u003e\u003cspan class=\"line\"\u003e\u003cspan class=\"cl\"\u003e--------------\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003e如此一来，想要在物理层面进行数据传输时，以page为单位，是无法将不同relation的tuple分开的，也就是细粒度不够。\u003c/p\u003e\n\u003cp\u003e逻辑复制的另一个特点，是可以以表为单位，进行数据同步，由一个Reader完成。\u003c/p\u003e\n\u003cp\u003eReader逐行的去读取物理中的tuple，筛选那些符合要求的tuple，进行下一步工作。\u003c/p\u003e\n\u003cp\u003e逻辑复制提高的数据同步的细粒度，可以在库、表、甚至行上进行数据过滤，显然是一种更灵活的同步方式，在某些场景下，其效果更好，常见的有：\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u003cstrong\u003e应用场景\u003c/strong\u003e\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e某数据库使用厂商需要进行版本升级，但升级前后版本由于迭代问题，在物理存储上存在差异，导致无法进行直接替换；\u003c/li\u003e\n\u003cli\u003e某数据库使用厂商需要将原有的数据库数据迁移到一款新的数据库产品上，而这两个数据库的内核架构完全不同，物理存储存在本质差异；\u003c/li\u003e\n\u003cli\u003e某厂商部门之间使用的数据库产品不同，但部门之间存在协作，需要进行数据传递；\n\u0026hellip;\u003c/li\u003e\n\u003c/ol\u003e\u003c/blockquote\u003e\n\u003ch2 id=\"架构\"\u003e架构\u003c/h2\u003e\n\u003cp\u003e\u003cimg alt=\"alt text\" loading=\"lazy\" src=\"image.png\"\u003e\u003c/p\u003e\n\u003cp\u003e如图所示，逻辑复制功能，是两个实例（或生产者与消费者）之间完成的数据同步，通常我们把作为数据源端的实例，称为发布端（Publisher），而准备接收数据并进行回放的实例称为订阅端（Subscriber）。\u003c/p\u003e\n\u003ch3 id=\"发布端\"\u003e发布端\u003c/h3\u003e\n\u003cp\u003e发布端的组成部分，共分为以下几个部分：WALReader、Decoder、Sender，通常是由三个独立的线程，按照其角色完成不同的工作：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eWALReader：主要完成对Xlog日志的读取，即从磁盘上将当前已罗盘的Xlog record读取到内存，并发送给Decoder；\u003c/li\u003e\n\u003cli\u003eDecoder：解码线程，由于WALReader发送来的数据，是物理层面的记录，Decoder会按照特定的规则，将物理信息转换为逻辑信息，从内存上看，使用一个结构体，保存Xlog record中的xid、LSN、DMLType等信息。同时，Decoder还需要将这些信息，按照约定好的协议（Protocol）将数据进行打包，其中应用最广泛的端到端协议是pgoutput（后面会介绍他的协议格式以及细节实现）。Decoder会将这些按照协议进行拼接的逻辑数据存储到私有内存中，当达到一定条件时，将数据发送给Sender线程执行发送。\u003c/li\u003e\n\u003cli\u003eSender：将Decoder发送来的数据通过网络发送给订阅端。\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch4 id=\"发布端如何保证事务一致性\"\u003e发布端如何保证事务一致性\u003c/h4\u003e\n\u003cp\u003e对于数据同步来说，最重要的是事务一致性，如果不能保证一致性，那么逻辑复制将是毫无意义的。而要保证事务一致性，通常主要责任在于发布端，发布端需要确保自己发送逻辑信息的顺序，是严格的，即使不能保证发送顺序一定与WAL日志写入顺序完全一致，但必须保证事务的最终一致性。为了保证事务一致性，在发布端，通常会有以下几个部分保证：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e严格按照commit顺序进行事务发送：事务的提交顺序非常重要，Decoder解码到一条逻辑数据时，并不会立刻发送给Sender，而是将条变更存储起来，直到解码到该事务对应的commit，才将整个事务完发送；\u003c/li\u003e\n\u003cli\u003e错误重发：当订阅端接收到一个事务的commit时，即代表这个事务经传输完毕，订阅端会发送一个确认LSN给发布端，发布端需要确认LSN是在当前处理LSN的前面，如果此时LSN发生错乱，发布端会立即这条返回的LSN开始，重新发送这些变更；\u003c/li\u003e\n\u003cli\u003ecommit时间确认：在Decoder将Xlog信息解码为逻辑协议信息时对于某些类型的消息，会携带commit timestampz，这是该事务提时的瞬时时间戳；\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch4 id=\"发布端对于内存的管理\"\u003e发布端对于内存的管理\u003c/h4\u003e\n\u003cp\u003e在业务系统中，有时不可避免的会出现大事务，通常包含几M甚至百M的事务变更数据，在逻辑复制模块中，上文提到，通常是将所有事务存储于内存，当遇到该事务的commit时，才进行发送。对于这种大事务来说，如果多几条，可能很容易造成内存压力，引起CPU抖动，有影响系统整体性能的可能性。\u003c/p\u003e\n\u003cp\u003e为了保证系统整体性能，当遇到这种大事务的时候，通常会设计一个内存阈值，当在内存中已经存储了多条事务变更时，一旦当前内存占用达到阈值，发布端会选择当前内存中一个最大的事务（不一定是完整的，只是transaction size最大）spill to disk；诚然，这会带来一定的IO开销，因为当我们读到被spill的事务的commit时，需要把它从磁盘上读出来，但相比于其带来的内存负荷，这是合理的取舍。\u003c/p\u003e","title":"逻辑复制"},{"content":"1. 关于我 作者：Jia Xuhui 年龄：97年出生，2027年就满20了 专业：计算机 职业：数据库内核开发 现居：成都 微信：easymoneysniper（注明来源） 经历： 时间\t经历\t内容 2016-2020\t南京理工大学\t能源与动力工程学院 2021-2024\t成都信息工程大学\t计算机科学与技术 2024-2025 虚谷伟业 数据库内核开发 2025- 海量数据 数据库内核开发\n2. 博客 博客记录的内容：主要有3类：\n计算机基础 数据库内核 杂谈 好文心得、记录 写博客的目的，主要有2个：\n学习笔记：我发现我的记忆，在面对复杂问题的时候，会很不够用，所以要记录，万一别人问起我来，我做过的东西答不上来，很尴尬，也表示没有掌握。\n知识分享：其实也不算分享，因为不一定对所有的人都有价值，可能只是我觉得对我个人比较有价值\n读博客的时候，需要注意3个问题：、\n正确性：很多内容，按我的理解写的，可能有误，欢迎指正（我自己也会写完问一下ai有没有常识性错误，然而深层次的，不好说） 完整性：由于工作需求，不一定会连续的处理一个模块的问题，可能东跳西跳的； 美观性：页面美观，完全是ai写的，我描述我想要的，他来完成，可能会有显示bug 3. 博客相关 框架：hugo\n主题：papermod\nai：gemini 3 pro（挺好用，而且免费）\n目前还在逐渐完善中，在Cloudflare上部署起来了，或许每个人都可以看到了\n","permalink":"https://my-blog.j8465383071.workers.dev/about/","summary":"\u003ch2 id=\"1-关于我\"\u003e1. 关于我\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e作者：Jia Xuhui\u003c/li\u003e\n\u003cli\u003e年龄：97年出生，2027年就满20了\u003c/li\u003e\n\u003cli\u003e专业：计算机\u003c/li\u003e\n\u003cli\u003e职业：数据库内核开发\u003c/li\u003e\n\u003cli\u003e现居：成都\u003c/li\u003e\n\u003cli\u003e微信：easymoneysniper（注明来源）\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e经历：\n时间\t经历\t内容\n2016-2020\t南京理工大学\t能源与动力工程学院\n2021-2024\t成都信息工程大学\t计算机科学与技术\n2024-2025   虚谷伟业        数据库内核开发\n2025-       海量数据        数据库内核开发\u003c/p\u003e\n\u003ch2 id=\"2-博客\"\u003e2. 博客\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e博客记录的内容：主要有3类：\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e计算机基础\u003c/li\u003e\n\u003cli\u003e数据库内核\u003c/li\u003e\n\u003cli\u003e杂谈\u003c/li\u003e\n\u003cli\u003e好文心得、记录\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e写博客的目的，主要有2个：\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e学习笔记：我发现我的记忆，在面对复杂问题的时候，会很不够用，所以要记录，万一别人问起我来，我做过的东西答不上来，很尴尬，也表示没有掌握。\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e知识分享：其实也不算分享，因为不一定对所有的人都有价值，可能只是我觉得对我个人比较有价值\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e读博客的时候，需要注意3个问题：、\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e正确性：很多内容，按我的理解写的，可能有误，欢迎指正（我自己也会写完问一下ai有没有常识性错误，然而深层次的，不好说）\u003c/li\u003e\n\u003cli\u003e完整性：由于工作需求，不一定会连续的处理一个模块的问题，可能东跳西跳的；\u003c/li\u003e\n\u003cli\u003e美观性：页面美观，完全是ai写的，我描述我想要的，他来完成，可能会有显示bug\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"3-博客相关\"\u003e3. 博客相关\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e框架：hugo\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e主题：papermod\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eai：gemini 3 pro（挺好用，而且免费）\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e目前还在逐渐完善中，在Cloudflare上部署起来了，或许每个人都可以看到了\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e","title":"0.AboutMe"},{"content":"关于 把这里当成第一步，开始积累自己的东西，当有一天面对外部变化，能够从从容容、游刃有余。\n我是贾旭辉，我希望能够养成良好的习惯，开始随手记录一些工作中、生活中积累到的东西。\n种下一棵树最好的时间是十年前，其次就是现在了。\n-- 2026.02.10 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/readme/","summary":"\u003ch1 id=\"关于\"\u003e关于\u003c/h1\u003e\n\u003cp\u003e把这里当成第一步，开始积累自己的东西，当有一天面对外部变化，能够从从容容、游刃有余。\u003c/p\u003e\n\u003cp\u003e我是贾旭辉，我希望能够养成良好的习惯，开始随手记录一些工作中、生活中积累到的东西。\u003c/p\u003e\n\u003cp\u003e种下一棵树最好的时间是十年前，其次就是现在了。\u003c/p\u003e\n\u003cpre\u003e\u003ccode\u003e                                -- 2026.02.10\n\u003c/code\u003e\u003c/pre\u003e","title":"0.Readme"},{"content":"概述 1.1 机密计算 1.2 可信执行环境 ","permalink":"https://my-blog.j8465383071.workers.dev/posts/projectdocs/0-confidential-computing/","summary":"\u003ch1 id=\"概述\"\u003e概述\u003c/h1\u003e\n\u003ch2 id=\"11-机密计算\"\u003e1.1 机密计算\u003c/h2\u003e\n\u003ch2 id=\"12-可信执行环境\"\u003e1.2 可信执行环境\u003c/h2\u003e","title":"海量 0 机密计算"}]