PostgreSQL的学习心得和知识总结(一百五十八)|在线调优工具pgtune的实现原理和源码解析


注:提前言明 本文借鉴了以下博主、书籍或网站的内容,其列表如下:

1、参考书籍:《PostgreSQL数据库内核分析》
2、参考书籍:《数据库事务处理的艺术:事务管理与并发控制》
3、PostgreSQL数据库仓库链接,点击前往
4、日本著名PostgreSQL数据库专家 铃木启修 网站主页,点击前往
5、参考书籍:《PostgreSQL指南:内幕探索》,点击前往
6、参考书籍:《事务处理 概念与技术》
7、pgtune 官方git仓库,点击前往
8、pgtune 官方在线使用,点击前往


1、本文内容全部来源于开源社区 GitHub和以上博主的贡献,本文也免费开源(可能会存在问题,评论区等待大佬们的指正)
2、本文目的:开源共享 抛砖引玉 一起学习
3、本文不提供任何资源 不存在任何交易 与任何组织和机构无关
4、大家可以根据需要自行 复制粘贴以及作为其他个人用途,但是不允许转载 不允许商用 (写作不易,还请见谅 💖)
5、本文内容基于PostgreSQL master源码开发而成


在线调优工具pgtune的实现原理和源码解析

  • 文章快速说明索引
  • 功能使用背景说明
  • 功能实现源码解析



文章快速说明索引

学习目标:

做数据库内核开发久了就会有一种 少年得志,年少轻狂 的错觉,然鹅细细一品觉得自己其实不算特别优秀 远远没有达到自己想要的。也许光鲜的表面掩盖了空洞的内在,每每想到于此,皆有夜半临渊如履薄冰之感。为了睡上几个踏实觉,即日起 暂缓其他基于PostgreSQL数据库的兼容功能开发,近段时间 将着重于学习分享Postgres的基础知识和实践内幕。


学习内容:(详见目录)

1、在线调优工具pgtune的实现原理和源码解析


学习时间:

2024年11月24日 13:46:59


学习产出:

1、PostgreSQL数据库基础知识回顾 1个
2、CSDN 技术博客 1篇
3、PostgreSQL数据库内核深入学习


注:下面我们所有的学习环境是Centos8+PostgreSQL master +Oracle19C+MySQL8.0

postgres=# select version();version                                                   
------------------------------------------------------------------------------------------------------------PostgreSQL 18devel on x86_64-pc-linux-gnu, compiled by gcc (GCC) 8.5.0 20210514 (Red Hat 8.5.0-21), 64-bit
(1 row)postgres=##-----------------------------------------------------------------------------#SQL> select * from v$version;          BANNER        Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production	
BANNER_FULL	  Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production Version 19.17.0.0.0	
BANNER_LEGACY Oracle Database 19c EE Extreme Perf Release 19.0.0.0.0 - Production	
CON_ID 0#-----------------------------------------------------------------------------#mysql> select version();
+-----------+
| version() |
+-----------+
| 8.0.27    |
+-----------+
1 row in set (0.06 sec)mysql>

功能使用背景说明

在这里插入图片描述

作用:根据硬件调整 PostgreSQL 配置。

优点:

  1. 无需下载或安装任何东西
  2. 也可以离线工作
  3. 可以作为移动应用程序工作
  4. 开源

使用一下,如下是(常用TPCC)一个推荐配置:

在这里插入图片描述

接下来看一下其实现细节,使用上面比较简单,这里不再赘述。后面大家在使用过程中有问题,也可以直接去官方仓库下提问题!


注1:因为这个算是一个通用设置,所能提供的参数较少(如下) 在具体的使用中,其他相关参数的设置大家可以自行分析:

    const configData = [['max_connections', maxConnectionsVal],['shared_buffers', formatValue(sharedBuffersVal)],['effective_cache_size', formatValue(effectiveCacheSizeVal)],['maintenance_work_mem', formatValue(maintenanceWorkMemVal)],['checkpoint_completion_target', checkpointCompletionTargetVal],['wal_buffers', formatValue(walBuffersVal)],['default_statistics_target', defaultStatisticsTargetVal],['random_page_cost', randomPageCostVal],['effective_io_concurrency', effectiveIoConcurrencyVal],['work_mem', formatValue(workMemVal)],['huge_pages', hugePagesVal]]

注2:这不是标准答案,可以视为一种参考建议值 大家在使用中可以根据自己的实际情况进行调整!


可选的应用场景,有:

const dbTypeOptions = () => [{label: 'Web application',value: DB_TYPE_WEB},{label: 'Online transaction processing system',value: DB_TYPE_OLTP},{label: 'Data warehouse',value: DB_TYPE_DW},{label: 'Desktop application',value: DB_TYPE_DESKTOP},{label: 'Mixed type of application',value: DB_TYPE_MIXED}
]

因此大家要充分理解自己的业务情况!


功能实现源码解析

下面我们按照参数的顺序,挨个解释pgtune设置值的细节。

一、max_connections 这个值设置多少即为多少;若是没有设置 则使用下面的默认值:

参考点击:http://postgres.cn/docs/current/runtime-config-connection.html#GUC-MAX-CONNECTIONS

export const selectMaxConnections = createSelector([selectConnectionNum, selectDBType],(connectionNum, dbType) =>connectionNum? connectionNum // 设置的走设置值,而非下面的默认值: {[DB_TYPE_WEB]: 200,[DB_TYPE_OLTP]: 300,[DB_TYPE_DW]: 40,[DB_TYPE_DESKTOP]: 20,[DB_TYPE_MIXED]: 100}[dbType]
)

二、shared_buffers

参考点击:http://postgres.cn/docs/current/runtime-config-resource.html#GUC-SHARED-BUFFERS

export const selectSharedBuffers = createSelector([selectTotalMemoryInKb, selectDBType, selectOSType, selectDBVersion],(totalMemoryKb, dbType, osType, dbVersion) => {let sharedBuffersValue = {[DB_TYPE_WEB]: Math.floor(totalMemoryKb / 4),[DB_TYPE_OLTP]: Math.floor(totalMemoryKb / 4),[DB_TYPE_DW]: Math.floor(totalMemoryKb / 4),[DB_TYPE_DESKTOP]: Math.floor(totalMemoryKb / 16),[DB_TYPE_MIXED]: Math.floor(totalMemoryKb / 4)}[dbType]if (dbVersion < 10 && OS_WINDOWS === osType) {// Limit shared_buffers to 512MB on Windowsconst winMemoryLimit = (512 * SIZE_UNIT_MAP['MB']) / SIZE_UNIT_MAP['KB']if (sharedBuffersValue > winMemoryLimit) {sharedBuffersValue = winMemoryLimit}}return sharedBuffersValue}
)
  • 该参数通常设置建议为:totalMemoryKb的1/4 或 1/16(看业务场景)
  • 在pg10以下的Windows环境上,建议设置不超过 512MB

三、effective_cache_size 该参数通常建议设置为totalMemoryKb的 3/4

参考点击:http://postgres.cn/docs/current/runtime-config-query.html#GUC-EFFECTIVE-CACHE-SIZE

export const selectEffectiveCacheSize = createSelector([selectTotalMemoryInKb, selectDBType],(totalMemoryKb, dbType) =>({[DB_TYPE_WEB]: Math.floor((totalMemoryKb * 3) / 4),[DB_TYPE_OLTP]: Math.floor((totalMemoryKb * 3) / 4),[DB_TYPE_DW]: Math.floor((totalMemoryKb * 3) / 4),[DB_TYPE_DESKTOP]: Math.floor(totalMemoryKb / 4),[DB_TYPE_MIXED]: Math.floor((totalMemoryKb * 3) / 4)})[dbType]
)

四、maintenance_work_mem

参考点击:http://postgres.cn/docs/current/runtime-config-resource.html#GUC-MAINTENANCE-WORK-MEM

export const selectMaintenanceWorkMem = createSelector([selectTotalMemoryInKb, selectDBType, selectOSType],(totalMemoryKb, dbType, osType) => {let maintenanceWorkMemValue = {[DB_TYPE_WEB]: Math.floor(totalMemoryKb / 16),[DB_TYPE_OLTP]: Math.floor(totalMemoryKb / 16),[DB_TYPE_DW]: Math.floor(totalMemoryKb / 8),[DB_TYPE_DESKTOP]: Math.floor(totalMemoryKb / 16),[DB_TYPE_MIXED]: Math.floor(totalMemoryKb / 16)}[dbType]// Cap maintenance RAM at 2GB on servers with lots of memoryconst memoryLimit = (2 * SIZE_UNIT_MAP['GB']) / SIZE_UNIT_MAP['KB']if (maintenanceWorkMemValue >= memoryLimit) {if (OS_WINDOWS === osType) {// 2048MB (2 GB) will raise error at Windows, so we need remove 1 MB from itmaintenanceWorkMemValue = memoryLimit - (1 * SIZE_UNIT_MAP['MB']) / SIZE_UNIT_MAP['KB']} else {maintenanceWorkMemValue = memoryLimit}}return maintenanceWorkMemValue}
)
  • 该参数通常是totalMemoryKb的 1/16 或 1/8
  • 若是该值大于2G,则设置为2G

五、checkpoint_completion_target 设置为0.9

参考点击:http://postgres.cn/docs/current/runtime-config-wal.html#GUC-CHECKPOINT-COMPLETION-TARGET

export const selectCheckpointCompletionTarget = createSelector([],() => 0.9 // based on https://github.com/postgres/postgres/commit/bbcc4eb2
)

六、wal_buffers

参考点击:http://postgres.cn/docs/current/runtime-config-wal.html#GUC-WAL-BUFFERS

export const selectWalBuffers = createSelector([selectSharedBuffers], (sharedBuffersValue) => {// Follow auto-tuning guideline for wal_buffers added in 9.1, where it's// set to 3% of shared_buffers up to a maximum of 16MB.let walBuffersValue = Math.floor((3 * sharedBuffersValue) / 100)const maxWalBuffer = (16 * SIZE_UNIT_MAP['MB']) / SIZE_UNIT_MAP['KB']if (walBuffersValue > maxWalBuffer) {walBuffersValue = maxWalBuffer}// It's nice of wal_buffers is an even 16MB if it's near that number. Since// that is a common case on Windows, where shared_buffers is clipped to 512MB,// round upwards in that situationconst walBufferNearValue = (14 * SIZE_UNIT_MAP['MB']) / SIZE_UNIT_MAP['KB']if (walBuffersValue > walBufferNearValue && walBuffersValue < maxWalBuffer) {walBuffersValue = maxWalBuffer}// if less, than 32 kb, than set it to minimumif (walBuffersValue < 32) {walBuffersValue = 32}return walBuffersValue
})
  • 遵循 9.1 中添加的 wal_buffers 自动调整指南,将其设置为 shared_buffers 的 3%,最高为 16MB。
  • 如果 wal_buffers 接近该数字,则最好是 16MB。由于这是 Windows 上的常见情况,其中 shared_buffers 被限制为 512MB,因此在这种情况下向上舍入
  • 如果小于 32 kb,则将其设置为最小值

七、default_statistics_target 该参数使用以下默认值

参考点击:http://postgres.cn/docs/current/runtime-config-query.html#GUC-DEFAULT-STATISTICS-TARGET

export const selectDefaultStatisticsTarget = createSelector([selectDBType],(dbType) =>({[DB_TYPE_WEB]: 100,[DB_TYPE_OLTP]: 100,[DB_TYPE_DW]: 500,[DB_TYPE_DESKTOP]: 100,[DB_TYPE_MIXED]: 100})[dbType]
)

八、random_page_cost 根据硬盘的类型,该参数选择以下值

参考点击:http://postgres.cn/docs/current/runtime-config-query.html#GUC-RANDOM-PAGE-COST

export const selectRandomPageCost = createSelector([selectHDType], (hdType) => {return {[HARD_DRIVE_HDD]: 4,[HARD_DRIVE_SSD]: 1.1,[HARD_DRIVE_SAN]: 1.1}[hdType]
})

九、effective_io_concurrency 该参数在Linux系统下,根据硬盘类型设置如下默认值

参考点击:http://postgres.cn/docs/current/runtime-config-resource.html#GUC-EFFECTIVE-IO-CONCURRENCY

export const selectEffectiveIoConcurrency = createSelector([selectOSType, selectHDType],(osType, hdType) => {if (osType !== OS_LINUX) {return null}return {[HARD_DRIVE_HDD]: 2,[HARD_DRIVE_SSD]: 200,[HARD_DRIVE_SAN]: 300}[hdType]}
)

十、parallel setting

在分析work_mem之前,首先先看一下parallel setting相关:

// 默认设置如下const DEFAULT_DB_SETTINGS = {default: {['max_worker_processes']: 8,['max_parallel_workers_per_gather']: 2,['max_parallel_workers']: 8}
}

如下(如果cpuNum未指定或者太小,不再设置相关并行设置 进而使用上面默认):

export const selectParallelSettings = createSelector([selectDBVersion, selectDBType, selectCPUNum],(dbVersion, dbType, cpuNum) => {if (!cpuNum || cpuNum < 4) {return []}let workersPerGather = Math.ceil(cpuNum / 2)if (dbType !== DB_TYPE_DW && workersPerGather > 4) {// 没有明确的证据表明每个新工人都会为每个新核心带来巨大的利益workersPerGather = 4 // no clear evidence, that each new worker will provide big benefit for each noew core}let config = [{key: 'max_worker_processes',value: cpuNum},{key: 'max_parallel_workers_per_gather',value: workersPerGather}]if (dbVersion >= 10) {config.push({key: 'max_parallel_workers',value: cpuNum})}if (dbVersion >= 11) {let parallelMaintenanceWorkers = Math.ceil(cpuNum / 2)if (parallelMaintenanceWorkers > 4) {parallelMaintenanceWorkers = 4 // no clear evidence, that each new worker will provide big benefit for each noew core}config.push({key: 'max_parallel_maintenance_workers',value: parallelMaintenanceWorkers})}return config}
)
  • max_worker_processes设置成cpunum
  • max_parallel_workers_per_gather的设置:数仓的场景下 workersPerGather = cpunum/2;其他场景下 workersPerGather通常最大都是 4
  • 在pg10及其以上,max_parallel_workers设置成cpunum
  • 在pg11及其以上,max_parallel_maintenance_workers的设置 通常最大都是 4

参考点击:

  • http://postgres.cn/docs/current/runtime-config-resource.html#GUC-MAX-WORKER-PROCESSES
  • http://postgres.cn/docs/current/runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS-PER-GATHER
  • http://postgres.cn/docs/current/runtime-config-resource.html#GUC-MAX-PARALLEL-WORKERS
  • http://postgres.cn/docs/current/runtime-config-resource.html#GUC-MAX-PARALLEL-MAINTENANCE-WORKERS

十一、work_mem

参考点击:http://postgres.cn/docs/current/runtime-config-resource.html#GUC-WORK-MEM

export const selectWorkMem = createSelector([selectTotalMemoryInKb,selectSharedBuffers,selectMaxConnections,selectParallelSettings,selectDbDefaultValues,selectDBType],(totalMemoryKb,sharedBuffersValue,maxConnectionsValue,parallelSettingsValue,dbDefaultValues,dbType) => {const parallelForWorkMem = (() => {if (parallelSettingsValue.length) {const maxParallelWorkersPerGather = parallelSettingsValue.find((param) => param['key'] === 'max_parallel_workers_per_gather')if (maxParallelWorkersPerGather &&maxParallelWorkersPerGather['value'] &&maxParallelWorkersPerGather['value'] > 0) {return maxParallelWorkersPerGather['value']}}if (dbDefaultValues['max_parallel_workers_per_gather'] &&dbDefaultValues['max_parallel_workers_per_gather'] > 0) {return dbDefaultValues['max_parallel_workers_per_gather']}return 1})()// work_mem is assigned any time a query calls for a sort, or a hash, or any other structure that needs a space allocation, which can happen multiple times per query. So you're better off assuming max_connections * 2 or max_connections * 3 is the amount of RAM that will actually use in reality. At the very least, you need to subtract shared_buffers from the amount you're distributing to connections in work_mem.// The other thing to consider is that there's no reason to run on the edge of available memory. If you do that, there's a very high risk the out-of-memory killer will come along and start killing PostgreSQL backends. Always leave a buffer of some kind in case of spikes in memory usage. So your maximum amount of memory available in work_mem should be ((RAM - shared_buffers) / (max_connections * 3) / max_parallel_workers_per_gather).const workMemValue =(totalMemoryKb - sharedBuffersValue) / (maxConnectionsValue * 3) / parallelForWorkMemlet workMemResult = {[DB_TYPE_WEB]: Math.floor(workMemValue),[DB_TYPE_OLTP]: Math.floor(workMemValue),[DB_TYPE_DW]: Math.floor(workMemValue / 2),[DB_TYPE_DESKTOP]: Math.floor(workMemValue / 6),[DB_TYPE_MIXED]: Math.floor(workMemValue / 2)}[dbType]// if less, than 64 kb, than set it to minimumif (workMemResult < 64) {workMemResult = 64}return workMemResult}
)

简单分析一下:

  1. parallelForWorkMem的计算:来源于上面并行设置中max_parallel_workers_per_gather
  2. work_mem的计算:
  • 每次查询调用排序、哈希或任何其他需要空间分配的结构时,都会分配 work_mem,每个查询可能会多次发生这种情况。因此,最好假设 max_connections * 2 或 max_connections * 3 是实际使用的 RAM 量。至少,您需要从分配给 work_mem 中连接的量中减去 shared_buffers
  • 另一件需要考虑的事情是,没有理由在可用内存的边缘运行。如果这样做,内存不足杀手出现并开始杀死 PostgreSQL 后端的风险非常高。始终留下某种缓冲区以防内存使用量激增。因此,work_mem 中可用的最大内存量应为 ((RAM - shared_buffers) / (max_connections * 3) / max_parallel_workers_per_gather)
  • 根据不同场景 计算出最后的建议值
    // work_mem is assigned any time a query calls for a sort, or a hash, or any other structure that needs a space allocation, which can happen multiple times per query. So you're better off assuming max_connections * 2 or max_connections * 3 is the amount of RAM that will actually use in reality. At the very least, you need to subtract shared_buffers from the amount you're distributing to connections in work_mem.// The other thing to consider is that there's no reason to run on the edge of available memory. If you do that, there's a very high risk the out-of-memory killer will come along and start killing PostgreSQL backends. Always leave a buffer of some kind in case of spikes in memory usage. So your maximum amount of memory available in work_mem should be ((RAM - shared_buffers) / (max_connections * 3) / max_parallel_workers_per_gather).const workMemValue =(totalMemoryKb - sharedBuffersValue) / (maxConnectionsValue * 3) / parallelForWorkMemlet workMemResult = {[DB_TYPE_WEB]: Math.floor(workMemValue),[DB_TYPE_OLTP]: Math.floor(workMemValue),[DB_TYPE_DW]: Math.floor(workMemValue / 2),[DB_TYPE_DESKTOP]: Math.floor(workMemValue / 6),[DB_TYPE_MIXED]: Math.floor(workMemValue / 2)}[dbType]// if less, than 64 kb, than set it to minimumif (workMemResult < 64) {workMemResult = 64}

十二、huge_pages

参考点击:http://postgres.cn/docs/current/runtime-config-resource.html#GUC-HUGE-PAGES

export const selectHugePages = createSelector([selectTotalMemoryInKb],// more 32GB - better also have huge page// 超过 32GB - 最好也有大页面(totalMemoryKBytes) => (totalMemoryKBytes >= 33554432 ? 'try' : 'off')
)

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

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

相关文章

【问题】webdriver.Chrome()设置参数executable_path报不存在

场景1: 标红报错unresolved reference executable_path 场景2: 执行报错TypeError: __init__() got an unexpected keyword argument executable_path 原因&#xff1a; 上述两种场景是因为selenium4开始不再支持某些初始化参数。比如executable_path 解决&#xff1a; 方案…

JS听到了双生花的回响

日期对象 学会了日期对象可以让网页显示日期 是用来表示时间的对象&#xff0c;可以得到当前系统的时间 实例化 new关键字&#xff0c;就是实例化的代表 就比如说&#xff0c;你没有对象&#xff0c;但是你是程序员&#xff0c;这个时候你可以先定义一个类&#xff08;你的…

C++类中多线程的编码方式

问题 在C++代码中,一般的代码是需要封装在类里面,比如对象,方法等。否则就不能很好的利用C++面向对象的能力了。 但是这个方式在处理线程时会碰到一个问题。 考虑下面一个简单的场景: class demoC { public:std::thread t;int x;void threadFunc(){std::cout<<x&…

Chapter 17 v-model进阶

欢迎大家订阅【Vue2Vue3】入门到实践 专栏&#xff0c;开启你的 Vue 学习之旅&#xff01; 文章目录 1 v-model原理2 表单类组件封装3 v-model简化代码 1 v-model原理 1. 基本原理 v-model 本质上是一个语法糖&#xff0c;它将 value 属性 和 input 事件 的绑定合并为一个指令…

spring-boot-maven-plugin 标红

情况&#xff1a;创建好 Spring Boot 项目后&#xff0c;pom.xml 文件中 spring-boot-maven-plugin 标红。 解决方案&#xff1a;加上 Spring Boot 的版本即可解决。

电子应用设计方案-31:智能AI音响系统方案设计

智能 AI 音响系统方案设计 一、引言 智能 AI 音响作为一种新兴的智能家居设备&#xff0c;通过融合语音识别、自然语言处理、音频播放等技术&#xff0c;为用户提供便捷的语音交互服务和高品质的音乐体验。本方案旨在设计一款功能强大、性能稳定、用户体验良好的智能 AI 音响系…

“harmony”整合不同平台的单细胞数据之旅

其实在Seurat v3官方网站的Vignettes中就曾见过该算法&#xff0c;但并没有太多关注&#xff0c;直到看了北大张泽民团队在2019年10月31日发表于Cell的《Landscap and Dynamics of Single Immune Cells in Hepatocellular Carcinoma》&#xff0c;为了同时整合两类数据&#xf…

接口测试工具:reqable

背景 在众多接口测试工具中挑选出一个比较好用的接口测试工具。使用过很多工具&#xff0c;如Postman、Apifox、ApiPost等&#xff0c;基本上是同类产品&#xff0c;一般主要使用到的功能就是API接口和cURL&#xff0c;其他的功能目前还暂未使用到。 对比 性能方面&#xff…

内容安全与系统构建加速,助力解决生成式AI时代的双重挑战

内容安全与系统构建加速&#xff0c;助力解决生成式AI时代的双重挑战 0. 前言1. PRCV 20241.1 大会简介1.2 生成式 Al 时代的内容安全与系统构建加速 2. 生成式 AI2.1 生成模型2.2 生成模型与判别模型的区别2.3 生成模型的发展 3. GAI 内容安全3.1 GAI 时代内容安全挑战3.2 图像…

SRS搭建直播推流服务

学习链接 5分钟教你搭建SRS流媒体服务器 - B站视频 SRS Stack 入门B站合集视频 - SRS官方教程 SRS官网 SRS官网文档 ossrs/srs github SRS for window - 可以安装windows版本的srs&#xff0c;SRS 5.0.89正式支持Windows&#xff0c;每个5.0的版本都会提供安装包 文章目录…

javaScript数据类型存储

2.1、简单类型与复杂类型 简单类型又叫做基本数据类型或者值类型&#xff0c;复杂类型又叫做引用类型 值类型&#xff1a;简单数据类型/基本数据类型&#xff0c;在存储时变量中存储的时值本身&#xff0c;因此叫做值类型 string、number、boolean、undefined、null 注意&…

深度学习之 DenseNet和2图像分割常用数据集

1 DenseNet 卷积神经网络结构的设计主要朝着两个方向发展&#xff0c;一个是更宽的网络&#xff08;代表&#xff1a;GoogleNet、VGG&#xff09;&#xff0c;一个是更深的网络&#xff08;代表&#xff1a;ResNet&#xff09;。但是随着层数的加深会出现一个问题——梯度消失&…

Nginx:反向代理

目录 反向代理原理 反向代理配置 日志对比 反向代理原理 网站通过代理服务器发布&#xff0c;用户无需得知网站的实际地址&#xff0c;通过代理服务器进行请求与响应。 用户所有的网站请求报文与响应报文都被代理服务器拦截&#xff0c;在网络层将源地址和目的地址进行了修改…

Linux系统编程——进程替换

目录 前言 二、进程程序替换的概念 三、进程程序替换的原理 ​编辑 四、为什么需要进行进程程序替换 五、如何进行进程程序替换 1、进程替换函数&#xff1a; 1)execl()函数 2)execv()函数 3) execlp()函数 4) execvp()函数 5&#xff09;execle函数 6&#xff09;ex…

探索HarmonyOS:一键掌握Router与NavPathStatck的传参和页面回调技巧

路由的选择 HarmonyOS提供两种路由实现的方式&#xff0c;分别是 Router 和 NavPatchStack。两者使用场景和特效各有优劣。 组件适用场景特点备注Router模块间与模块内页面切换通过每个页面的url实现模块间解耦NavPathStack模块内页面切换通过组件级路由统一路由管理 什么时候使…

go使用mysql实现增删改查操作

1、安装MySQL驱动 go get -u github.com/go-sql-driver/mysql2、go连接MySQL import ("database/sql""log"_ "github.com/go-sql-driver/mysql" // 导入 mysql 驱动 )type Users struct {ID intName stringEmail string }var db *sql.DBfu…

ffmpeg安装(windows)

ffmpeg安装-windows 前言ffmpeg安装路径安装说明 前言 ffmpeg的安装也是开箱即用的,并没有小码哥说的那么难 ffmpeg安装路径 这就下载好了! 安装说明 将上面的bin目录加入到环境变量,然后在cmd中测试一下: C:\Users\12114\Desktop\test\TaskmgrPlayer\x64\Debug>ffmpe…

FPGA存在的意义:为什么adc连续采样需要fpga来做,而不会直接用iic来实现

FPGA存在的意义&#xff1a;为什么adc连续采样需要fpga来做&#xff0c;而不会直接用iic来实现 原因ADS111x连续采样实现连续采样功能说明iic读取adc的数据速率 VS adc连续采样的速率adc连续采样的速率iic读取adc的数据速率结论分析 FPGA读取adc数据问题一&#xff1a;读取adc数…

《Vue零基础入门教程》第十四课:列表渲染

往期内容 《Vue零基础入门教程》第六课&#xff1a;基本选项 《Vue零基础入门教程》第八课&#xff1a;模板语法 《Vue零基础入门教程》第九课&#xff1a;插值语法细节 《Vue零基础入门教程》第十课&#xff1a;属性绑定指令 《Vue零基础入门教程》第十一课&#xff1a;事…

Redis主从架构

Redis&#xff08;Remote Dictionary Server&#xff09;是一个开源的、高性能的键值对存储系统&#xff0c;广泛应用于缓存、消息队列、实时分析等场景。为了提高系统的可用性、可靠性和读写性能&#xff0c;Redis提供了主从复制&#xff08;Master-Slave Replication&#xf…