【PostgreSQL内核学习(十八)—— (数据库表参数)】

数据库表参数

  • default_reloptions 函数
  • 案例

声明:本文的部分内容参考了他人的文章。在编写过程中,我们尊重他人的知识产权和学术成果,力求遵循合理使用原则,并在适用的情况下注明引用来源。
本文主要参考了《PostgresSQL数据库内核分析》一书,OpenGauss1.1.0 的开源代码和《OpenGauss数据库源码解析》一书以及OpenGauss社区学习文档

default_reloptions 函数

  default_reloptions 函数是一个选项解析器,用于处理与数据库关系(表或视图)相关的选项。它接受一个包含关系选项的参数,然后解析验证这些选项,将它们存储在一个特定的数据结构中(StdRdOptions)。这个函数的主要目的是允许用户或数据库管理员通过选项来自定义配置关系的各种属性和行为,例如填充因子自动化清理策略安全性设置。它是数据库系统中对关系配置的重要组成部分,以实现更好的性能行为控制
  default_reloptions 函数的作用是接收传入的关系选项(以二进制形式表示),然后将这些选项解析验证,最后将它们存储在一个特定的数据结构StdRdOptions)中,以便在数据库系统中配置管理关系的各种属性行为,如填充因子自动化清理策略安全性设置等。这个函数允许数据库管理员或应用程序开发人员根据需要自定义配置关系的行为和性能特性
  default_reloptions 函数源码如下所示:(路径:src/gausskernel/storage/access/common/reloptions.cpp

/* * 为使用StdRdOptions的任何内容(例如fillfactor和autovacuum)提供选项解析器* reloptions:传入的关系选项,以二进制形式表示* validate:指示是否进行验证的标志* kind:关系选项的类型,通常是RELOPT_KIND_HEAP或RELOPT_KIND_TOAST*/
bytea *default_reloptions(Datum reloptions, bool validate, relopt_kind kind)
{relopt_value *options = NULL;  // 存储解析后的选项值的数组StdRdOptions *rdopts = NULL;    // 存储最终结果的数据结构int numoptions;                 // 选项数量static const relopt_parse_elt tab[] = {// 定义选项名称、类型和存储位置的映射数组// 每个元素包括选项名称、数据类型和在StdRdOptions结构中的偏移量// 用于将选项值解析到对应的字段中// 更多选项可以在这里添加{ "fillfactor", RELOPT_TYPE_INT, offsetof(StdRdOptions, fillfactor) },{ "autovacuum_enabled", RELOPT_TYPE_BOOL, offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, enabled) },{ "autovacuum_vacuum_threshold", RELOPT_TYPE_INT,offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_threshold) },{ "autovacuum_analyze_threshold", RELOPT_TYPE_INT,offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, analyze_threshold) },{ "autovacuum_vacuum_cost_delay", RELOPT_TYPE_INT,offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_delay) },{ "autovacuum_vacuum_cost_limit", RELOPT_TYPE_INT,offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_cost_limit) },{ "autovacuum_freeze_min_age", RELOPT_TYPE_INT64,offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, freeze_min_age) },{ "autovacuum_freeze_max_age", RELOPT_TYPE_INT64,offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, freeze_max_age) },{ "autovacuum_freeze_table_age", RELOPT_TYPE_INT64,offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, freeze_table_age) },{ "autovacuum_vacuum_scale_factor", RELOPT_TYPE_REAL,offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, vacuum_scale_factor) },{ "autovacuum_analyze_scale_factor", RELOPT_TYPE_REAL,offsetof(StdRdOptions, autovacuum) + offsetof(AutoVacOpts, analyze_scale_factor) },{ "security_barrier", RELOPT_TYPE_BOOL, offsetof(StdRdOptions, security_barrier) },{ "enable_rowsecurity", RELOPT_TYPE_BOOL, offsetof(StdRdOptions, enable_rowsecurity) },{ "force_rowsecurity", RELOPT_TYPE_BOOL, offsetof(StdRdOptions, force_rowsecurity) },{ "enable_tsdb_delta", RELOPT_TYPE_BOOL, offsetof(StdRdOptions, enable_tsdb_delta) },{ "tsdb_deltamerge_interval", RELOPT_TYPE_INT, offsetof(StdRdOptions, tsdb_deltamerge_interval) },{ "tsdb_deltamerge_threshold", RELOPT_TYPE_INT, offsetof(StdRdOptions, tsdb_deltamerge_threshold) },{ "tsdb_deltainsert_threshold", RELOPT_TYPE_INT, offsetof(StdRdOptions, tsdb_deltainsert_threshold) },{ "max_batchrow", RELOPT_TYPE_INT, offsetof(StdRdOptions, max_batch_rows) },{ "deltarow_threshold", RELOPT_TYPE_INT, offsetof(StdRdOptions, delta_rows_threshold) },{ "partial_cluster_rows", RELOPT_TYPE_INT, offsetof(StdRdOptions, partial_cluster_rows) },{ "internal_mask", RELOPT_TYPE_INT, offsetof(StdRdOptions, internalMask) },{ "orientation", RELOPT_TYPE_STRING, offsetof(StdRdOptions, orientation) },{ "compression", RELOPT_TYPE_STRING, offsetof(StdRdOptions, compression) },{"table_access_method", RELOPT_TYPE_STRING, offsetof(StdRdOptions, table_access_method)},{ "ttl", RELOPT_TYPE_STRING, offsetof(StdRdOptions, ttl) },{ "period", RELOPT_TYPE_STRING, offsetof(StdRdOptions, period) },{ "string_optimize", RELOPT_TYPE_STRING, offsetof(StdRdOptions, string_optimize) },{ "partition_interval", RELOPT_TYPE_STRING, offsetof(StdRdOptions, partition_interval) },{ "time_column", RELOPT_TYPE_STRING, offsetof(StdRdOptions, time_column) },{ "ttl_interval", RELOPT_TYPE_STRING, offsetof(StdRdOptions, ttl_interval) },{ "gather_interval", RELOPT_TYPE_STRING, offsetof(StdRdOptions, gather_interval) },{ "version", RELOPT_TYPE_STRING, offsetof(StdRdOptions, version) },{ "compresslevel", RELOPT_TYPE_INT, offsetof(StdRdOptions, compresslevel) },{ "ignore_enable_hadoop_env", RELOPT_TYPE_BOOL, offsetof(StdRdOptions, ignore_enable_hadoop_env) },{ "append_mode", RELOPT_TYPE_STRING, offsetof(StdRdOptions, append_mode) },{ "merge_list", RELOPT_TYPE_STRING, offsetof(StdRdOptions, merge_list) },{ "rel_cn_oid", RELOPT_TYPE_INT, offsetof(StdRdOptions, rel_cn_oid) },{ "append_mode_internal", RELOPT_TYPE_INT, offsetof(StdRdOptions, append_mode_internal) },{ "start_ctid_internal", RELOPT_TYPE_STRING, offsetof(StdRdOptions, start_ctid_internal) },{ "end_ctid_internal", RELOPT_TYPE_STRING, offsetof(StdRdOptions, end_ctid_internal) },{ "user_catalog_table", RELOPT_TYPE_BOOL, offsetof(StdRdOptions, user_catalog_table) },{ "hashbucket", RELOPT_TYPE_BOOL, offsetof(StdRdOptions, hashbucket) },{ "primarynode", RELOPT_TYPE_BOOL, offsetof(StdRdOptions, primarynode) },{ "on_commit_delete_rows", RELOPT_TYPE_BOOL, offsetof(StdRdOptions, on_commit_delete_rows)},{ "wait_clean_gpi", RELOPT_TYPE_STRING, offsetof(StdRdOptions, wait_clean_gpi)}};// 解析传入的关系选项,将其存储在options数组中,并返回选项数量options = parseRelOptions(reloptions, validate, kind, &numoptions);/* if none set, we're done */// 如果没有设置任何选项,则返回NULLif (numoptions == 0)return NULL;// 为rdopts分配内存,根据StdRdOptions结构的大小以及选项数量rdopts = (StdRdOptions *)allocateReloptStruct(sizeof(StdRdOptions), options, numoptions);// 使用解析后的选项填充rdopts结构,将选项值分配到对应的字段中fillRelOptions((void *)rdopts, sizeof(StdRdOptions), options, numoptions, validate, tab, lengthof(tab));// 释放options数组中的字符串值的内存for (int i = 0; i < numoptions; i++) {if (options[i].gen->type == RELOPT_TYPE_STRING && options[i].isset)pfree(options[i].values.string_val);}pfree(options);// 返回结果,以bytea类型的数据返回StdRdOptions结构return (bytea *)rdopts;
}

  其中,表(或关系)的选项的配置如下表所示:

参 数含 义
fillfactor设置表的填充因子,用于指定在表的数据页中保留多少空间,以便将来插入新行。
autovacuum_enabled一个布尔值,指定是否启用了自动化清理和分析。
autovacuum_vacuum_threshold自动清理操作的触发阈值,当表中的行数超过此阈值时,将执行自动清理操作。
autovacuum_analyze_threshold自动分析操作的触发阈值,当表中的行数超过此阈值时,将执行自动分析操作。
autovacuum_vacuum_cost_delay自动清理操作的成本延迟,以控制其执行速度。
autovacuum_vacuum_cost_limit自动清理操作的成本限制,以控制资源消耗。
autovacuum_freeze_min_age触发自动冻结的最小年龄,用于维护事务ID冻结的表。
autovacuum_freeze_max_age触发自动冻结的最大年龄,用于维护事务ID冻结的表。
autovacuum_freeze_table_age自动冻结表的年龄,用于维护事务ID冻结的表。
autovacuum_vacuum_scale_factor自动清理的比例因子。
autovacuum_analyze_scale_factor自动分析的比例因子。
security_barrier一个布尔值,指定是否启用了安全屏障。
enable_rowsecurity一个布尔值,指定是否启用了行级安全性。
force_rowsecurity一个布尔值,指定是否强制启用了行级安全性。
enable_tsdb_delta一个布尔值,指定是否启用了时序数据库(TSDB)的增量数据存储。
tsdb_deltamerge_intervalTSDB增量数据合并的时间间隔。
tsdb_deltamerge_thresholdTSDB增量数据合并的阈值。
tsdb_deltainsert_thresholdTSDB增量数据插入的阈值。
max_batchrow最大批量行数。
deltarow_threshold增量行的阈值。
partial_cluster_rows部分聚集行的数量。
internal_mask内部掩码。
orientation表的方向。
compression数据的压缩方式。
table_access_method表的访问方法。
ttl表的生存时间。
period表的周期。
string_optimize字符串优化。
partition_interval分区间隔。
time_column时间列。
ttl_interval生存时间间隔。
gather_interval聚集间隔。
version版本。
compresslevel压缩级别。
ignore_enable_hadoop_env是否忽略启用Hadoop环境。
append_mode附加模式。
merge_list合并列表。
rel_cn_oid关系CN OID
append_mode_internal内部附加模式。
start_ctid_internal内部起始CTID
end_ctid_internal内部结束CTID
user_catalog_table是否为用户目录表。
hashbucket是否为哈希桶。
primarynode是否为主节点。
on_commit_delete_rows提交时删除行。
wait_clean_gpi等待清理GPI

  这些选项配置了表的各种属性和行为,以满足特定的数据库需求。

案例

  接下来,我们通过几个案例来观察其中的几个代表参数的实际作用,来了解一下这些参数的意义。具体案例如下:

1. 创建存储表,执行以下 SQL 语句

CREATE TABLE test_table (id serial PRIMARY KEY,name text
) WITH (fillfactor = 70,  -- 设置填充因子autovacuum_enabled = true,  -- 启用自动清理和分析autovacuum_vacuum_threshold = 1000,  -- 自动清理触发阈值autovacuum_analyze_threshold = 500,  -- 自动分析触发阈值autovacuum_vacuum_cost_delay = 10,  -- 自动清理成本延迟autovacuum_vacuum_cost_limit = 1000,  -- 自动清理成本限制compression = 'lz4'  -- 数据压缩方式
);postgres=# \d+ test_tableTable "public.test_table"Column |  Type   |                        Modifiers                        | Storage  | Stats target | Description
--------+---------+---------------------------------------------------------+----------+--------------+-------------id     | integer | not null default nextval('test_table_id_seq'::regclass) | plain    |              |name   | text    |                                                         | extended |              |
Has OIDs: no
Options: orientation=column, autovacuum_enabled=true, autovacuum_analyze_threshold=500, compression=low

2. 插入一些示例数据到列存储表中

DO $$ 
DECLAREcounter INT := 1;
BEGINFOR counter IN 1..1500 LOOPINSERT INTO test_table (name) VALUES ('Item ' || counter);END LOOP;
END $$;postgres=# select * from test_table;id  |   name
------+-----------1 | Item 12 | Item 23 | Item 34 | Item 45 | Item 56 | Item 67 | Item 78 | Item 89 | Item 910 | Item 1011 | Item 1112 | Item 1213 | Item 1314 | Item 1415 | Item 1516 | Item 1617 | Item 1718 | Item 1819 | Item 1920 | Item 2021 | Item 2122 | Item 2223 | Item 2324 | Item 2425 | Item 2526 | Item 2627 | Item 2728 | Item 2829 | Item 2930 | Item 3031 | Item 3132 | Item 3233 | Item 3334 | Item 3435 | Item 3536 | Item 3637 | Item 3738 | Item 3839 | Item 39
--More--

3. 执行自动分析并查看统计信息

SELECT schemaname,relname,last_vacuum,last_autovacuum,last_analyze,last_autoanalyze,vacuum_count,autovacuum_count,analyze_count,autoanalyze_count
FROM pg_stat_all_tables
WHERE relname = 'test_table';schemaname |  relname   | last_vacuum | last_autovacuum |         last_analyze          |       last_autoanalyze        | vacuum_count | autovacuum_count | anal
yze_count | autoanalyze_count
------------+------------+-------------+-----------------+-------------------------------+-------------------------------+--------------+------------------+-----
----------+-------------------public     | test_table |             |                 | 2023-10-07 11:32:20.377228+08 | 2023-10-07 11:32:20.377228+08 |            0 |                0 |1 |                 1
(1 row)

  可以看到,当表中的数据量达到自动分触发阈值autovacuum_analyze_threshold ,则会执行自动分析 autoanalyze

4. 执行自动清理

  在PostgreSQL数据库中,自动触发autovacuum_vacuum_threshold选项所定义的自动清理autovacuum)操作通常由数据库自身的内部机制控制autovacuum_vacuum_threshold是一个配置选项,它定义了当表中的行数达到指定阈值时,自动触发VACUUM操作的条件

要触发自动清理,需要满足以下条件:

  1. 表的行数超过了autovacuum_vacuum_threshold所定义的阈值
  2. 自动清理(autovacuum)进程处于活动状态,通常是后台运行的自动清理进程

  自动清理进程会定期检查表的状态并根据一系列配置选项来决定是否执行VACUUM操作。autovacuum_vacuum_threshold只是其中之一。其他配置选项还包括autovacuum_analyze_thresholdautovacuum_freeze_max_age等,它们影响了自动清理的行为。
  需要注意的是autovacuum进程通常会数据库空闲时执行自动清理操作,以避免干扰正在进行的活动查询和事务。此外,autovacuum的行为也可以通过其他配置选项进行微调,以满足特定应用场景的需求。
  总之,要触发autovacuum_vacuum_threshold自动清理,需要确保表的行数达到了指定阈值,并确保autovacuum进程处于活动状态,它会自动监测并执行相应的清理操作。

SELECT schemaname,relname,last_vacuum,last_autovacuum,last_analyze,last_autoanalyze,vacuum_count,autovacuum_count,analyze_count,autoanalyze_count
FROM pg_stat_all_tables
WHERE relname = 'test_table';schemaname |  relname   |          last_vacuum          | last_autovacuum |         last_analyze          |       last_autoanalyze        | vacuum_count | autov
acuum_count | analyze_count | autoanalyze_count
------------+------------+-------------------------------+-----------------+-------------------------------+-------------------------------+--------------+------
------------+---------------+-------------------public     | test_table | 2023-10-07 15:35:41.430136+08 |2023-10-07 15:35:41.430136+08| 2023-10-07 15:32:22.660942+08 | 2023-10-07 15:32:22.660942+08 |            1 |0 |             2 |                 2
(1 row)

  这里不一一列举表(或关系)的选项的配置的案例,如需要详细了解可以查询相关手册。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/100361.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【2023研电赛】安谋科技企业命题特别奖:面向独居老人的智能居家监护系统

本文为2023年第十八届中国研究生电子设计竞赛安谋科技企业命题特别奖分享&#xff0c;参加极术社区的【有奖活动】分享2023研电赛作品扩大影响力&#xff0c;更有丰富电子礼品等你来领&#xff01;&#xff0c;分享2023研电赛作品扩大影响力&#xff0c;更有丰富电子礼品等你来…

Meta Semantic Template for Evaluation of Large Language Models

本文是LLM系列文章&#xff0c;针对《Meta Semantic Template for Evaluation of Large Language Models》的翻译。 大型语言模型评估的元语义模板 摘要1 引言2 相关工作3 方法4 实验5 结论 摘要 大型语言模型(llm)是否真正理解语言的语义&#xff0c;或者只是记住训练数据?…

dart的Websocket为什么找不到onOpen方法?

我主要使用的是JAVA&#xff0c;而JAVA使用Websocket时&#xff0c;Websocket一定会有个onOpen方法。 ClientEndpoint public class WebsocketListener {OnOpenpublic void onOpen(Session session) throws IOException {}OnMessagepublic void onMessage(ByteBuffer byteBuff…

按关键字搜索淘宝商品API接口获取商品销量、优惠价、商品标题等参数示例

关键词搜索商品接口的作用是提供搜索功能&#xff0c;让用户根据关键词在电商平台上搜索商品&#xff0c;并根据搜索条件和偏好获取相关的商品列表和推荐结果&#xff0c;提高用户购物体验和准确度。对于电商平台而言&#xff0c;这个接口也能帮助用户发现更多商品、提升销量和…

PostgreSQL安装错误:Problem running post-install step

问题描述 安装包&#xff1a;pgpostgresql-14.9-1-windows-x64 postgresql-16.0-1-windows-x64 采取措施 一、 首先安装的是16版本的程序&#xff0c;报错后卸载尝试安装14版本软件&#xff0c;依旧报错。 二、 网上搜索&#xff0c;发现该博客&#xff1a; PostgreSQL安…

Springboot 接收POST、json、文本数据实践

一、接收 Form 表单数据 1&#xff0c;基本的接收方法 &#xff08;1&#xff09;下面样例 Controller 接收 form-data 格式的 POST 数据&#xff1a; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.Request…

windows平台FairMOT的实现

环境&#xff1a;python3.6pytorch1.1.0torchvision0.3.0cuda9.2vs2015 该项目需要装3个c库&#xff08;dcn_v2&#xff0c;apex&#xff0c;cython_bbox&#xff09;特别坑&#xff0c;各种环境不匹配&#xff0c;各种bug。本人c小白&#xff0c;但是一路摸索总算成功了。下面…

数学术语之源——单射(injection),满射(surjection),双射(bijection)

1. 单射或入射(injection) 1.1 injection的词源 词义为“a forcing of a fluid into a body (with a syringe, etc.)(迫使液体进入体内(使用注射器等))”(始于15世纪早期)&#xff0c;来自古法语“iniection ”(14世纪)或者直接来自拉词语“iniectionem (主格‘iniectio’)”&…

游戏软件开发与应用软件开发有什么不同呢?

游戏软件开发和应用软件开发是两种不同类型的软件开发&#xff0c;它们在许多方面都有不同之处。以下是它们之间的一些主要区别&#xff1a; 目标用户群体&#xff1a; 游戏软件开发的主要目标是提供娱乐和休闲体验&#xff0c;通常面向广大的游戏玩家群体。游戏软件的设计和开…

【嵌入式】常用串口协议与转换芯片详解

文章目录 0 前言1 一个通信的协议的组成2 常用协议名词解释2.1 UART2.2 RS-2322.3 RS-4852.4 RS-4222.5 比较 3 常用的芯片 0 前言 最近有点想研究USB协议&#xff0c;正好也看到有评论说对如何选择USB转串口模块有些疑惑&#xff0c;其实我也一直很想写一篇关于串口的总结式的…

修炼k8s+flink+hdfs+dlink(四:k8s(二)组件)

一&#xff1a;控制平面组件。 控制平面组件会为集群做出全局决策&#xff0c;比如资源的调度。 以及检测和响应集群事件&#xff0c;例如当不满足部署的 replicas 字段时&#xff0c; 要启动新的 pod&#xff09;。 1. kube-apiserver。 该组件负责公开了 Kubernetes API&a…

浏览器详解(四) 渲染

大家好&#xff0c;我是半虹&#xff0c;这篇文章来讲浏览器渲染 1、基本介绍 浏览器是多进程多线程的架构&#xff0c;包括有浏览器进程、渲染器进程、GPU 进程、插件进程等 在上篇文章中我们介绍过浏览器进程&#xff0c;作为浏览器主进程&#xff0c;负责浏览器基本界面的…

天龙八部服务端Public目录功能讲解

PublicDataAIScript文件夹中 script(0~210).ai怪物AI脚本设定如是否主动攻击是否使用技能 PublicDataScript文件夹中 eventbossgroupbg_BossAI_CreateMonster.lua 是BOSS群 刷小怪通用脚本 PublicDataScript文件夹中 eventbossgroupbg_CangShan.lua 苍山 BOSS群刷新脚本 Public…

创建properties资源文件,并由spring组件类获取资源文件

1.1 创建资源文件file-upload-dev.properties #文件上传地址 file.imageUserFaceLocation=/workspaces/images/foodie/faces #图片访问地址 file.imageServerUrl=http://localhost:8088/foodie/faces1.2 创建spring组件获取资源文件类FileUpload import org.springframework.…

超低延时直播技术演进之路-进化篇

一、概述 网络基础设施升级、音视频传输技术迭代、WebRTC 开源等因素&#xff0c;驱动音视频服务时延逐渐降低&#xff0c;使超低延时直播技术成为炙手可热的研究方向。实时音视频业务在消费互联网领域蓬勃发展&#xff0c;并逐渐向产业互联网领域加速渗透。经历了行业第一轮的…

Doris 2.0.1 DockerFile版 升级实战

1、Doris 2.0.1 DockerFile 的制作 参考 Doris 2.0.1 Dockerfile制作-CSDN博客 2、之前的Doris 集群通过 Docker容器进行的部署&#xff0c;需提前准备好Doris2.0.1的镜像包 参考&#xff1a; 集群升级 - Apache Doris Doris 升级请遵守不要跨两个及以上关键节点版本升级的…

Unix Network Programming Episode 78

‘getaddrinfo’ Function The gethostbyname and gethostbyaddr functions only support IPv4. The API for resolving IPv6 addresses went through several iterations, as will be described in Section 11.20(See 8.9.20); the final result is the getaddrinfo function…

ansible部署二进制k8s

简介 GitHub地址&#xff1a; https://github.com/chunxingque/ansible_install_k8s 本脚本通过ansible来快速安装和管理二进制k8s集群&#xff1b;支持高可用k8s集群和单机k8s集群地部署&#xff1b;支持不同版本k8s集群部署&#xff0c;一般小版本的部署脚本基本是通用的。 …

js文件的入口代码及需要入口代码的原因

1 在js解释器解释代码时&#xff0c;是从上往下逐条执行的&#xff0c;但是在js文件中&#xff0c;存在许多进行页面交互的代码&#xff0c;它们需要获取到当前按钮元素&#xff0c;比如&#xff1a;var btn document.querySelector(button), 如果将js文件写在了页面结…

java项目实现不停服更新的4种方案(InsCode AI 创作助手)

文章目录 1. Blue-Green 部署2. 滚动更新3. 使用负载均衡器4. 灰度发布 在软件开发和维护中&#xff0c;不停机更新是确保应用程序持续可用的关键任务之一。以下是四种常见的不停机更新策略及其示例&#xff1a; 1. Blue-Green 部署 概念&#xff1a; Blue-Green 部署是一种部…