当前位置: 首页 > news >正文

对OceanBase中的配置项与系统变量,合法性检查实践

在“OceanBase 配置项&系统变量实现及应用详解”的系列文章中,我们已经对配置项和系统变量的源码进行了解析。当涉及到新增配置项或系统变量时,通常会为其指定一个明确的取值范围或定义一个专门的合法性检查函数。本文将详细阐述在不同情境下,应如何对配置项和系统变量进行合法性检查。

配置项的合法性检查

配置项通常可以直接设定其取值范围,或者根据需要自定义合法性检查函数。此外,在某些情况下,还需要通过访问特定的配置项甚至系统变量,才能确定是否满足修改条件

常规检查

在定义配置项时,对于基础类型的数据,一般会指定一个“取值范围”。比如[0,100]"表示0到100之间的整数,方括号表示包含0和100;"[0M,)"表示范围从0到无穷大,"M"是数据的单位,它还可以是"K"、"G"等。

DEF_INT(cpu_count, OB_CLUSTER_PARAMETER, "0", "[0,]","the number of CPU\\'s in the system. ""If this parameter is set to zero, the number will be set according to sysconf; ""otherwise, this parameter is used. Range: [0,+∞) in integer",ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));

cpu_count 合法性检查示例:

对于有的配置项,无法用一个简单的字符串来描述它的取值范围,就需要定义一个专门的检查函数。

DEF_STR_WITH_CHECKER(default_compress_func, OB_CLUSTER_PARAMETER, "zstd_1.3.8",common::ObConfigCompressFuncChecker,"default compress function name for create new table, ""values: none, lz4_1.0, snappy_1.0, zlib_1.0, zstd_1.0, zstd_1.3.8",ObParameterAttr(Section::OBSERVER, Source::DEFAULT, EditLevel::DYNAMIC_EFFECTIVE));

合法性检查类有固定的模板可以使用,只需模仿已有的结构定义即可。关键在于check函数的功能,比如 ObConfigCompressFuncChecker::check 函数,会去检查传入的值是否在指定的 compress_funcs 数组中,如果不是则返回 is_valid = false,表示参数不合法,那么最终就会修改失败。

bool ObConfigCompressFuncChecker::check(const ObConfigItem &t) const
{bool is_valid = false;for (int i = 0; i < ARRAYSIZEOF(common::compress_funcs) && !is_valid; ++i) {if (0 == ObString::make_string(compress_funcs[i]).case_compare(t.str())) {is_valid = true;}}return is_valid;
}// 在某个头文件中定义
const char *const compress_funcs[] =
{"lz4_1.0","none","snappy_1.0","zstd_1.0","zstd_1.3.8","lz4_1.9.1",
};

default_compress_func 合法性检查示例:

特殊检查

检查集群配置项

有的配置项可能会依赖其他配置项的值,比如A必须大于B、A*B要小于C等要求,这时候就需要在检查函数中访问其他配置项的值,从而判断当前传入的新值是否符合要求。

例如租户配置项 max_stale_time_for_weak_consistency,不能小于集群配置项 weak_read_version_refresh_interval(超时时间必须大于刷新时间,不然来不及刷新很可能会超时),那么在它的 check 函数中,可以通过全局的 GCONF 对象访问集群配置项的值。

bool ObConfigStaleTimeChecker::check(const ObConfigItem &t) const
{bool is_valid = false;int64_t stale_time = ObConfigTimeParser::get(t.str(), is_valid);if (is_valid) {is_valid = (stale_time >= GCONF.weak_read_version_refresh_interval);if (!is_valid) {LOG_USER_ERROR(OB_NOT_SUPPORTED, "max_stale_time_for_weak_consistency violate"" weak_read_version_refresh_interval,");}}return is_valid;
}

max_stale_time_for_weak_consistency 合法性检查示例:

检查租户配置项

对于某些配置项,可能需要跟另一个租户配置项进行对比,而租户配置项存在多个实例,显然无法直接通过 GCONF 访问。

以 partition_balance_schedule_interval 为例,首先定义一个常量字符串 PARTITION_BALANCE_SCHEDULE_INTERVAL 来表示该配置项,在配置项预检查函数 set_config_pre_hook 中,如果 strcmp 匹配到该配置项,则可以进行后续的检查。遍历本次更新涉及到的所有 tenant_id(注意不是所有租户,只是当前修改命令涉及的租户),依次获取每个租户的 tenant_config,从中取出配置项 balancer_idle_time,然后与传入的值进行对比,若所有租户全部检查通过则可以修改。

	} else if (0 == STRCMP(item->name_.ptr(), PARTITION_BALANCE_SCHEDULE_INTERVAL)) {const int64_t DEFAULT_BALANCER_IDLE_TIME = 10 * 1000 * 1000L; // 10sfor (int i = 0; i < item->tenant_ids_.count() && valid; i++) {const uint64_t tenant_id = item->tenant_ids_.at(i);omt::ObTenantConfigGuard tenant_config(TENANT_CONF(tenant_id));int64_t balancer_idle_time = tenant_config.is_valid() ? tenant_config->balancer_idle_time : DEFAULT_BALANCER_IDLE_TIME;int64_t interval = ObConfigTimeParser::get(item->value_.ptr(), valid);if (valid) {if (0 == interval) {valid = true;} else if (interval >= balancer_idle_time) {valid = true;} else {valid = false;char err_msg[DEFAULT_BUF_LENGTH];(void)snprintf(err_msg, sizeof(err_msg), "partition_balance_schedule_interval of tenant %ld, ""it should not be less than balancer_idle_time", tenant_id);LOG_USER_ERROR(OB_INVALID_ARGUMENT, err_msg);}}if (!valid) {ret = OB_INVALID_ARGUMENT;LOG_WARN("config invalid", KR(ret), K(*item), K(balancer_idle_time), K(tenant_id));}}

partition_balance_schedule_interval 合法性检查示例:

  1. 修改所有租户的 partition_balance_schedule_interval = 1800s 失败,因为其中一个租户 perf 的 balancer_idle_time = 2000s,而 partition_balance_schedule_interval 不能小于 balancer_idle_time,所以 perf 租户无法修改,导致整个修改操作失败;
  2. 修改 test 租户的 partition_balance_schedule_interval = 1800s 成功,因为 test 租户的 balancer_idle_time = 10s,满足要求;
  3. 修改 perf 租户的 partition_balance_schedule_interval = 1800s 失败,因为 perf 租户的 balancer_idle_time = 2000s,不满足要求;
  4. 修改 sys 租户(当前租户为sys租户)的 partition_balance_schedule_interval = 1800s 成功,因为 sys 租户的 balancer_idle_time = 10s,满足要求;

1702260734

检查全局系统变量

配置项还可能受到系统变量的影响,有时也需要检查全局系统变量的值,这就要从schema中获取系统变量进行比较。

以 max_stale_time_for_weak_consistency为例,同样地,首先为目标配置项定义一个常量字符串 WEAK_READ_VERSION_REFRESH_INTERVAL。在配置项预检查函数 set_config_pre_hook 中,如果 strcmp 匹配到该配置项,则可以进行后续的检查,代码较多的情况下可以封装一个函数(check_weak_read_version_refresh_interval)用于检查合法性。

const char* const WEAK_READ_VERSION_REFRESH_INTERVAL = "weak_read_version_refresh_interval";int ObRootService::set_config_pre_hook(obrpc::ObAdminSetConfigArg &arg)
{} else if (0 == STRCMP(item->name_.ptr(), WEAK_READ_VERSION_REFRESH_INTERVAL)) {int64_t refresh_interval = ObConfigTimeParser::get(item->value_.ptr(), valid);if (valid && OB_FAIL(check_weak_read_version_refresh_interval(refresh_interval, valid))) {LOG_WARN("check refresh interval failed ", KR(ret), K(*item));} else if (!valid) {ret = OB_INVALID_ARGUMENT;LOG_WARN("config invalid", KR(ret), K(*item));}

check_weak_read_version_refresh_interval 函数先从 schema_service_中获取所有租户的 id,然后对于每个租户,依次从 schema_service_中获取 ob_max_read_stale_time 的值,再与当前传入的值进行对比,如果不合法则返回 false,所以租户都检查通过则返回 true。

int ObRootService::check_weak_read_version_refresh_interval(int64_t refresh_interval, bool &valid)
{......if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(OB_SYS_TENANT_ID, sys_schema_guard))) {LOG_WARN("get sys schema guard failed", KR(ret));} else if (OB_FAIL(sys_schema_guard.get_tenant_ids(tenant_ids))) {LOG_WARN("get tenant ids failed", KR(ret));} else {......for (int64_t i = 0; OB_SUCC(ret) && valid && i < tenant_ids.count(); i++) {tenant_id = tenant_ids[i];if (OB_FAIL(GCTX.schema_service_->get_tenant_schema_guard(tenant_id, schema_guard))) {LOG_WARN("get schema guard failed", KR(ret), K(tenant_id));} else if (OB_FAIL(schema_guard.get_tenant_system_variable(tenant_id,OB_SV_MAX_READ_STALE_TIME, var_schema))) {LOG_WARN("get tenant system variable failed", KR(ret), K(tenant_id));} else if (OB_FAIL(var_schema->get_value(NULL, NULL, obj))) {LOG_WARN("get value failed", KR(ret), K(tenant_id), K(obj));} else if (OB_FAIL(obj.get_int(session_max_stale_time))) {LOG_WARN("get int failed", KR(ret), K(tenant_id), K(obj));} else if (session_max_stale_time != share::ObSysVarFactory::INVALID_MAX_READ_STALE_TIME&& refresh_interval > session_max_stale_time) {valid = false;LOG_USER_ERROR(OB_INVALID_ARGUMENT,"weak_read_version_refresh_interval is larger than ob_max_read_stale_time");}}}

weak_read_version_refresh_interval 合法性检查示例:

  1. 修改 session 变量 ob_max_read_stale_time = 2s,然后修改 weak_read_version_refresh_interval = 3s 成功,因为session变量不影响配置项的修改;
  2. 修改 global 变量 ob_max_read_stale_time = 2s 失败,因为 ob_max_read_stale_time(系统变量)需要大于等于 weak_read_version_refresh_interval(配置项);
  3. 修改 global 变量 ob_max_read_stale_time = 3s,然后修改 weak_read_version_refresh_interval = 4s 失败,因为global变量的值可以影响配置项的修改;

系统变量的合法性检查

系统变量同样支持多种合法性检查方式,以便应对不同场景的需求。

常规检查

与配置项类似,在定义系统变量时也可以指定取值范围。

例如 connect_timeout,设置了"min_val"和"max_val"字段,取值范围就是[2, 31536000],不需要自己增加额外的代码,现有的框架会自动进行范围检查。

"connect_timeout": {"id": 22,"name": "connect_timeout","default_value": "10","base_value": "10","data_type": "int","info": " ","flags": "GLOBAL","min_val": "2","max_val": "31536000","publish_version": "","info_cn": "","background_cn": "","ref_url": ""},

connect_timeout 范围检查示例:

有的系统变量是字符串类型,无法用简单的数值表示取值范围,可以在 update_global_variables 函数中增加额外的检查代码。例如 ob_log_level,调用 OB_LOGGER.parse_check 函数进行检查,返回 OB_SUCCESS 表示检查通过。

	} else if (set_var.var_name_ == OB_SV_LOG_LEVEL) {ObString log_level;if (OB_FAIL(val.get_varchar(log_level))) {LOG_WARN("fail get varchar", K(val), K(ret));} else if (0 == log_level.case_compare("disabled")) {//allowed for variables} else if (OB_FAIL(OB_LOGGER.parse_check(log_level.ptr(), log_level.length()))) {LOG_WARN("Log level parse check error", K(log_level), K(ret));}

ob_log_level 合法性检查示例:

特殊检查

同样的,系统变量也需要访问其他的配置项或者变量,从而判断传入值的合法性。

检查集群配置项

以 ob_max_read_stale_time 为例,如果是global变量,可以在 update_global_variables 函数中,通过 GCONF 获取其他集群级别配置项的值,对比当前传入的值是否合法,不合法则返回 OB_INVALID_ARGUMENT。

int ObVariableSetExecutor::update_global_variables(
{......} else if (set_var.var_name_ == OB_SV_MAX_READ_STALE_TIME) {int64_t max_read_stale_time = 0;if (OB_FAIL(val.get_int(max_read_stale_time))) {LOG_WARN("fail to get int value", K(ret), K(val));} else if (max_read_stale_time != ObSysVarFactory::INVALID_MAX_READ_STALE_TIME &&max_read_stale_time < GCONF.weak_read_version_refresh_interval) {ret = OB_INVALID_ARGUMENT;LOG_USER_ERROR(OB_INVALID_ARGUMENT,"max_read_stale_time is smaller than weak_read_version_refresh_interval");}

ob_max_read_stale_time 合法性检查示例:

如果是session变量,则可以在 process_session_variable 函数中调用相应的处理函数,相关的判断逻辑与global变量一致即可。

OB_INLINE int ObBasicSessionInfo::process_session_variable(ObSysVarClassType var, const ObObj &val,const bool check_timezone_valid/*true*/, const bool is_update_sys_var/*false*/)
{int ret = OB_SUCCESS;switch (var) {case SYS_VAR_OB_LOG_LEVEL: {OZ (process_session_log_level(val), val);break;}

检查租户配置项

目前代码中没有这样的例子,如果需要在更新系统变量时检查租户配置项,可以参考更新配置项时的做法。而且,系统变量只涉及当前租户,所以也只需要获取当前租户的配置项进行合法性检查。

检查系统变量

对于global变量,可以在 update_global_variables 函数中,先获取当前租户的 schema,然后取得需要的系统变量的值。获取的方式与“更新配置项时检查全局系统变量”类似,不再赘述。

对于session变量,在 process_session_variable 函数中,通过 sys_vars_cache_.get_xxx() 的方式获取其缓存值,检查通过后直接调用 sys_vars_cache_.set_xxx() 函数更新变量值即可。

小结

通过自定义的合法性检查手段,对配置项和系统变量的值进行检查,可以有效避免用户设置无效的、超出正常边界的值,进而影响系统稳定性和可用性。

至此,关于配置项和系统变量的使用方法和源码分析已经介绍完了,接下来还会有一些应用和问题排查相关的文章,感兴趣的同学可以关注下。

参考文档

如何新增配置项?

如何新增系统变量?

OceanBase 里的 schema 是什么?

相关文章:

对OceanBase中的配置项与系统变量,合法性检查实践

在“OceanBase 配置项&系统变量实现及应用详解”的系列文章中&#xff0c;我们已经对配置项和系统变量的源码进行了解析。当涉及到新增配置项或系统变量时&#xff0c;通常会为其指定一个明确的取值范围或定义一个专门的合法性检查函数。本文将详细阐述在不同情境下&#x…...

YOLOv8绝缘子边缘破损检测系统(可以从图片、视频和摄像头三种方式检测)

可检测图片和视频当中出现的绝缘子和绝缘子边缘是否出现破损&#xff0c;以及自动开启摄像头&#xff0c;进行绝缘子检测。基于最新的YOLO-v8训练的绝缘子检测模型和完整的python代码以及绝缘子的训练数据&#xff0c;下载后即可运行。&#xff08;效果视频&#xff1a;YOLOv8绝…...

【vim 学习系列文章 18 -- 选中行前后增加两行】

请阅读【嵌入式开发学习必备专栏 之 Vim】 文章目录 选中行前后增加两行1. 定义函数2. 创建快捷键映射3. 保存并重新加载 .vimrc使用方法 重新选中实现步骤 1: 定义函数步骤 2: 绑定快捷键保存并重新加载 .vimrc使用方法 选中行前后增加两行 为了在 Vim 中实现这个功能&#x…...

分布式系统接口限流方案

Git地址&#xff1a;https://gitee.com/deepjava/test-api-limit.git 方案一、 Guava工具包 实现单机版限流 具体代码见git 方案二、Redis lua脚本 实现分布式系统的接口限流 具体代码见git...

Flutter仿Boss-6.底部tab切换

效果 实现 图片资源采用boss包中的动画webp资源。Flutter采用Image加载webp动画。 遇到的问题 问题&#xff1a;Flutter加载webp再次加载无法再次播放动画问题 看如下代码&#xff1a; Image.asset(assets/images/xxx.webp,width: 40.w,height: 30.w, )运行的效果&#xf…...

深入理解机器学习:用Python构建您的第一个预测模型

在这个数据驱动的时代&#xff0c;机器学习技术正在成为各行各业的变革力量。无论是金融、医疗、零售还是教育&#xff0c;机器学习都在为业务决策提供支持&#xff0c;优化用户体验&#xff0c;并创造出全新的服务方式。今天&#xff0c;我们将一起走进机器学习的世界&#xf…...

redisson与redis集群检测心跳机制原理

redisson与redis集群检测心跳机制原理 1、ClusterConnectionManager.scheduleClusterChangeCheck 创建延时定时调度任务 2、monitorFuture group.schedule(new Runnable() { EventExecutorGroup 是 Netty 中用于管理一组 EventExecutor 的组件&#xff0c;它类似于 EventLoo…...

部署Redis

部署Redis过程简要记录 在家目录创建存放各类软件源码、安装文件、数据、日志、依赖等目录 cd /home/liqiang mkdir sourcecode software app log data lib tmp在 sourcecode 中下载Redis并解压 cd sourcecode wget http://download.redis.io/releases/redis-5.0.4.tar.gz t…...

性能测试-数据库优化二(SQL的优化、数据库拆表、分表分区,读写分离、redis)

数据库优化 explain select 重点&#xff1a; type类型&#xff0c;rows行数&#xff0c;extra SQL的优化 在写on语句时&#xff0c;将数据量小的表放左边&#xff0c;大表写右边where后面的条件尽可能用索引字段&#xff0c;复合索引时&#xff0c;最好按复合索引顺序写wh…...

44.基于SpringBoot + Vue实现的前后端分离-汽车租赁管理系统(项目 + 论文PPT)

项目介绍 本站是一个B/S模式系统&#xff0c;采用SpringBoot Vue框架&#xff0c;MYSQL数据库设计开发&#xff0c;充分保证系统的稳定性。系统具有界面清晰、操作简单&#xff0c;功能齐全的特点&#xff0c;使得基于SpringBoot Vue技术的汽车租赁管理系统设计与实现管理工作…...

2024届数字IC秋招-华为机试-数字芯片-笔试真题和答案(五)(含2022年和2023年)

文章目录 前言1、多比特信号A,时钟域clk_a存在从4’d11到4’d12的变化过程中,若时钟域clk_b直接采用D触发器采样,可能采样到数据是2、Bod由1变成0,Arb会如何变化3、减少片外DRAM的访问,而代之以片内SRAM访问,这样可以降低访问功耗,降低片外DRAM,同时加大片内SRAM能节省…...

Lua语法(四)——协程

参考链接: 系列链接: Lua语法(一) 系列链接: Lua语法(二)——闭包/日期和时间 系列链接: Lua语法(三)——元表与元方法 系列链接: Lua语法(四)——协程 系列链接: Lua语法(五)——垃圾回收 系列链接: Lua语法(六)——面相对象编程 Lua语法 四——协程 简介正文协程coroutine.c…...

LangChain-15 Manage Prompt Size 管理上下文大小,用Agent的方式询问问题,并去百科检索内容,总结后返回

背景描述 这一节内容比较复杂&#xff1a; 涉及到使用工具进行百科的检索&#xff08;有现成的插件&#xff09;有AgentExecutor来帮助我们执行后续由于上下文过大&#xff0c; 我们通过计算num_tokens&#xff0c;来控制我们的上下文 安装依赖 pip install --upgrade --qu…...

OR-TOOL 背包算法

起因&#xff1a;最近公司要发票自动匹配&#xff0c; 比如财务输入10000W块&#xff0c;找到发票中能凑10000的。然后可以快速核销。 废话不多&#xff0c; 一 官方文档 https://developers.google.cn/optimization/pack/knapsack?hlzh-cn 二 POM文件 <!--google 算法包…...

前端h5录音

时隔差不多半个月&#xff0c; 现在才来写这编博客。由于某些原因&#xff0c;我一直没有写&#xff0c;请大家原谅。前段时间开发了一个小模块。模块的主要功能就是有一个录音的功能。也就是说&#xff0c;模仿微信发送语音的功能一样。不多说&#xff0c;直接来一段代码 //自…...

Android Studio 使用Flutter开发第一个Web页面(进行中)

附上Flutter官方文档 1、新建Flutter项目&#xff08;需要勾选web选项&#xff09; 新建项目构成为&#xff1a; 2、配置 Flutter 使用 path 策略 官方文档 在main.dart中&#xff0c;需要导入flutter_web_plugins/url_strategy.dart包&#xff0c;并在main(){}函数中usePath…...

Vue.js组件精讲 第2章 基础:Vue.js组件的三个API:prop、event、slot

如果您已经对 Vue.js 组件的基础用法了如指掌&#xff0c;可以跳过本小节&#xff0c;不过当做复习稍读一下也无妨。 组件的构成 一个再复杂的组件&#xff0c;都是由三部分组成的&#xff1a;prop、event、slot&#xff0c;它们构成了 Vue.js 组件的 API。如果你开发的是一个…...

npm install 报 ERESOLVE unable to resolve dependency tree 异常解决方法

问题 在安装项目依赖时&#xff0c;很大可能会遇到安装不成功的问题&#xff0c;其中有一个很大的原因&#xff0c;可能就是因为你的npm版本导致的。 1.npm ERR! code ERESOLVE npm ERR! ERESOLVE unable to resolve dependency tree 2.ERESOLVE unable to resolve dependenc…...

RPC还是HTTP

RPC是一个远程调用的通讯协议 RPC要比HTTP快一些 1. HTTP体积大 原因是HTTP协议会带着一堆无用信息 HTTP由三部分组成 请求头 请求行 请求体 这三部分只有请求体是需要的 2. HTTP支持的序列化协议比较少 RPC支持更多轻量级的通讯协议 3. RPC协议支持定制...

Conda 常用命令总结

创建虚拟环境 conda create -n name python[your_version] 激活环境 conda activate name 退出环境 conda deactivate 查看虚拟环境 conda info --envs 删除虚拟环境 conda remove -n name --all 删除所有的安装包及cache(索引缓存、锁定文件、未使用过的包和tar包) …...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

Cursor实现用excel数据填充word模版的方法

cursor主页&#xff1a;https://www.cursor.com/ 任务目标&#xff1a;把excel格式的数据里的单元格&#xff0c;按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例&#xff0c;…...

DockerHub与私有镜像仓库在容器化中的应用与管理

哈喽&#xff0c;大家好&#xff0c;我是左手python&#xff01; Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库&#xff0c;用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

Xen Server服务器释放磁盘空间

disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...