<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>设计文档 on Kernel Notes</title><link>https://my-blog.j8465383071.workers.dev/tags/%E8%AE%BE%E8%AE%A1%E6%96%87%E6%A1%A3/</link><description>Recent content in 设计文档 on Kernel Notes</description><generator>Hugo -- 0.147.7</generator><language>zh-cn</language><lastBuildDate>Mon, 07 Sep 2026 15:30:00 +0800</lastBuildDate><atom:link href="https://my-blog.j8465383071.workers.dev/tags/%E8%AE%BE%E8%AE%A1%E6%96%87%E6%A1%A3/index.xml" rel="self" type="application/rss+xml"/><item><title>海量 1 设计 oracle加密函数</title><link>https://my-blog.j8465383071.workers.dev/posts/projectdocs/1-design-oracle-crypto-func/</link><pubDate>Tue, 25 Feb 2025 09:49:00 +0800</pubDate><guid>https://my-blog.j8465383071.workers.dev/posts/projectdocs/1-design-oracle-crypto-func/</guid><description>&lt;h1 id="1">1&lt;/h1>
&lt;ol>
&lt;li>
&lt;p>设置默认版本&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">contrib/pgcrypto/pgcrypto.control
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">defaultl_version&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;2.0&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">dbcompatibilities&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="s1">&amp;#39;A, B, PG&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>生成同名的sql文件&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">touch contrib/pgcrypto/pgcrypto-2.0.sql
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>安装sql文件&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># pgcrypto.control与pgcrypt.*.sql文件&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ll &lt;span class="nv">$GAUSSHOME&lt;/span>/share/postgresql/extension &lt;span class="p">|&lt;/span> grep pgcrypto
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>加载插件&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 执行：CREATE EXTENSION pgcrypto&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">..&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">CreateExtension&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">check_valild_extension_name&lt;/span> &lt;span class="c1"># 检查插件名：要求不含 &amp;#39;-&amp;#39;、不含&amp;#39;..&amp;#39;等路径字符&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">get_extension_oid&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">heap_open&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;pg_extension&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">systable_beginscan&lt;/span> &lt;span class="c1"># 遍历系统表 pg_extension：确保插件存在&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">read_extension_control_file&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">parse_extension_control_file&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">get_extension_control_filename&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sprintf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="si">{share}&lt;/span>&lt;span class="s2">/extension/&lt;/span>&lt;span class="si">{extension_name}&lt;/span>&lt;span class="s2">.control&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ParreConfigFp&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 获取 directory, default_version, module_pathname, dbcompatibilities 等参数&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">get_extension_script_filename&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">get_extension_script_direcotry&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">name&lt;/span> &lt;span class="ow">is&lt;/span> &lt;span class="s1">&amp;#39;pgcrypto&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">sprintf&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;&lt;/span>&lt;span class="si">{script_dir}&lt;/span>&lt;span class="s2">/crypto-a.sql&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">read_extension_script_file&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">InsertExtensionTuple&lt;/span> &lt;span class="c1"># 插入系统表 pg_extension&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">execute_extension_script&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ApplyExtensionUpdates&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ol></description></item><item><title>海量 2 设计 profile</title><link>https://my-blog.j8465383071.workers.dev/posts/projectdocs/2-design-profile/</link><pubDate>Thu, 06 Mar 2025 11:32:00 +0800</pubDate><guid>https://my-blog.j8465383071.workers.dev/posts/projectdocs/2-design-profile/</guid><description>&lt;h1 id="1-oracle兼容性-支持profile功能">1 Oracle兼容性-支持profile功能&lt;/h1>
&lt;h2 id="11-功能简述">1.1 功能简述&lt;/h2>
&lt;p>本特性实现与oracle profile相同的功能，支持为不同用户设置7个不同的配置参数：&lt;/p>
&lt;ol>
&lt;li>failed_login_attempts&lt;/li>
&lt;li>password_lock_time&lt;/li>
&lt;li>password_life_time&lt;/li>
&lt;li>password_grace_time&lt;/li>
&lt;li>password_reuse_time&lt;/li>
&lt;li>password_reuse_max&lt;/li>
&lt;li>idle_time&lt;/li>
&lt;/ol>
&lt;p>简单使用示例如下：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sql" data-lang="sql">&lt;span class="line">&lt;span class="cl">&lt;span class="k">CREATE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">PROFILE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">pro1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">LIMIT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">failed_login_attempts&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">10&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">CREATE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">USER&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">u1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">PASSWORD&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;u1.pass1&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">ALTER&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">USER&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">u1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">PROFILE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">u1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="12-实现方案">1.2 实现方案&lt;/h2>
&lt;h3 id="一元数据">一、元数据&lt;/h3>
&lt;p>本特性的关键实现为：对用户提供DDL接口，在内核中存储配置数据。因此，在介绍代码流程前，先介绍接口与元数据。&lt;/p>
&lt;ol>
&lt;li>
&lt;p>新增GUC参数resource_limit (与oracle参数名一致)&lt;br>
控制是否启用oracle profile功能。&lt;br>
如果该参数为on，以下5个guc参数则不再生效：[failed_login_attempts, password_lock_time, password_effect_time, password_reuse_time, password_reuse_max]。另外，对于已经过身份认证的连接，session_timeout也不再生效，相关功能均由profile中的用户级参数控制。&lt;br>
对于新安装的集群、旧版本升级的集群，该参数的值存在差异：&lt;/p>
&lt;ul>
&lt;li>
&lt;p>新安装：新安装的数据库，即3.0.8版本及之后，该guc参数值默认为on（初始值为off，由initdb自动设置为on）&lt;/p>
&lt;/li>
&lt;li>
&lt;p>升级：从3.0.8之前版本，升级到3.0.8版本时，在升级的过程中，该参数的值仍然是off，即升级上来默认不可用profile功能&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sql" data-lang="sql">&lt;span class="line">&lt;span class="cl">&lt;span class="k">SELECT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">pg_settings&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">WHERE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">name&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;resource_limit&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">RECORD&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">]&lt;/span>&lt;span class="c1">-------------------------------------------
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">name&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">resource_limit&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">setting&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">on&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">-- 默认为on （由initdb设置为on，从旧版本升级到新版本时，升级脚本会将该参数设置为off）
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">unit&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">category&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Ungrouped&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">short_desc&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">Used&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">to&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">enable&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">profile&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">feature&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">extra_desc&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">default&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">on&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">context&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">postmaster&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="c1">-- 需重启生效
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">vartype&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">bool&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">source&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">default&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">min_val&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">max_val&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">enumvals&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">boot_val&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">off&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">reset_val&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">off&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">sourcefile&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="n">sourceline&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>修改6个GUC参数的生效条件&lt;br>
当GUC参数resource_limit取值为on时，以下6个GUC参数不再生效：[failed_login_attempts, password_lock_time, password_effect_time, password_reuse_time, password_reuse_max, session_timeout]&lt;/p></description></item><item><title>海量 2 设计 oracle profile</title><link>https://my-blog.j8465383071.workers.dev/posts/projectdocs/2-design-profile-oracle/</link><pubDate>Thu, 20 Feb 2025 19:24:00 +0800</pubDate><guid>https://my-blog.j8465383071.workers.dev/posts/projectdocs/2-design-profile-oracle/</guid><description>&lt;h1 id="2">2&lt;/h1>
&lt;p>代码&lt;br>
新增试图&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sql" data-lang="sql">&lt;span class="line">&lt;span class="cl">&lt;span class="k">SELECT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">pg_user_settings&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="c1">-- 新增视图 pg_user_settings
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">SELECT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">rolname&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">profile&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">pg_authid&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">WHERE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">rolcanlogin&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">true&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="k">LEFT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">JOIN&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">vb_profile&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">ON&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="n">rolname&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">setname&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">setting&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">settype&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">settype&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">setsource&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="c1">--------+-----------------------+----------+---------+-------------+----------------
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">u1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">password_effect_time&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="mi">90&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">int&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">profile&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">guc&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">pro1&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">cluster&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">guc&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">|&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">postgresql&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">conf&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="参数1-failed_login_attempts">参数1: failed_login_attempts&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># opegauss使用1个内存中的hash表，存储密码失败次数&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">ClientAuthentication&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 进行身份认证时，如果认证失败，则更新hash表中的失败次数值&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">UpdateFailCountToHashTable&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">InitAccountLockHashTable&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">hash_search&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 如果失败次数超过GUC限制，则锁定账户&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">failed_login_attempts&lt;/span>&lt;span class="err">：&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">lockflag&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kc">True&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="参数2-password_lock_time">参数2: password_lock_time&lt;/h4>
&lt;h4 id="参数3-password_effect_time">参数3: password_effect_time&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 通过内置函数，主动查看密码剩余天数&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">gs_password_deadline&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">GetCurrentUserId&lt;/span> &lt;span class="c1"># 1 获取当前用户&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">GetUserCurrentPwdtime&lt;/span> &lt;span class="c1"># 2 从系统表pg_auth_history中，获取密码创建时间passwordtime&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">heap_open&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;pg_auth_history&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">systable_beginscan&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">floor&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">u_sess&lt;/span>&lt;span class="o">-&amp;gt;&lt;/span>&lt;span class="n">attr&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">attr_security&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">Password_effect_time&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1"># 3 从guc参数password_effect_time中获取密码有效天数&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 计算步骤2和3中的时间，返回剩余过期天数&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="参数4-password_reuse_max">参数4: password_reuse_max&lt;/h4>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">AddAuthHistory&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">systable_beginscan&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;pg_auth_history&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="c1"># 1 从系统表pg_auth_history中，获取曾用过的密码rolpassword，获取生成密码的时间passwordtime&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">systable_getnext_back&lt;/span> &lt;span class="c1"># 倒着从系统表扫描，即先扫描不太古老的旧密码，再扫描更古老的旧密码&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">pg_sha256_encrypt&lt;/span> &lt;span class="c1"># 使用旧密码的salt，加密新密码&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">strncmp&lt;/span> &lt;span class="p">:&lt;/span> &lt;span class="c1"># 比较新密码是否与旧密码相等&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">hasSame&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kc">True&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 如果新旧密码相等，计算新旧密码间隔天数，与GUC参数password_reuse_time比较，判断是否满足密码重用时间限制&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">now&lt;/span> &lt;span class="o">-&lt;/span> &lt;span class="n">pg_auth_history&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">passwordtime&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;password_reuse_time&amp;#39;&lt;/span>&lt;span class="err">：&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">isTimeSafe&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kc">True&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 计算这是倒数第几个密码&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">changeTimes&lt;/span>&lt;span class="o">++&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">changeTimes&lt;/span> &lt;span class="o">&amp;gt;&lt;/span> &lt;span class="s1">&amp;#39;password_reuse_max&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">isMaxSafe&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 满足 password_reuse_time 和 password_reuse_max 中任意一个条件，都可以修改密码&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># - 要么用好几次之前的密码（满足 password_reuse_max 条件）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># - 要么用很旧之间使用的密码（满足 password_reuse_time 条件）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">if&lt;/span> &lt;span class="n">hasSame&lt;/span> &lt;span class="ow">and&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="n">isTimeSafe&lt;/span> &lt;span class="ow">and&lt;/span> &lt;span class="ow">not&lt;/span> &lt;span class="n">isMaxSafe&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 报错&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="参数5-password_reuse_time">参数5: password_reuse_time&lt;/h4></description></item><item><title>海量 5 设计 G100审计</title><link>https://my-blog.j8465383071.workers.dev/posts/projectdocs/5-design-g100-audit-refactor/</link><pubDate>Mon, 01 Sep 2025 18:00:00 +0800</pubDate><guid>https://my-blog.j8465383071.workers.dev/posts/projectdocs/5-design-g100-audit-refactor/</guid><description>&lt;h1 id="g100审计功能重构">G100审计功能重构&lt;/h1>
&lt;h1 id="1-功能简述">1 功能简述&lt;/h1>
&lt;p>在需求文档中，已详细介绍需求背景，此处不在重复介绍。&lt;br>
G100 309之前版本，审计特性存在较多问题，因此，在本版本，将重新设计与实现审计特性，解决功能、性能、易用性、可维护性、可扩展性等问题，使审计特性达到大规模商用的标准。&lt;/p>
&lt;h1 id="2-实现方案">2 实现方案&lt;/h1>
&lt;h2 id="一审计架构">一、审计架构&lt;/h2>
&lt;p>审计特性，核心子功能如下：&lt;/p>
&lt;ol>
&lt;li>配置审计：通过GUC参数，配置审计参数：日志目录、目录大小、日志文件淘汰策略等&lt;/li>
&lt;li>设置范围：通过SQL语法，设置审计策略，控制哪些事件需审计。在策略中，可按用户、操作、对象、操作结果等过滤事件&lt;/li>
&lt;li>收集事件：在代码关键节点，收集事件&lt;/li>
&lt;li>过滤事件：根据审计策略，过滤无需审计的事件&lt;/li>
&lt;li>生成日志：提取事件关键信息，生成日志&lt;/li>
&lt;li>传输日志：工作线程，通过共享内存，传输日志给审计线程&lt;/li>
&lt;li>存储日志：审计线程，组织日志，并将其存储至文件中。文件存放在单独的日志目录&lt;/li>
&lt;li>查询日志：通过内置FUNCTION，在线查询日志，通过TOOL，离线查询日志&lt;/li>
&lt;/ol>
&lt;blockquote>
&lt;p>&lt;strong>其中，设置范围、过滤事件子功能相对独立，可单独设计与实现，所以，拆分到另一个的设计文档中。&lt;/strong>&lt;/p>&lt;/blockquote>
&lt;p>审计特性整体架构图如下：&lt;/p>
&lt;p>&lt;img alt="1-st" loading="lazy" src="https://my-blog.j8465383071.workers.dev/images/ProjectDocs/5-design-g100-audit-refactor/1-st.png">&lt;/p>
&lt;h2 id="二工作流程">二、工作流程&lt;/h2>
&lt;p>收集事件的主体、操作、客体等信息时，因为需收集操作结果，即操作成功或失败，所以，很多场景中，收集事件需分为2个阶段：&lt;/p>
&lt;ul>
&lt;li>执行操作前：收集事件基本信息，包括操作类型等&lt;/li>
&lt;li>执行操作后：收集事件的操作结果。对于出现ERROR的场景，则在异常处理函数中收集操作结果。&lt;/li>
&lt;/ul>
&lt;p>在所有事件中，DML语句的事件稍复杂一点，此处主要以该类语句为例，梳理整体执行流程：&lt;/p>
&lt;p>&lt;img alt="2-fl" loading="lazy" src="https://my-blog.j8465383071.workers.dev/images/ProjectDocs/5-design-g100-audit-refactor/2-fl.png">&lt;/p>
&lt;h2 id="三详细流程">三、详细流程&lt;/h2>
&lt;h3 id="阶段1-配置审计进程启动">阶段1 配置审计（进程启动）&lt;/h3>
&lt;p>首先，用户通过GUC参数，配置审计文件管理等功能。然后，在系统启动阶段，审计模块将根据配置，初始化的各类关键资源，包括：&lt;/p>
&lt;ol>
&lt;li>日志文件：日志存储目录，初始日志文件等&lt;/li>
&lt;li>审计内存：日志缓存区，内存上下文等&lt;/li>
&lt;li>审计线程：信号处理函数等&lt;/li>
&lt;li>事件收集节点：hook函数注册等&lt;/li>
&lt;/ol>
&lt;p>详细启动过程如下：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">main&lt;/span> &lt;span class="c1"># 1. 启动vastbase进程&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">knl_instance_init&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">MemoryContextInit&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">PostmasterMain&lt;/span> &lt;span class="c1"># 2. 启动postmaster线程&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">SelectConfigFiles&lt;/span> &lt;span class="c1"># 3. 加载GUC参数&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">checkDataDir&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;audit_dir_init&amp;#39;&lt;/span> &lt;span class="c1"># 4. 创建审计日志文件目录&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;audit_hook_init&amp;#39;&lt;/span> &lt;span class="c1"># 5. 注册审计回调函数：身份认证等&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">load_hba&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">reset_shared&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">CreateSharedMemoryAndSemaphores&lt;/span> &lt;span class="c1"># （日志缓冲区不是共享内存，后文阶段6详细介绍）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">GlobalSysDBCache&lt;/span>&lt;span class="p">::&lt;/span>&lt;span class="n">Init&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">CreateLocalSysDBCache&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">InitRoleIdHashTable&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;audit_comm_init&amp;#39;&lt;/span> &lt;span class="c1"># 6. 初始化审计内存上下文、日志缓存区，创建审计日志文件&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;initialize_util_thread(AUDIT_WRITER)&amp;#39;&lt;/span> &lt;span class="c1"># 7. 启动audit-writer 线程，持续读取日志缓冲区，等待接收与存储日志&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">initialize_thread&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">..&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># ===== audit-writer 线程 ==============&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">GaussDbThreadMain&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">InitShmemAccess&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">InitAuxiliaryProcess&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">CreateSharedMemoryAndSemaphores&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">GaussDBAuxiliaryThreadMain&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">BaseInit&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;adt_writer_main&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># ===== audit-writer 线程 ==============&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ServerLoop&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="p">(;;)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">comm_select&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ConnCreate&lt;/span> &lt;span class="c1"># 9. 接收客户端连接&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">BackendStartup&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">initialize_util_thread&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">WORKER&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">initialize_thread&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">..&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># ===== postgres 线程 ==============&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">GaussDbThreadMain&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">knl_thread_init&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">InitializeGUCOptions&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">CreateLocalSysDBCache&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;audit_hook_init&amp;#39;&lt;/span> &lt;span class="c1"># 10. 注册事件收集回调函数：计划执行、函数执行等回调点&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">BackendInitialize&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">BackendRun&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">PostgresMain&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># ===== postgres 线程 ==============&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;initialize_util_thread(AUDIT_WRITER)&amp;#39;&lt;/span> &lt;span class="c1"># 11. 检查audit-writer 线程状态与自动重启&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="阶段2-设置范围">阶段2 设置范围&lt;/h3>
&lt;p>向用户提供SQL接口，用于创建审计策略。（见另一个设计文档）&lt;/p></description></item><item><title>海量 5 方案 G100审计重构</title><link>https://my-blog.j8465383071.workers.dev/posts/projectdocs/5-solution-g100-audit-refactor/</link><pubDate>Wed, 23 Apr 2025 18:00:00 +0800</pubDate><guid>https://my-blog.j8465383071.workers.dev/posts/projectdocs/5-solution-g100-audit-refactor/</guid><description>&lt;ol>
&lt;li>&lt;a href="#1-%E5%AE%A1%E8%AE%A1%E7%89%B9%E6%80%A7%E4%BB%8B%E7%BB%8D">1 审计特性介绍&lt;/a>
&lt;ol>
&lt;li>&lt;a href="#1-1-%E6%A0%B8%E5%BF%83%E5%8A%9F%E8%83%BD">1.1 核心功能&lt;/a>&lt;/li>
&lt;li>&lt;a href="#1-2-%E6%95%B4%E4%BD%93%E6%9E%B6%E6%9E%84%EF%BC%88308-3%EF%BC%89">1.2 整体架构（308.3）&lt;/a>&lt;/li>
&lt;li>&lt;a href="#1-3-%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B%EF%BC%88308-3%EF%BC%89">1.3 工作流程（308.3）&lt;/a>&lt;/li>
&lt;li>&lt;a href="#1-4-%E6%96%87%E4%BB%B6%E7%BB%84%E7%BB%87">1.4 文件组织&lt;/a>&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>&lt;a href="#2-%E4%BD%BF%E7%94%A8%E5%AE%A1%E8%AE%A1%E7%89%B9%E6%80%A7">2 使用审计特性&lt;/a>
&lt;ol>
&lt;li>&lt;a href="#2-1-%E9%85%8D%E7%BD%AE%E5%AE%A1%E8%AE%A1%E7%89%B9%E6%80%A7">2.1 配置审计特性&lt;/a>&lt;/li>
&lt;li>&lt;a href="#2-2-%E5%90%AF%E5%8A%A8%E6%95%B0%E6%8D%AE%E5%BA%93">2.2 启动数据库&lt;/a>&lt;/li>
&lt;li>&lt;a href="#2-3-%E7%94%9F%E6%88%90%E5%AE%A1%E8%AE%A1%E6%97%A5%E5%BF%97">2.3 生成审计日志&lt;/a>&lt;/li>
&lt;li>&lt;a href="#2-4-%E6%9F%A5%E8%AF%A2%E5%AE%A1%E8%AE%A1%E6%97%A5%E5%BF%97">2.4 查询审计日志&lt;/a>&lt;/li>
&lt;li>&lt;a href="#2-5-%E5%BC%82%E5%B8%B8%E7%AE%A1%E7%90%86">2.5 异常管理&lt;/a>&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>&lt;a href="#3-%E5%AE%A1%E8%AE%A1%E7%89%B9%E6%80%A7%E5%8F%98%E6%9B%B4%E7%82%B9">3 审计特性变更点&lt;/a>
&lt;ol>
&lt;li>&lt;a href="#3-1-%E9%97%AE%E9%A2%98%E5%88%86%E6%9E%90">3.1 问题分析&lt;/a>&lt;/li>
&lt;li>&lt;a href="#2-2-%E9%87%8D%E6%9E%84%E7%9B%AE%E6%A0%87">2.2 重构目标&lt;/a>&lt;/li>
&lt;li>&lt;a 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">2.3 问题分析（当前版本）&lt;/a>
&lt;ol>
&lt;li>&lt;a href="#%E4%B8%80%E3%80%81%E5%AD%98%E5%82%A8%E6%97%A5%E5%BF%97%E6%85%A2">一、存储日志慢&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%E4%BA%8C%E3%80%81%E6%A3%80%E7%B4%A2%E6%97%A5%E5%BF%97%E6%85%A2">二、检索日志慢&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%E4%B8%89%E3%80%81%E6%96%87%E4%BB%B6%E9%97%AE%E9%A2%98%E5%A4%9A">三、文件问题多&lt;/a>&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>&lt;a href="#2-4-%E9%87%8D%E6%9E%84%E6%96%B9%E6%A1%88">2.4 重构方案&lt;/a>
&lt;ol>
&lt;li>&lt;a 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">一、存储日志重构&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%E4%BA%8C%E3%80%81%E6%A3%80%E7%B4%A2%E6%97%A5%E5%BF%97">二、检索日志&lt;/a>&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>&lt;a href="#2-5-%E9%87%8D%E6%9E%84%E5%BC%80%E9%94%80">2.5 重构开销&lt;/a>&lt;/li>
&lt;li>&lt;a href="#2-6-%E9%87%8D%E6%9E%84%E5%BD%B1%E5%93%8D">2.6 重构影响&lt;/a>&lt;/li>
&lt;li>&lt;a href="#2-7-%E6%80%A7%E8%83%BD%E6%B5%8B%E8%AF%95">2.7 性能测试&lt;/a>&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>&lt;a 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">3 审计特性详细设计&lt;/a>
&lt;ol>
&lt;li>&lt;a href="#3-1-%E6%9E%B6%E6%9E%84%E8%AE%BE%E8%AE%A1">3.1 架构设计&lt;/a>
&lt;ol>
&lt;li>&lt;a href="#%E4%B8%80%E3%80%81%E6%95%B4%E4%BD%93%E6%9E%B6%E6%9E%84">一、整体架构&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%E4%BA%8C%E3%80%81%E5%B7%A5%E4%BD%9C%E6%B5%81%E7%A8%8B">二、工作流程&lt;/a>&lt;/li>
&lt;li>&lt;a href="#%E4%B8%89%E3%80%81%E6%96%87%E4%BB%B6%E7%BB%84%E7%BB%87">三、文件组织&lt;/a>&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>&lt;a href="#3-2-%E8%AF%A6%E7%BB%86%E8%AE%BE%E8%AE%A1">3.2 详细设计&lt;/a>
&lt;ol>
&lt;li>&lt;a 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">一、配置审计特性&lt;/a>&lt;/li>
&lt;li>&lt;a 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">二、审计文件管理&lt;/a>&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>&lt;a href="#%E4%B8%89%E3%80%81-%E5%90%AF%E5%8A%A8%E6%95%B0%E6%8D%AE%E5%BA%93">三、 启动数据库&lt;/a>&lt;/li>
&lt;li>&lt;a 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">四、生成审计日志&lt;/a>&lt;/li>
&lt;li>&lt;a 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">五、存储审计日志&lt;/a>&lt;/li>
&lt;li>&lt;a 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">六、审计日志一致性&lt;/a>&lt;/li>
&lt;li>&lt;a 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">七、归并审计日志&lt;/a>&lt;/li>
&lt;li>&lt;a 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">八、查询审计日志&lt;/a>&lt;/li>
&lt;/ol>
&lt;/li>
&lt;li>&lt;a 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">4 审计后续重构计划&lt;/a>&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>摘要&lt;/strong>&lt;/p>
&lt;blockquote>
&lt;p>介绍审计特性，分析性能问题，提出优化方案，评审优化方案，规划其他计划&lt;/p>&lt;/blockquote>
&lt;h1 id="1-审计特性介绍">1 审计特性介绍&lt;/h1>
&lt;h2 id="11-核心功能">1.1 核心功能&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>审计特性：记录数据库内的各种事件，事件包括：&lt;/p></description></item><item><title>海量 6 设计 greenplum</title><link>https://my-blog.j8465383071.workers.dev/posts/projectdocs/6-design-greenplum/</link><pubDate>Thu, 15 May 2025 16:36:00 +0800</pubDate><guid>https://my-blog.j8465383071.workers.dev/posts/projectdocs/6-design-greenplum/</guid><description>&lt;h1 id="1-需求分析">1 需求分析&lt;/h1>
&lt;ol>
&lt;li>透明加密
&lt;ul>
&lt;li>主密钥&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>动态脱敏
&lt;ul>
&lt;li>和统一审计共用resource lable模块&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>全密态
&lt;ul>
&lt;li>密态等值&lt;/li>
&lt;li>密态非等值
&lt;ul>
&lt;li>范围查询：OPE保序加密&lt;/li>
&lt;li>模糊查询&lt;/li>
&lt;li>内置函数&lt;/li>
&lt;li>排序&lt;/li>
&lt;li>..&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>防篡改
&lt;ul>
&lt;li>分布式：有点麻烦，区块链记录在每个节点上&lt;/li>
&lt;li>哈希函数：md5&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ol>
&lt;h2 id="11-透明加密">1.1 透明加密&lt;/h2>
&lt;ul>
&lt;li>模块分析
&lt;ul>
&lt;li>密钥管理
&lt;ul>
&lt;li>设置主密钥&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>定义加密属性
&lt;ul>
&lt;li>表：普通表、临时表、分区表、toast表&lt;/li>
&lt;li>索引&lt;/li>
&lt;li>xlog&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>加密数据
&lt;ul>
&lt;li>加密算法：aes-256-ctr, sm4-ctr&lt;/li>
&lt;li>备机加密&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sql" data-lang="sql">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">-- 创建主密钥
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="c1">-- 设置表加密
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">CREATE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">TABLE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">t1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">c1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">INT&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">c2&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">TEXT&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">WITH&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">enable_tde&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="k">on&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="c1">-- 验证数据加密存储
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">INSERT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">INTO&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">t1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">VALUES&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">1&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;bbbcccddd&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="12-动态脱敏">1.2 动态脱敏&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sql" data-lang="sql">&lt;span class="line">&lt;span class="cl">&lt;span class="c1">-- 开启脱敏功能
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="n">gs_guc&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">reload&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">D&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="err">$&lt;/span>&lt;span class="n">GAUSSHOME&lt;/span>&lt;span class="o">/&lt;/span>&lt;span class="k">data&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="k">c&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;enable_security_policy=on&amp;#34;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="c1">-- 创建表
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">CREATE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">TABLE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">t1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">c1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">TEXT&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">c2&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">TEXT&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">INSERT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">INTO&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">t1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">VALUES&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;bbccdd&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;bbccdd&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="c1">-- 创建用户
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">CREATE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">USER&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">u1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">PASSWORD&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;u1.password&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">CREATE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">USER&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">u2&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">PASSWORD&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;u2.password&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">GRANT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">SELECT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">ON&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">t1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">TO&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">u1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">GRANT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">SELECT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">ON&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">t1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">TO&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">u2&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="c1">-- 创建资源标签（只对u1脱敏）
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">CREATE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">RESOURCE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">LABEL&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">l1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">ADD&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">COLUMN&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">t1&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="n">c1&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">CREATE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">MASKING&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">POLICY&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">m1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">randommasking&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">ON&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">LABEL&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">l1&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">FILTER&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">ON&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">ROLES&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">u1&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="c1">-- 验证脱敏：只有u1脱敏
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">SET&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">ROLE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">u1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">PASSWORD&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;u1.password&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">SELECT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">t1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">RESET&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">ROLE&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">SET&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">ROLE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">u2&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">PASSWORD&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;u2.password&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">SELECT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">t1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">RESET&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">ROLE&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="c1">-- 清理环境
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span>&lt;span class="k">DROP&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">MASKING&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">POLICY&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">m1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">DROP&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">RESOURCE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">LABEL&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">l1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">DROP&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">TABLE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">t1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">DROP&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">USER&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">u1&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="n">u2&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="13-全密态">1.3 全密态&lt;/h2>
&lt;ul>
&lt;li>模块分析
&lt;ul>
&lt;li>客户端
&lt;ul>
&lt;li>语法解析&lt;/li>
&lt;li>语义分析&lt;/li>
&lt;li>加密&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>服务端
&lt;ul>
&lt;li>..&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;h2 id="14-防篡改">1.4 防篡改&lt;/h2>
&lt;ul>
&lt;li>hash算法：md5&lt;/li>
&lt;/ul>
&lt;h1 id="2-greenplum">2 greenplum&lt;/h1>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">yum install zstd libzstd-devel krb5-devel krb5-libs cyrus-sasl-gssapi libevent-devel libyaml-devel libxml2 libxml2-devel curl libcurl-devel
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">yum install apr apr-devel apr-util apr-util-devel
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">yum install expat-devel openldap-devel bzip2 bzip2-devel xerces-c xerces-c-devel python36-devel
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ln -s /usr/include/python2.7/Python.h /usr/include/Python.h
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 报错就降级&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">yum downgrade expat-2.1.0-12.el7
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">mkdir install
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">cd&lt;/span> install
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># echo &amp;#39;&amp;#39;使用单引号可防止变量$PATH等展开&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">echo&lt;/span> &lt;span class="s1">&amp;#39;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">export GPHOME=`pwd`/install
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">export BINARYLIBS=`pwd`/../third
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">export GCC_PATH=$BINARYLIBS/buildtools/gcc10.3
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">export CC=$GCC_PATH/gcc/bin/gcc
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">export CXX=$GCC_PATH/gcc/bin/g++
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">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
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">export PATH=$GCC_PATH/gcc/bin:$PATH
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">&amp;#39;&lt;/span> &amp;gt; genv
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 建议把环境变量再在~/.bashrc中写一份，因为初始化集群时，需要ssh登录，以初始化segment节点&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">./configure --with-python --with-libxml --with-gssapi --without-zlib --with-gpcc --prefix&lt;span class="o">=&lt;/span>&lt;span class="nv">$GPHOME&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">make -sj &lt;span class="m">16&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">make install -sj &lt;span class="m">16&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">echo&lt;/span> &lt;span class="s2">&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">ARRAY_NAME=&amp;#34;&lt;/span>Greenplum Cluster&lt;span class="s2">&amp;#34;
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">SEG_PREFIX=gpseg #segment数据库前缀名
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">PORT_BASE=40000 #segment数据库起始端口号
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">declare -a DATA_DIRECTORY=(//home/shenkun/gp/install/segdata)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">#segments数据目录，有几个DATA_DIRECTORY, 每个节点上便会启动几个segment，本例为2个segment
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">MASTER_HOSTNAME=master #master主机名
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">MASTER_DIRECTORY=/home/shenkun/gp/install/master #master数据目录
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">MASTER_PORT=5000 #master端口号，也是对外业务端口号
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">TRUSTED_SHELL=ssh
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">CHECK_POINT_SEGMENTS=8
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">ENCODING=UNICODE
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">DATABASE_NAME=gpdb
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">MACHINE_LIST_FILE=/home/shenkun/gp/install/hostfile #集群配置文件，hostfile对应7中创建的文件名
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s2">&amp;#34;&lt;/span> &amp;gt; gpcfg
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">echo&lt;/span> &lt;span class="s2">&amp;#34;master&amp;#34;&lt;/span> &amp;gt; hostfile
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">gpinitsystem -c gpcfg -a
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">psql -p &lt;span class="m">5000&lt;/span> -d gpdb
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nv">PGOPTIONS&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;-c gp_session_role=utility&amp;#39;&lt;/span> psql -p &lt;span class="m">40000&lt;/span> -d gpdb
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># @ master&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">exec_simple_query
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> pg_parse_query
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> pg_analyze_and_rewrite
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> pg_plan_queries
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> pg_plan_querie
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> planner
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> standard_planner
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> subquery_planner
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> cdbllize_adjust_top_path
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> create_plan
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> cdbpathtoplan_create_flow
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> makeFlow
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> cdbllize_decorate_subplans_with_motions
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> PortalStart
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ExecutorStart
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> standard_ExecutorStart
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> CdbDispatchPlan
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># @ segment&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> exec_mpp_query
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> deserializeNode
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> PortalStart
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> PortalRun
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> PortalDrop
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> PortalRun
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> PortalRunMulti
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ProcessQuery
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ExecutorStart
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ExecutorRun
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> standard_ExecutorRun
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ExecutePlan
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ExecutorFinish
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ExecutorEnd
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> PortalDrop
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div></description></item><item><title>WAL 加密模块设计</title><link>https://my-blog.j8465383071.workers.dev/posts/security/wal-encryption-design/</link><pubDate>Mon, 07 Sep 2026 15:30:00 +0800</pubDate><guid>https://my-blog.j8465383071.workers.dev/posts/security/wal-encryption-design/</guid><description>&lt;p>假设集群里已经存在表级透明加密模块，在此基础上设计一个高性能、高易用性的 WAL 加密模块。&lt;/p>
&lt;p>WAL 加密的难点几乎不在&amp;quot;加密&amp;quot;本身，而在两件事：&lt;strong>同一个 8KB 页会被反复重写&lt;/strong>，以及&lt;strong>恢复路径要在拿不到 catalog 的时候就能解密&lt;/strong>。下面按设计决策的顺序展开。&lt;/p>
&lt;h2 id="1-威胁模型">1 威胁模型&lt;/h2>
&lt;p>先划清边界，因为它直接决定后面几个取舍。&lt;/p>
&lt;ul>
&lt;li>&lt;strong>要防的&lt;/strong>：磁盘 / 备份 / 归档介质被拖走；DBA 之外的运维人员直接读 &lt;code>pg_wal/&lt;/code>；WAL 归档到对象存储。&lt;/li>
&lt;li>&lt;strong>不防的&lt;/strong>：有 root 权限的在线攻击者（内存里必然有明文）、旁路攻击。&lt;/li>
&lt;/ul>
&lt;h3 id="11-为什么不用-dm-crypt-了事">1.1 为什么不用 dm-crypt 了事&lt;/h3>
&lt;p>如果只是防&amp;quot;介质丢失&amp;quot;，块设备加密（LUKS/dm-crypt）性价比高得多。在数据库内核里做 WAL 加密，真正的理由只有三个：&lt;/p>
&lt;ol>
&lt;li>密钥要由数据库自己管，不能落在 OS 层（密评 / 国测要求）；&lt;/li>
&lt;li>归档件要天然带密；&lt;/li>
&lt;li>和已有的表级 TDE 共用一套密钥体系。&lt;/li>
&lt;/ol>
&lt;p>设计要始终对齐这三个理由，否则很容易做成一个又慢、又没多大意义的模块。&lt;/p>
&lt;h3 id="12-fpi-是必须堵的洞">1.2 FPI 是必须堵的洞&lt;/h3>
&lt;p>既然表级 TDE 已经存在，那么 &lt;strong>FPI（full page image）就是个必堵的泄漏点&lt;/strong>。&lt;/p>
&lt;p>如果 TDE 是在 smgr 层做的（缓冲区里是明文、写盘时加密），那么 WAL 里的 FPI 记录的是&lt;strong>明文页&lt;/strong> —— 加密表的数据会原封不动地漏进 WAL。&lt;/p>
&lt;blockquote>
&lt;p>只要集群里存在任何一张加密表，WAL 加密就必须强制开启，不能是两个独立开关。&lt;/p>&lt;/blockquote>
&lt;p>实现上做成一个集群级的 &lt;code>data_encryption = on&lt;/code>，或者至少让 &lt;code>CREATE ENCRYPTION POLICY&lt;/code> 在 WAL 加密未开启时直接报错。这是易用性设计里最重要的一条：&lt;strong>不要把一个&amp;quot;配错了就静默泄密&amp;quot;的组合留给用户&lt;/strong>。&lt;/p></description></item><item><title>海量 9 设计 E100审计</title><link>https://my-blog.j8465383071.workers.dev/posts/projectdocs/9-design-e100-audit/</link><pubDate>Tue, 22 Jul 2025 14:28:00 +0800</pubDate><guid>https://my-blog.j8465383071.workers.dev/posts/projectdocs/9-design-e100-audit/</guid><description>&lt;h1 id="1-e100审计功能">1 E100审计功能&lt;/h1>
&lt;h2 id="11-功能简述">1.1 功能简述&lt;/h2>
&lt;p>【审计功能】&lt;br>
审计是重要的安全特性，核心功能是收集数据库内的事件，例如：登录用户、创建对象、查询数据等，根据事件生成与审计日志，存储审计日志，向用户提供日志查询接口。使用方式请看需求文档。&lt;/p>
&lt;p>【审计架构】&lt;br>
审计整体架构如下图所示：（&lt;strong>“线程“替换为“进程”&lt;/strong>，原图不小心弄丢了，不好修改了，将就看）&lt;/p>
&lt;p>&lt;img alt="adt-1" loading="lazy" src="https://my-blog.j8465383071.workers.dev/images/ProjectDocs/9-design-e100-audit/adt-1.png">&lt;/p>
&lt;p>【审计流程】&lt;/p>
&lt;p>&lt;img alt="adt-2" loading="lazy" src="https://my-blog.j8465383071.workers.dev/images/ProjectDocs/9-design-e100-audit/adt-2.png">&lt;/p>
&lt;h2 id="12-实现方案">1.2 实现方案&lt;/h2>
&lt;h3 id="一启动审计进程">一、启动审计进程&lt;/h3>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">1. 启动postmaster进程 &lt;span class="c1"># PostmasterMain&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 2. 加载GUC参数 &lt;span class="c1"># SelectConfigFiles&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 2.1 &lt;span class="s1">&amp;#39;---加载审计GUC---&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 3. 创建共享内存和信号量 &lt;span class="c1"># reset_shared -&amp;gt; CreateSharedMemoryAndSemaphores&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 3.1 计算共享内存总大小
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;计算审计共享内存大小：根据GUC配置&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 3.2 创建共享内存 &lt;span class="c1"># PGSharedMemoryCreate&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 3.3 创建LwLock &lt;span class="c1"># CreateLWLocks&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 3.4 初始化wal-buffer共享内存 &lt;span class="c1"># XLOGShmemInit&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 3.5 初始化share-buffer共享内存 &lt;span class="c1"># InitBufferPool&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 3.6 &lt;span class="s1">&amp;#39;如果开启审计：初始化审计共享内存：划分共享内存，包括audit-buffer&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 4. 启动sys-log进程 &lt;span class="c1"># SysLogger_Start&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 5. &lt;span class="s1">&amp;#39;如果开启审计：初始化审计模块&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 5.1 &lt;span class="s1">&amp;#39;日志目录：检验与创建审计日志目录&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 5.2 &lt;span class="s1">&amp;#39;日志文件：每次重启，使用新的日志文件，方便用户单个删除日志文件&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 5.3 &lt;span class="s1">&amp;#39;内存上下文：创建审计全局内存上下文&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 5.4 &lt;span class="s1">&amp;#39;审计缓存区：初始化audit-buffer&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 5.5 &lt;span class="s1">&amp;#39;审计文件：初始化审计文件（并发write, read, delete日志）&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 5.6 &lt;span class="s1">&amp;#39;回调函数：在执行DDL、计划、函数等关键函数中，注册生成审计事件、日志的回调函数&amp;#39;&lt;/span> &lt;span class="c1"># 后面详细介绍&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 6. &lt;span class="s1">&amp;#39;如果开启审计：启动审计进程&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 6.1 &lt;span class="s1">&amp;#39;信号：注册信号处理函数：sighup, sigquit, sigusr1&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 6.2 &lt;span class="s1">&amp;#39;显示：设置ps命令显示的进程信息&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 6.3 主循环
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 6.4 &lt;span class="s1">&amp;#39;等待事件：关键是timeout&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 6.5 &lt;span class="s1">&amp;#39;存储日志：读取audit-buffer中待落盘的日志，并存储&amp;#39;&lt;/span> &lt;span class="c1"># 后面详细介绍&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 6.6 &lt;span class="s1">&amp;#39;调整速率：按照每次落盘数据的长度，动态调整timeout&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 连续多次为0，timeout依次变为1ms, 100ms, 1s
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 单次落盘长度大于16m，timeout&lt;span class="o">=&lt;/span>&lt;span class="m">0&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 7. &lt;span class="s1">&amp;#39;主循环&amp;#39;&lt;/span> &lt;span class="c1"># ServerLoop&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 7.1 接收客户端连接 &lt;span class="c1"># select&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 7.2 创建postgres进程 &lt;span class="c1"># BackendStartup -&amp;gt; BackendRun -&amp;gt; PostgresMain&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 7.3 检查与重启sys-log进程 &lt;span class="c1"># SysLogger_Start&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 7.4 &lt;span class="s1">&amp;#39;检查与重启审计进程&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 7.5 检查与重启checkpointer进程 &lt;span class="c1"># StartCheckpointer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> 7.6 检查与重启wal-writer进程 &lt;span class="c1"># StartWalWriter&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="二收集审计事件">二、收集审计事件&lt;/h3>
&lt;p>目前，只有以下2类进程，会生成审计事件：&lt;/p></description></item><item><title>分享编写需求/设计文档的个人经验</title><link>https://my-blog.j8465383071.workers.dev/posts/projectdocs/writing-requirement-and-design-docs/</link><pubDate>Tue, 15 Jul 2025 10:54:00 +0800</pubDate><guid>https://my-blog.j8465383071.workers.dev/posts/projectdocs/writing-requirement-and-design-docs/</guid><description>&lt;h1 id="1-简介">1 简介&lt;/h1>
&lt;h2 id="11-分享的主题">1.1 分享的主题&lt;/h2>
&lt;p>分享一些编写需求、设计文档经验&lt;/p>
&lt;h2 id="12-分享的背景">1.2 分享的背景&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>背景：我写的需求文档，（相对）还算详细，所以有此次分享&lt;/p>
&lt;ul>
&lt;li>308.1，profile功能的需求文档：&lt;a href="https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007196">https://www.tapd.cn/60475194/markdown_wikis/show/#1160475194001007196&lt;/a>&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>根因：前公司流程繁重，被迫养成这种习惯。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>分享的内容：可分享的干货不多，我觉得，在写文档的过程中，大部分人想的很详细，只是没有编写到文档中，毕竟每个人都有自己的编写风格。所以，本文的重点，是介绍前公司流程与要求，并以我做过的需求为例，为大家提供一点参考。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>分享人经历：交过10+个不算小的需求，完整写过10+次需求与设计文档，格式与海量的接近。&lt;/p>
&lt;/li>
&lt;li>
&lt;p>分享的局限：交付的需求，主要是安全方向，也涉及SQL、存储等多个模块，所以，本文主要以安全需求的角度写，其他模块的需求不一定适用。&lt;/p>
&lt;/li>
&lt;/ul>
&lt;p>&lt;img alt="scope" loading="lazy" src="https://my-blog.j8465383071.workers.dev/images/ProjectDocs/writing-requirement-and-design-docs/scope.png">&lt;/p>
&lt;h2 id="13-前公司的流程">1.3 前公司的流程&lt;/h2>
&lt;p>与海量相比，前公司的交付流程，几乎一样：&lt;/p>
&lt;ol>
&lt;li>客户：提出需求&lt;/li>
&lt;li>产品、项目、测试、架构等：审核需求&lt;/li>
&lt;li>开发：撰写需求/设计文档&lt;/li>
&lt;li>各角色：评审需求/设计文档&lt;/li>
&lt;li>开发：编写代码&lt;/li>
&lt;li>…&lt;/li>
&lt;/ol>
&lt;p>其中，在&lt;code>4.评审需求/设计文档&lt;/code>环节，前公司区别较大：&lt;/p>
&lt;ul>
&lt;li>
&lt;p>一、评审人员多&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>编号&lt;/th>
&lt;th>角色&lt;/th>
&lt;th>评审人&lt;/th>
&lt;th>目的&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>1&lt;/td>
&lt;td>开发&lt;/td>
&lt;td>安全组、SQL组、存储组、运维组、..&lt;/td>
&lt;td>避免影响其他模块，协助发现风险&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>2&lt;/td>
&lt;td>测试&lt;/td>
&lt;td>测试人、测试组长&lt;/td>
&lt;td>学习新需求，识别测试重点&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>3&lt;/td>
&lt;td>架构&lt;/td>
&lt;td>架构设计&lt;/td>
&lt;td>避免影响其他模块，确保后向兼容&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>4&lt;/td>
&lt;td>资料&lt;/td>
&lt;td>资料优化、资料审核&lt;/td>
&lt;td>学习新需求&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>5&lt;/td>
&lt;td>用例&lt;/td>
&lt;td>用例审核&lt;/td>
&lt;td>确保各种check可看护功能&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>6&lt;/td>
&lt;td>其他&lt;/td>
&lt;td>流程提升&lt;/td>
&lt;td>-&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;/li>
&lt;li>
&lt;p>二、评审通过难&lt;/p>
&lt;ol>
&lt;li>组内评审&lt;/li>
&lt;li>线上评审：上述所有角色会上评审，不过，一般很多人会议冲突，关键靠线下评审&lt;/li>
&lt;li>线下评审（关键流程）：各类角色共10+必选评审人，通过在线需求文档、设计文档了解需求，提出疑问，提出意见。开发分析解决后，找提出人确认意见，才算闭环。最后，所有必选评审人评审通过，才算完成流程。&lt;/li>
&lt;/ol>
&lt;/li>
&lt;/ul>
&lt;p>在这种流程中，需求与设计文档，要满足很多要求：&lt;/p>
&lt;ol>
&lt;li>
&lt;p>普适：考虑到其他组开发、测试、资料等角色，不熟悉本领域的基础知识，所以，需要详细介绍相关原理，很多原理需要从头介绍&lt;/p>
&lt;/li>
&lt;li>
&lt;p>完整：要充分例举所有可能涉及风险，否则，评审人会认为未考虑到&lt;/p>
&lt;blockquote>
&lt;p>举例：做了1个需求，可以为表设置加密属性，需要考虑：系统表、用户表（atore表、ustore表、分区表、临时表、toast表、unlogged表、segment表、hashbuckent表、物化视图…）&lt;/p>&lt;/blockquote>
&lt;/li>
&lt;/ol>
&lt;h1 id="2-需求文档写作思路">2 需求文档写作思路&lt;/h1>
&lt;h2 id="21-分析过程">2.1 分析过程&lt;/h2>
&lt;p>首先，客户提出需求，很多需求不够清晰。&lt;/p>
&lt;blockquote>
&lt;p>示例：&lt;/p>
&lt;ul>
&lt;li>profile原始需求：
&lt;ul>
&lt;li>目前对于数据库用户的管理方式不够便捷，无法像Oracle为用户赋予一组安全策略。一些属性如密码有效期、密码过期天数、密码尝试次数等也只能全局设定，无法指定用户配置。&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>&lt;/blockquote>
&lt;p>然后，以我的个人习惯，分析需求的流程如下：&lt;/p></description></item><item><title>海量 10 设计 SSL协议</title><link>https://my-blog.j8465383071.workers.dev/posts/projectdocs/10-design-ssl/</link><pubDate>Tue, 09 Sep 2025 18:48:00 +0800</pubDate><guid>https://my-blog.j8465383071.workers.dev/posts/projectdocs/10-design-ssl/</guid><description>&lt;h1 id="1-tls协议支持第三方流量审计">1 TLS协议支持第三方流量审计&lt;/h1>
&lt;h2 id="11-功能简述">1.1 功能简述&lt;/h2>
&lt;p>【需求背景】&lt;br>
TLS协议，是保障通信安全的加密协议，可分为4个子功能：&lt;/p>
&lt;ol>
&lt;li>密钥生成：通过密钥交换或密钥协商等协议，让双方生成相同的密钥&lt;/li>
&lt;li>身份认证：在开始阶段，双方均向对方发送自己的证书。双方接收证书后，基于PKI体系，校验证书是否合法。&lt;/li>
&lt;li>数据加密：发送方发生数据前，使用密钥加密数据，发送数据密文。接受方接受密文后，使用密钥解密，获取数据。&lt;/li>
&lt;li>数据校验：在加密数据的同时，生成数据完整性校验码，与数据密文拼接在一起。（简单理解：生成数据的哈希值，并使用密钥加密哈希值）接收方解密数据后，同样生成数据完整性校验码，与接收的相比，判断是否一致。&lt;/li>
&lt;/ol>
&lt;p>开源软件libssl.so提供TLS功能，应用只需调用接口，即可实现TLS协议。同时，libssl.so提供100+算法套件，可让应用选择不同的参数组合，1个算法套件，包含4个关键参数：&lt;/p>
&lt;ol>
&lt;li>密钥生成：密钥生成协议&lt;/li>
&lt;li>身份认证：证书算法类型&lt;/li>
&lt;li>数据加密：加密算法类型&lt;/li>
&lt;li>数据校验：哈希算法类型&lt;/li>
&lt;/ol>
&lt;p>例如，libssl.so中，常用的算法套件为：ECDHE-RSA-AES128-SHA256，该套件中，参数的含义如下：&lt;/p>
&lt;ol>
&lt;li>密钥生成协议：ECDHE协议。（常见协议类型:DHE、ECDHE、RSA等）&lt;/li>
&lt;li>证书算法类型：RSA&lt;/li>
&lt;li>加密算法类型：AES-128&lt;/li>
&lt;li>哈希算法类型：SHA-256&lt;/li>
&lt;/ol>
&lt;p>【需求分析】&lt;br>
vastbase支持TLS协议，当vsql与vastbase通信时，双方可使用TLS模块，生成密钥，并使用密钥加密、解密通信数据，包括：SQL语句、SQL执行结果等。&lt;br>
客户可能采用第三方工具，截取网络流量，获取传输中的SQL等数据，进行流量审计。但是，在使用TLS协议的情况下，网络中的数据是密文形式，无法进行流量审计。&lt;/p>
&lt;p>vastbase提供1个GUC参数ssl_ciphers，用于配置TLS协议采用的算法套件，旧版本，该参数的取值范围如下：&lt;/p>
&lt;ul>
&lt;li>ECDHE-ECDSA-AES256-GCM-SHA384&lt;/li>
&lt;li>ECDHE-RSA-AES256-GCM-SHA384&lt;/li>
&lt;li>DHE-RSA-AES256-GCM-SHA384&lt;/li>
&lt;li>ECDHE-ECDSA-AES128-GCM-SHA256&lt;/li>
&lt;li>DHE-RSA-AES128-GCM-SHA256&lt;/li>
&lt;li>ECDHE-RSA-AES128-SHA256&lt;/li>
&lt;li>ECDHE-ECDSA-SM4-CBC-SM3&lt;/li>
&lt;li>4个仅tassl支持的国密算法套件&lt;/li>
&lt;/ul>
&lt;p>上述7个套件中，密钥生成协议为：ECDHE、DHE，此类DH协议，无法让第三方工具获取密钥。&lt;/p>
&lt;p>本版本，新增4个算法套件：&lt;/p>
&lt;ul>
&lt;li>AES128-SHA256&lt;/li>
&lt;li>AES256-SHA256&lt;/li>
&lt;li>AES128-GCM-SHA256&lt;/li>
&lt;li>AES256-GCM-SHA384&lt;/li>
&lt;/ul>
&lt;p>上述4个套件，密钥生成协议为：RSA，该协议可让第三方工具获取密钥，使其可解密网络流量，获取SQL语句、SQL执行结果等。&lt;/p>
&lt;p>【需求实现】&lt;br>
之前，vastbase限制ssl_ciphers的取值范围，仅放开7个算法套件，本版本，将新增放开4个算法套件。&lt;/p>
&lt;p>实现时，仅修改ssl_ciphers的取值范围，新增支持4个算法套件[AES128-SHA256、AES256-SHA256、AES128-GCM-SHA256、AES256-GCM-SHA384]，4个算法套件将直接传递给libssl.so，内核不做任何处理。&lt;/p>
&lt;p>因此，本需求无复杂设计。本文主要介绍完整的TLS协议工作原理。&lt;/p>
&lt;h2 id="12-实现方案">1.2 实现方案&lt;/h2>
&lt;h3 id="一ecdhe与rsa的区别">一、ECDHE与RSA的区别&lt;/h3>
&lt;p>此处简化ECDHE与RSA的步骤与算法，提取最核心的原理，方便快速理解。&lt;/p>
&lt;ul>
&lt;li>
&lt;p>一、ECDHE密钥协商协议&lt;br>
第三方工具、攻击者完全无法获取密钥。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">client server
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">+-------------------------------------------+-----------------------------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> &amp;lt;---- 0. 双方随机约定一些公开参数 ------&amp;gt; &lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> 1. 生成随机私钥 client_priv
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> 2. 基于client_priv，计算公钥 client_pub
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> 3. 发送公钥 client_pub ------------&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 4. 接收公钥 client_pub
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 5. 生成随机私钥 server_priv
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 6. 基于server_priv，计算公钥 server_pub
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;lt;------------ &lt;span class="p">|&lt;/span> 7. 发送公钥 server_pub
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> 8. 接收公钥 server_pub
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> 9. 基于client_priv，server_pub，计算密钥
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 10. 基于server_priv，client_pub，计算密钥
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">（第9步和第10步，可以计算出相同的密钥）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">简单举个例子
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">client server
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">+-------------------------------------------+-----------------------------------
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> &amp;lt;----- 0. generate and send &lt;span class="o">(&lt;/span>2,11&lt;span class="o">)&lt;/span> ----&amp;gt; &lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> 1. generate &lt;span class="m">8&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> 2. caculate &lt;span class="o">(&lt;/span>&lt;span class="m">8&lt;/span> * 2&lt;span class="o">)&lt;/span> % &lt;span class="nv">11&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="m">5&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> 3. send &lt;span class="m">5&lt;/span> ----------&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 4. receive &lt;span class="m">5&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 5. generate &lt;span class="m">10&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 6. caculate &lt;span class="o">(&lt;/span>&lt;span class="m">10&lt;/span> * 2&lt;span class="o">)&lt;/span> % &lt;span class="nv">11&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="m">9&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &amp;lt;------------ &lt;span class="p">|&lt;/span> 7. send &lt;span class="m">9&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> 8. receive &lt;span class="m">9&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> 9. &lt;span class="nv">key&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="o">(&lt;/span>&lt;span class="m">8&lt;/span> * 9&lt;span class="o">)&lt;/span> % &lt;span class="nv">11&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="m">6&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 10. &lt;span class="nv">key&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="o">(&lt;/span>&lt;span class="m">10&lt;/span> * 5&lt;span class="o">)&lt;/span> % &lt;span class="nv">11&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="m">6&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">攻击者：截获网络流量，获取2,11,5,9，无法计算出密钥为6
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;/li>
&lt;li>
&lt;p>二、RSA密钥交换协议&lt;/p></description></item><item><title>海量 透明加密 设计</title><link>https://my-blog.j8465383071.workers.dev/posts/projectdocs/13-design-tde/</link><pubDate>Mon, 23 Mar 2026 20:52:00 +0800</pubDate><guid>https://my-blog.j8465383071.workers.dev/posts/projectdocs/13-design-tde/</guid><description>&lt;h1 id="1-透明加密">1 透明加密&lt;/h1>
&lt;h2 id="11-功能简述">1.1 功能简述&lt;/h2>
&lt;p>关于透明加密的基本概念，请看需求文档。&lt;br>
用户使用透明加密的示例如下：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sql" data-lang="sql">&lt;span class="line">&lt;span class="cl">&lt;span class="k">CREATE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">TABLE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">t1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">c1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">TEXT&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">c2&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="nb">TEXT&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">CREATE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">ENCRYPTION&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">KEY&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">tde_key&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">WITH&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="k">source&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="k">local&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">password&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;pass.123&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">CREATE&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">ENCRYPTION&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">POLICY&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">ep1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">FRO&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">t1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">KEY&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">tde_key&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">INSERT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">INTO&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">t1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">VALUES&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;data1&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;data2&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">INSERT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">INTO&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">t1&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">VALUES&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;data1&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;data2&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w">&lt;/span>&lt;span class="k">SELECT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="o">*&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">FROM&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">t1&lt;/span>&lt;span class="p">;&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="12-实现方案">1.2 实现方案&lt;/h2>
&lt;h3 id="121-整体架构">1.2.1 整体架构&lt;/h3>
&lt;p>透明加密的核心目标，是通过数据加密方案，解决攻击者绕过数据库安全机制，直接从磁盘窃取数据的问题。&lt;br>
在加密数据后，需要确保不影响内核在数据上进行计算。因此，需要在存储层底层，对数据进行加密。另外，为确保存储底层能够识别哪些数据加密，哪些数据不加密，以及使用什么算法加密等，上层需传递加密信息。透明加密逻辑架构如下：&lt;/p>
&lt;p>&lt;img alt="1-struct" loading="lazy" src="https://my-blog.j8465383071.workers.dev/images/ProjectDocs/13-design-tde/1-struct.png">&lt;/p>
&lt;h3 id="122-工作流程">1.2.2 工作流程&lt;/h3>
&lt;p>为适配存储底层设计，同时兼顾加密性能，以Page为粒度进行加密，并且，在Page中，存储加密信息。&lt;/p>
&lt;p>&lt;img alt="2-flow" loading="lazy" src="https://my-blog.j8465383071.workers.dev/images/ProjectDocs/13-design-tde/2-flow.png">&lt;/p>
&lt;h3 id="123-详细流程">1.2.3 详细流程&lt;/h3>
&lt;h4 id="一启动进程">一、启动进程&lt;/h4>
&lt;p>在启动进程阶段，故障恢复时，如果回放到属于加密表的xlog，涉及到解密Page，因此，需在故障恢复前加载密钥。&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="n">main&lt;/span> &lt;span class="c1"># 1. 启动数据库进程（基于pg-16代码）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">PostmasterMain&lt;/span> &lt;span class="c1"># 2. 启动postmaster进程&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">SelectConfigFiles&lt;/span> &lt;span class="c1"># 3. 读取GUC文件&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="s1">&amp;#39;tde_load_encryption_key&amp;#39;&lt;/span> &lt;span class="c1"># 4. 读取密钥文件（后文介绍密钥如何生成）&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">SysLogger_Start&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">StartupDataBase&lt;/span> &lt;span class="c1"># 5. 开始故障恢复&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">StartupProcessMain&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">StartupXLOG&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ReadControlFile&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">PerformWalRecovery&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">loop&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ReadRecord&lt;/span> &lt;span class="c1"># 6. 读取xlog&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ApplyWalRecord&lt;/span> &lt;span class="c1"># 7. 重放xlog&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">GetRmgr&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">rm_redo&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="o">...&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">heap_xlog_insert&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">XLogReadBufferForRedo&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">XLogReadBufferForRedoExtended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">XLogReadBufferExtended&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ReadBufferWithoutRelcache&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ReadBuffer_common&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">smgrread&lt;/span> &lt;span class="c1"># 8. 读取数据文件&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># 需解密，后文统一介绍&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ServerLoop&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="n">loop&lt;/span>&lt;span class="p">:&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">ConnCreate&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">BackendStartup&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">BackendRun&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">PostgresMain&lt;/span> &lt;span class="c1"># 9. 启动postgres进程&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">StartCheckpointer&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">StartBackgroundWriter&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">StartChildProcess&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">AuxiliaryProcessMain&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">BackgroundWriterMain&lt;/span> &lt;span class="c1"># 10. 启动bgwriter进程&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="二生成密钥">二、生成密钥&lt;/h4>
&lt;p>当前版本，所有表，使用同一个数据密钥。因此，暂时无需新增系统表，存储密钥对象。&lt;/p></description></item><item><title>海量 mac 设计</title><link>https://my-blog.j8465383071.workers.dev/posts/projectdocs/14-design-mac/</link><pubDate>Mon, 23 Mar 2026 21:41:00 +0800</pubDate><guid>https://my-blog.j8465383071.workers.dev/posts/projectdocs/14-design-mac/</guid><description>&lt;h1 id="1-强制访问控制">1 强制访问控制&lt;/h1>
&lt;h2 id="11-功能简述">1.1 功能简述&lt;/h2>
&lt;p>从实现的角度看，当用户执行SQL时，强制访问控制主要实现以下功能：&lt;/p>
&lt;ol>
&lt;li>CREATE ACCESS POLICY ..：在系统表中，记录ACCESS POLICY，以及其中的LABLE等信息&lt;/li>
&lt;li>CREATE TABLE ..：创建表时，如果设置acess_policy字段，则自动为表新增1列隐藏列，列名为access_label&lt;/li>
&lt;li>INSERT ..：向表插入数据时，根据当前用户的write_label，自动为数据生成access_label列的值。&lt;/li>
&lt;li>SELECT ..：从表查询数据时，根据当前用户的read_label，自动为查询语句添加过滤条件has_mac_permission(access_label, read_label)&lt;/li>
&lt;/ol>
&lt;p>另外，如果为表设置访问策略，需在索引中同时设置访问策略：&lt;/p>
&lt;ol>
&lt;li>CREATE INDEX ..：自动为索引新增1列，列名为access_label&lt;/li>
&lt;/ol>
&lt;p>对于一些其他语法，也许单独适配，包括：&lt;/p>
&lt;ol>
&lt;li>COPY ..：自动修改旧数据的access_label值&lt;/li>
&lt;/ol>
&lt;h2 id="12-实现方案">1.2 实现方案&lt;/h2>
&lt;h3 id="121-整体流程">1.2.1 整体流程&lt;/h3>
&lt;p>本文重点从源码角度，介绍强制访问控制策略如何基于隐藏列，实现强制访问控制，包括：创建、填充、匹配隐藏列等流程。&lt;br>
核心功能的大致流程如下：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">User Vastbase Disk
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">+---------------------------------------------------+---------------------------------------------------------+
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 管理员&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> 1. CREATE ACCESS POLICY .. LEVEL .. LABEL .. --&amp;gt; &lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 2. 存储access policy至系统表vb_access_policy --&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 3. 存储access level至系统表vb_access_level --&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 4. 存储access label至系统表vb_access_label --&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> 5. CREATE TABLE .. &lt;span class="o">(&lt;/span>&lt;span class="nv">access_policy&lt;/span>&lt;span class="o">=&lt;/span>..&lt;span class="o">)&lt;/span> --&amp;gt; &lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 6. 识别是否设置access_policy
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 7. 自动添加隐藏列access_label
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 8. 存储access_policy至系统表pg_class --&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 9. 存储accessl_label定义至系统表pg_attribute --&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> 10. CREATE USER ..
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> ACCESS POLICY .. READ LABEL .. WRITE LABEL --&amp;gt; &lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 11. 存储access_policy, read_label, write_label至系统表pg_authid --&amp;gt;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># 普通用户&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> 12. vsql -U username -W password --&amp;gt; &lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> 14. &lt;span class="nb">set&lt;/span> &lt;span class="nv">read_label&lt;/span> &lt;span class="o">=&lt;/span> .. / &lt;span class="nv">write_label&lt;/span> &lt;span class="o">=&lt;/span> .. --&amp;gt; &lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 15. 查询pg_authid，判断read_label/write_label是否合法 &amp;lt;--
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 16. 设置临时的read_label/write_label
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 17. 如何用户未自动设置read_label/write_label，自动根据pgauthid设置
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> 18. INSERT .. --&amp;gt; &lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 19. 查询pg_class，判断表是否有access_policy &amp;lt;--
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 20. 自动为隐藏列赋值，取值为write_label
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">|&lt;/span> 21. SELECT .. --&amp;gt; &lt;span class="p">|&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 22. 查询pg_class，判断表是否有access_policy &amp;lt;--
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 23. 语义分析
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 24. 查询重写：自动新增过滤条件：WHERE has_mac_permission&lt;span class="o">(&lt;/span>access_label, read_label&lt;span class="o">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">|&lt;/span> 24. 计划执行：扫描Tuple，根据过滤条件，过滤不满足权限检查的Tuple
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="122-详细流程">1.2.2 详细流程&lt;/h3>
&lt;h4 id="一创建策略">一、创建策略&lt;/h4>
&lt;p>当用户创建策略时，例如：&lt;/p></description></item><item><title>海量 15 设计 逻辑复制性能优化</title><link>https://my-blog.j8465383071.workers.dev/posts/projectdocs/15-design-logical-replication/</link><pubDate>Wed, 06 May 2026 17:48:00 +0800</pubDate><guid>https://my-blog.j8465383071.workers.dev/posts/projectdocs/15-design-logical-replication/</guid><description>&lt;h1 id="1-逻辑复制性能优化">1 逻辑复制性能优化&lt;/h1>
&lt;h2 id="11-功能简述">1.1 功能简述&lt;/h2>
&lt;ul>
&lt;li>原理：&lt;br>
假设，发布端执行&lt;code>INSERT INTO t1 VALUES(1,'data1')&lt;/code>，更改1行数据，产生1条wal日志。逻辑复制功能将读取这条wal，解码并生成1条message，将message发送至订阅端。订阅端应用这条message，等价于重新执行&lt;code>INSERT INTO t1 VALUES(1,'data1')&lt;/code>。 &lt;img alt="rep" loading="lazy" src="https://my-blog.j8465383071.workers.dev/images/ProjectDocs/15-design-logical-replication/rep.png">&lt;/li>
&lt;li>问题：&lt;br>
308.1 psu1以及之前版本，逻辑复制性能较低。以tpcc场景为例，40w tmpc时，发布端产生wal日志速度约100m/s，订阅端的复制速度约10+m/s。&lt;/li>
&lt;li>客户：&lt;br>
滚动升级场景中，备机停机升级，主机持续执行业务，备机升级后使用逻辑复制追赶主机数据。长存客户场景，主机产生wal日志速度约40-50m/s，旧版本逻辑复制速度10+m/s，由于逻辑复制速度太慢，备机无法追赶主机，最终导致升级失败。&lt;/li>
&lt;li>优化&lt;br>
本需求设计与实现并行逻辑复制机制，大幅提高逻辑复制速度，在上述场景中，订阅端速度可达到70-90m/s。并行逻辑复制分为3个关键子机制：
&lt;ol>
&lt;li>发布端多线程并行解码&lt;/li>
&lt;li>发布端与订阅端流复制传输协议&lt;/li>
&lt;li>订阅端多线程并行应用&lt;/li>
&lt;/ol>
&lt;/li>
&lt;/ul>
&lt;h2 id="12-实现方案">1.2 实现方案&lt;/h2>
&lt;p>本章分3个章节，分别介绍3个关键子机制。&lt;/p>
&lt;h3 id="121-发布端并行解码机制">1.2.1 发布端并行解码机制&lt;/h3>
&lt;p>在旧版本中，发布端采用串行解码机制，只有1个walsender线程，串行执行：1次读取1条wal日志，解码1条wal生成1条message，缓存或发送message。&lt;/p>
&lt;p>旧版本代码中，发布端有实现并行解码的代码，但是，无法直接使用，订阅端只能是工具，不能是数据库实例，且存在大量问题。本需求基于旧版本并行解码，实现权限的并行解码机制。&lt;/p>
&lt;p>并行解码机制，将启动多个线程，包括1个reader、多个decoder、1个walsender，它们的功能如下：&lt;/p>
&lt;ul>
&lt;li>reader：1次读取1条wal日志，将wal发送给decoder&lt;/li>
&lt;li>decoder：1次接收1条reader发送的wal，解码生成message，将message发送给walsender&lt;/li>
&lt;li>walsender：1次接收1条decoder发送的message，将message发送给订阅端&lt;/li>
&lt;/ul>
&lt;p>线程架构图如下：&lt;/p>
&lt;p>&lt;img alt="pa-pub" loading="lazy" src="https://my-blog.j8465383071.workers.dev/images/ProjectDocs/15-design-logical-replication/pa-pub.png">&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">lsn 1-10
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> d1 &lt;span class="m">1&lt;/span> &lt;span class="m">4&lt;/span> collect 阻塞 &lt;span class="m">1&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> d2 &lt;span class="m">2&lt;/span> &lt;span class="m">5&lt;/span> &lt;span class="m">2&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> d3 &lt;span class="m">3&lt;/span> &lt;span class="m">6&lt;/span> &lt;span class="m">3&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h3 id="122-发布端与订阅端流复制协议">1.2.2 发布端与订阅端流复制协议&lt;/h3>
&lt;h4 id="一握手阶段">一、握手阶段&lt;/h4>
&lt;p>订阅端与发布端建立连接时，订阅端会根据CRETE SUBSCRIPTION语法设置的参数，生成连接命令，根据连接命令，发布端和订阅端决定采用哪种通信协议，究竟是采用事务复制协议（旧版本）还是流复制协议（新版本）。&lt;/p>
&lt;h5 id="事务复制协议旧版本">事务复制协议（旧版本）&lt;/h5>
&lt;p>订阅端发送的连接命令如下：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sql" data-lang="sql">&lt;span class="line">&lt;span class="cl">&lt;span class="n">START_REPLICATION&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">SLOT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;$slot_name&amp;#34;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">LOGICAL&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="err">$&lt;/span>&lt;span class="n">start_lsn&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">proto_version&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;3&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">publication_names&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;&amp;#34;$publication_name&amp;#34;&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h5 id="流复制协议新版本">流复制协议（新版本）&lt;/h5>
&lt;p>如果CRETE SUBSCRIPTION时，指定worker_number&amp;gt;1，即启用并行逻辑复制机制，将使用新的连接命令，订阅端发送的连接命令如下：&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-sql" data-lang="sql">&lt;span class="line">&lt;span class="cl">&lt;span class="n">START_REPLICATION&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">SLOT&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s2">&amp;#34;$slot_name&amp;#34;&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">LOGICAL&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="err">$&lt;/span>&lt;span class="n">start_lsn&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="w"> &lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">proto_version&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;3&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">publication_names&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;&amp;#34;$publication_name&amp;#34;&amp;#39;&lt;/span>&lt;span class="err">，&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">streaming&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;extreme&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="n">parallel&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">decode&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">num&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;20&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">max&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">recordbuffer&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">memory&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;100&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="k">max&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">txn&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="k">in&lt;/span>&lt;span class="o">-&lt;/span>&lt;span class="n">memory&lt;/span>&lt;span class="w"> &lt;/span>&lt;span class="s1">&amp;#39;100&amp;#39;&lt;/span>&lt;span class="p">)&lt;/span>&lt;span class="w">
&lt;/span>&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>上述命令中新增了多个参数：&lt;/p></description></item></channel></rss>