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

PostgreSQL的wal文件回收问题

引子

将PostgreSQL的GUC参数wal_recycle设置为on,然后对数据库执行一定业务量的操作,会发现在pg_wal目录下,有很多未来使用的wal文件,且创建时间比现在正在使用的wal文件更早,下文将描述和分析这种情况。

问题描述

问题1:为什么未来使用的wal文件,创建时间会更早?
  1. 使用pg_controldata程序,查看数据库控制文件,发现PostgreSQL数据库当前正使用的wal文件为00000001000000000000007A;
[coder@localhost build_postgres]$ ./bin/pg_controldata data_test/
pg_control version number:            1201
Catalog version number:               201909212
Database system identifier:           7331656414979148006
Database cluster state:               shut down
pg_control last modified:             2024年02月04日 星期日 16时38分49秒
Latest checkpoint location:           0/7A000028
Latest checkpoint's REDO location:    0/7A000028
Latest checkpoint's REDO WAL file:    00000001000000000000007A
Latest checkpoint's TimeLineID:       1
Latest checkpoint's PrevTimeLineID:   1
Latest checkpoint's full_page_writes: on
Latest checkpoint's NextXID:          0:497
Latest checkpoint's NextOID:          16396
Latest checkpoint's NextMultiXactId:  1
Latest checkpoint's NextMultiOffset:  0
Latest checkpoint's oldestXID:        479
Latest checkpoint's oldestXID's DB:   1
Latest checkpoint's oldestActiveXID:  0
Latest checkpoint's oldestMultiXid:   1
Latest checkpoint's oldestMulti's DB: 1
Latest checkpoint's oldestCommitTsXid:486
Latest checkpoint's newestCommitTsXid:496
Time of latest checkpoint:            2024年02月04日 星期日 16时38分49秒
Fake LSN counter for unlogged rels:   0/3E8
Minimum recovery ending location:     0/0
Min recovery ending loc's timeline:   0
Backup start location:                0/0
Backup end location:                  0/0
End-of-backup record required:        no
wal_level setting:                    logical
wal_log_hints setting:                off
max_connections setting:              100
max_worker_processes setting:         8
max_wal_senders setting:              10
max_prepared_xacts setting:           0
max_locks_per_xact setting:           64
track_commit_timestamp setting:       on
Maximum data alignment:               8
Database block size:                  8192
Blocks per segment of large relation: 131072
WAL block size:                       8192
Bytes per WAL segment:                16777216
Maximum length of identifiers:        64
Maximum columns in an index:          32
Maximum size of a TOAST chunk:        1996
Size of a large-object chunk:         2048
Date/time type storage:               64-bit integers
Float4 argument passing:              by value
Float8 argument passing:              by value
Data page checksum version:           0
Mock authentication nonce:            def3a46f189241ca0085fac72f98a6f359897b3104fdc4ae6b4ea9ff7423e724
[coder@localhost build_postgres]$
  1. 查看data/pg_wal目录,发现在wal文件00000001000000000000007A后面,预分配了一些未来使用的wal文件。00000001000000000000007A后面的wal文件,是PostgreSQL在执行ckpt时,预分配的wal文件。观察发现,00000001000000000000007B及其以后的wal文件的时间,反而比00000001000000000000007A的创建时间更早。
[coder@localhost build_postgres]$ ll data_test/pg_wal/
总用量 1048576
-rw-------. 1 coder coder 16777216 24 16:38 000000010000000000000079
-rw-------. 1 coder coder 16777216 24 16:38 00000001000000000000007A
-rw-------. 1 coder coder 16777216 24 16:25 00000001000000000000007B
-rw-------. 1 coder coder 16777216 24 16:25 00000001000000000000007C
-rw-------. 1 coder coder 16777216 24 16:25 00000001000000000000007D
-rw-------. 1 coder coder 16777216 24 16:25 00000001000000000000007E
-rw-------. 1 coder coder 16777216 24 16:25 00000001000000000000007F
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000080
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000081
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000082
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000083
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000084
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000085
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000086
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000087
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000088
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000089
-rw-------. 1 coder coder 16777216 24 16:25 00000001000000000000008A
-rw-------. 1 coder coder 16777216 24 16:24 00000001000000000000008B
-rw-------. 1 coder coder 16777216 24 16:25 00000001000000000000008C
-rw-------. 1 coder coder 16777216 24 16:25 00000001000000000000008D
-rw-------. 1 coder coder 16777216 24 16:25 00000001000000000000008E
-rw-------. 1 coder coder 16777216 24 16:25 00000001000000000000008F
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000090
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000091
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000092
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000093
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000094
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000095
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000096
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000097
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000098
-rw-------. 1 coder coder 16777216 24 16:25 000000010000000000000099
-rw-------. 1 coder coder 16777216 24 16:25 00000001000000000000009A
-rw-------. 1 coder coder 16777216 24 16:26 00000001000000000000009B
-rw-------. 1 coder coder 16777216 24 16:26 00000001000000000000009C
-rw-------. 1 coder coder 16777216 24 16:26 00000001000000000000009D
-rw-------. 1 coder coder 16777216 24 16:26 00000001000000000000009E
-rw-------. 1 coder coder 16777216 24 16:26 00000001000000000000009F
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000A0
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000A1
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000A2
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000A3
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000A4
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000A5
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000A6
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000A7
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000A8
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000A9
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000AA
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000AB
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000AC
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000AD
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000AE
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000AF
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000B0
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000B1
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000B2
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000B3
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000B4
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000B5
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000B6
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000B7
-rw-------. 1 coder coder 16777216 24 16:26 0000000100000000000000B8
drwx------. 2 coder coder       43 24 16:38 archive_status
[coder@localhost build_postgres]$
  1. 使用stat,查看wal文件的更改时间信息
[coder@localhost build_postgres]$ stat data_test/pg_wal/00000001000000000000007A
文件:"data_test/pg_wal/00000001000000000000007A"
大小:16777216        块:32768      IO 块:4096   普通文件
设备:fd00h/64768d      Inode:33554500    硬链接:1
权限:(0600/-rw-------)  Uid:( 1000/   coder)   Gid:( 1000/   coder)
环境:unconfined_u:object_r:user_home_t:s0
最近访问:2024-02-04 16:39:38.050057576 +0800
最近更改:2024-02-04 16:38:49.974694468 +0800
最近改动:2024-02-04 16:38:49.974694468 +0800
创建时间:-
[coder@localhost build_postgres]$ stat data_test/pg_wal/00000001000000000000007B
文件:"data_test/pg_wal/00000001000000000000007B"
大小:16777216        块:32768      IO 块:4096   普通文件
设备:fd00h/64768d      Inode:33554504    硬链接:1
权限:(0600/-rw-------)  Uid:( 1000/   coder)   Gid:( 1000/   coder)
环境:unconfined_u:object_r:user_home_t:s0
最近访问:2024-02-04 16:39:44.187103929 +0800
最近更改:2024-02-04 16:25:39.695772523 +0800
最近改动:2024-02-04 16:26:20.931006693 +0800
创建时间:-
[coder@localhost build_postgres]$
问题2:为什么无法使用pg_waldump,解析未来使用的wal文件?

使用pg_waldump程序,解析PostgreSQL预分配给未来使用的wal文件,发现pg_waldump提示“fatal: could not find a valid record after 0/7C000000”,无法成功解析未来使用的wal文件;

[coder@localhost build_postgres]$ ./bin/pg_waldump data_test/pg_wal/00000001000000000000007C | tail -n 10
pg_waldump: fatal: could not find a valid record after 0/7C000000
[coder@localhost build_postgres]$

问题分析

问题1:为什么未来使用的wal文件,创建时间会更早?
  1. 查看00000001000000000000007B文件的MD5,并与archive归档目录下的wal文件比较,我们发现00000001000000000000007B文件,与00000001000000000000004B的MD5是一致的。
[coder@localhost build_postgres]$ md5sum data_test/pg_wal/00000001000000000000007B
bac5e93ba8d551dabd8ffe5a24a678d1  data_test/pg_wal/00000001000000000000007B
[coder@localhost build_postgres]$ md5sum archive/* |grep bac5e93ba8d551dabd8ffe5a24a678d1
bac5e93ba8d551dabd8ffe5a24a678d1  archive/00000001000000000000004B
[coder@localhost build_postgres]$
  1. 分析PostgreSQL的checkpoint执行流程,
检查点
重启点
回收不再使用的wal文件
删除不再使用的wal文件
CreateCheckPoint
RemoveOldXlogFiles
CreateRestartPoint
RemoveXlogFile
InstallXLogFileSegment
durable_unlink
  1. RemoveXlogFile函数中,关键代码如下:
static void
RemoveXlogFile(const char *segname, XLogRecPtr lastredoptr, XLogRecPtr endptr)
{skip.../** Before deleting the file, see if it can be recycled as a future log* segment. Only recycle normal files, pg_standby for example can create* symbolic links pointing to a separate archive directory.*/if (wal_recycle &&endlogSegNo <= recycleSegNo &&lstat(path, &statbuf) == 0 && S_ISREG(statbuf.st_mode) &&InstallXLogFileSegment(&endlogSegNo, path,true, recycleSegNo, true)){ereport(DEBUG2,(errmsg("recycled write-ahead log file \"%s\"",segname)));CheckpointStats.ckpt_segs_recycled++;/* Needn't recheck that slot on future iterations */endlogSegNo++;}else{skip...}skip...
}
问题2:为什么无法使用pg_waldump,解析未来使用的wal文件?
  1. 使用pg_waldump解析00000001000000000000007B文件,发现无法成功解析,提示如下:
[coder@localhost build_postgres]$ ./bin/pg_waldump data_test/pg_wal/00000001000000000000007B
pg_waldump: fatal: could not find a valid record after 0/7B000000
  1. 堆栈分析,定位到XLogReaderValidatePageHeader函数中:
(gdb) bt
#0  XLogReaderValidatePageHeader (state=0x6401f0, recptr=2063597568, phdr=0x640b10 "\001\321\a") at xlogreader.c:865
#1  0x000000000040574a in ReadPageInternal (state=0x6401f0, pageptr=2063597568, reqLen=0) at xlogreader.c:629
#2  0x00000000004060d9 in XLogFindNextRecord (state=0x6401f0, RecPtr=2063597568) at xlogreader.c:959
#3  0x00000000004044a7 in main (argc=2, argv=0x7fffffffe3e8) at pg_waldump.c:1116
(gdb)
  1. 关键以下代码:
bool
XLogReaderValidatePageHeader(XLogReaderState *state, XLogRecPtr recptr,char *phdr)
{...skip...if (hdr->xlp_pageaddr != recaddr){char        fname[MAXFNAMELEN];XLogFileName(fname, state->readPageTLI, segno, state->wal_segment_size);report_invalid_record(state,"unexpected pageaddr %X/%X in log segment %s, offset %u",(uint32) (hdr->xlp_pageaddr >> 32), (uint32) hdr->xlp_pageaddr,fname,offset);return false;}...skip...
}
pg_waldump
  1. 经过调试发现,pg_waldump在解析00000001000000000000007B文件时,发现其中的第一个XLogPageHeader的xlp_pageaddr是0x4b000000,也就是对应archive/00000001000000000000004B文件,与其文件名00000001000000000000007B不符,所以打印错误信息,退出该wal文件的解析。

小结

  1. PostgreSQL对于不再使用的wal文件,会根据具体情况,以及wal_recycle参数,决定是执行回收还是删除操作。如果是回收wal文件,则是直接重命名该wal文件的,并不会修改或者重置wal文件中的内容。
  2. 使用pg_waldump工具,无法解析回收的wal文件,原因是回收的wal文件,根据其文件名称,与文件中的实际内容,计算出的xlp_pageaddr不一致,pg_waldump发现不一致后,直接退出wal文件的解析。

相关文章:

PostgreSQL的wal文件回收问题

引子 将PostgreSQL的GUC参数wal_recycle设置为on&#xff0c;然后对数据库执行一定业务量的操作&#xff0c;会发现在pg_wal目录下&#xff0c;有很多未来使用的wal文件&#xff0c;且创建时间比现在正在使用的wal文件更早&#xff0c;下文将描述和分析这种情况。 问题描述 …...

java-JUC并发编程学习笔记05(尚硅谷)

我们写一段测试代码: 会出现线程不安全的问题。 使用Vector解决线程不安全问题&#xff1a; 但是这个类几乎不会被使用了&#xff0c;因为效率太低。 方法二&#xff1a;通过Collections解决&#xff1a; 但是这种方案实际中也不太会使用。 我们还有第三种方法使用CopyOnWri…...

vulhub中spring的CVE-2022-22947漏洞复现

Spring Cloud Gateway是Spring中的一个API网关。其3.1.0及3.0.6版本&#xff08;包含&#xff09;以前存在一处SpEL表达式注入漏洞&#xff0c;当攻击者可以访问Actuator API的情况下&#xff0c;将可以利用该漏洞执行任意命令。 参考链接&#xff1a; https://tanzu.vmware.c…...

网络原理TCP/IP(1)

文章目录 端口号UDP协议 在网络通信中&#xff0c;协议非常重要 协议进行了分层 应用层就是对应着应用程序&#xff0c;是程序员打交道最多的这一层&#xff0c;调用系统提供的网络api写出来的代码都是属于应用层的 应用层有很多现成的协议&#xff0c;但是更多的还是程序员需要…...

EasyExcel使用,实体导入导出

简介 Java解析、生成Excel比较有名的框架有Apache poi、jxl。但他们都存在一个严重的问题就是非常的耗内存&#xff0c;poi有一套SAX模式的API可以一定程度的解决一些内存溢出的问题&#xff0c;但POI还是有一些缺陷&#xff0c;比如07版Excel解压缩以及解压后存储都是在内存中…...

让IIS支持SSE (Server Sent Events)

本文只探讨IISPython网站的情况&#xff0c;对于asp.net也应该不用这么麻烦。 先上结论&#xff1a;用反向代理&#xff1a; IIS URL Rewrite waitress Waitress是一个纯python编写独立的WSGI服务器&#xff0c;功能比Gunicorn弱一些&#xff0c;但可以运行在windows平台上&…...

新手从零开始学习数学建模论文写作(美赛论文临时抱佛脚篇)

本文记录于数学建模老哥视频的学习过程中。b站视频&#xff1a;http://【【零基础教程】老哥&#xff1a;数学建模算法、编程、写作和获奖指南全流程培训&#xff01;】https://www.bilibili.com/video/BV1kC4y1a7Ee?p50&vd_sourceff53a726c62f94eda5f615bd4a62c458 目录…...

k8s存储之PV、PVC

在k8s集群中&#xff0c;资源存储会散落到各个工作节点上&#xff0c;这样对用资源调用很不方便&#xff0c;那么k8s是如何实现存储资源共享的呢&#xff0c;本文浅尝辄止的探讨一下&#xff0c;k8s是通过pv、pvc实现的。 一、PV、PVC的概念 1、持久卷(PV&#xff09; pv是Pe…...

go-基于逃逸分析来提升性能程序

go-基于逃逸分析来提升性能程序 为什么要学习逃逸分析&#xff1a; 为了提高程序的性能&#xff0c;通过逃逸分析我们能知道指标是分配到堆上还是栈上&#xff0c;如何是 分配到栈上&#xff0c;内存的分配和释放都是由编译器进行管理的&#xff0c;分配和释放的速度都非常的…...

[软件工具]文档页数统计工具软件pdf统计页数word统计页数ppt统计页数图文打印店快速报价工具

文档页数统计工具软件——打印方面好帮手 在信息化时代&#xff0c;文档已成为我们工作、学习、生活中不可或缺的一部分。无论是学术论文、商业报告&#xff0c;还是个人日记&#xff0c;都需要我们对其进行有效的管理。而在这个过程中&#xff0c;文档页数统计工具软件就显得…...

linux编译ffmpeg动态库

1&#xff0c;获取源码&#xff1a;git clone https://git.ffmpeg.org/ffmpeg.git 2&#xff0c;创建编译目录&#xff0c;并编译、安装&#xff0c; cd ffmpeg mkdir build cd build ../configure --prefix~/ffmpeg --enable-shared --enable-debug1 //configure后需要使…...

Unity3d Cinemachine篇(完)— TargetGroup

文章目录 前言使用TargetGroup追随多个模型1. 创建二个游戏物体2. 创建TargetGroup相机3. 设置相机4. 完成 前言 上一期我们简单的使用了ClearShot相机&#xff0c;这次我们来使用一下TargetGroup 使用TargetGroup追随多个模型 1. 创建二个游戏物体 2. 创建TargetGroup相机 3…...

事件驱动架构:使用Flask实现MinIO事件通知Webhooks

MinIO的事件通知可能一开始看起来并不激动人心&#xff0c;但一旦掌握了它们的力量&#xff0c;它们就能照亮您存储桶内的动态。事件通知是一个全面、高效的对象存储系统中的关键组件。Webhooks是我个人最喜欢的工具&#xff0c;用于与MinIO集成。它们在事件的世界中就像一把瑞…...

力扣面试150 只出现一次的数字Ⅱ 哈希 统计数位 DFA有穷自动机

Problem: 137. 只出现一次的数字 II 文章目录 思路&#x1f496; 哈希&#x1f496; 位数统计&#x1f496; DFA 状态机 思路 &#x1f468;‍&#x1f3eb; 参考 &#x1f496; 哈希 ⏰ 时间复杂度: O ( n ) O(n) O(n) &#x1f30e; 空间复杂度: O ( n ) O(n) O(n) cl…...

R语言学习case10:ggplot基础画图Parallel Coordinate Plot 平行坐标图

step1: 导入ggplot2库文件 library(ggplot2)step2&#xff1a;带入自带的iris数据集 iris <- datasets::irisstep3&#xff1a;查看数据信息 dim(iris)维度为 [150,5] head(iris)查看数据前6行的信息 step4&#xff1a;利用ggplot工具包绘图 plot5 <- ggparcoord(…...

Easy Excel动态表头的实现

步骤&#xff1a; 1.查找官方API文档理解实现 2.实现融入到代码里面 一&#xff1a;Easy Excel动态头实时生成头写入 动态头实时生成头写入 二&#xff1a;实现 目的&#xff1a;实现表头为&#xff0c;第一列是固定列&#xff0c;第二列为动态生成的时间段的每一天的日期…...

kvm qemu 优化 windows 虚拟机速度

主要优化磁盘 io 和网络 io 都选为 virtio windows 驱动下载 https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/archive-virtio/virtio-win-0.1.185-2/virtio-win-0.1.185.iso I also had incredibly slow performance with my virtual HDD. The followin…...

银行数据仓库体系实践(18)--数据应用之信用风险建模

信用风险 银行的经营风险的机构&#xff0c;那在第15节也提到了巴塞尔新资本协议对于银行风险的计量和监管要求&#xff0c;其中信用风险是银行经营的主要风险之一&#xff0c;它的管理好坏直接影响到银行的经营利润和稳定经营。信用风险是指交易对手未能履行约定契约中的义务而…...

每日一练 | 华为认证真题练习Day179

1、关于配置STUB区域需要注意的事项中描述正确的是 A. 骨干区域可以配置成为STUB区域 B. 如果将一个区域配置成为STUB区域&#xff0c;则该区域中的所有路由器都要配置STUB区域属性 C. STUB区域可以存在ASBR D. 虚连接可以穿越STUB 2、关于PIM-SM中的HellO报文的描述&#…...

[ubuntu]add-apt-repository 添加以及移除

add-apt-repository是一个用于添加PPA&#xff08;Personal Package Archive&#xff09;存储库的命令。它是Ubuntu和基于Ubuntu的Linux发行版中的apt软件包管理系统的一部分。 PPA存储库允许用户安装和更新软件包&#xff0c;这些软件包不包含在官方软件源中。通过添加PPA存储…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

椭圆曲线密码学(ECC)

一、ECC算法概述 椭圆曲线密码学&#xff08;Elliptic Curve Cryptography&#xff09;是基于椭圆曲线数学理论的公钥密码系统&#xff0c;由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA&#xff0c;ECC在相同安全强度下密钥更短&#xff08;256位ECC ≈ 3072位RSA…...

12.找到字符串中所有字母异位词

&#x1f9e0; 题目解析 题目描述&#xff1a; 给定两个字符串 s 和 p&#xff0c;找出 s 中所有 p 的字母异位词的起始索引。 返回的答案以数组形式表示。 字母异位词定义&#xff1a; 若两个字符串包含的字符种类和出现次数完全相同&#xff0c;顺序无所谓&#xff0c;则互为…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比

在机器学习的回归分析中&#xff0c;损失函数的选择对模型性能具有决定性影响。均方误差&#xff08;MSE&#xff09;作为经典的损失函数&#xff0c;在处理干净数据时表现优异&#xff0c;但在面对包含异常值的噪声数据时&#xff0c;其对大误差的二次惩罚机制往往导致模型参数…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

腾讯云V3签名

想要接入腾讯云的Api&#xff0c;必然先按其文档计算出所要求的签名。 之前也调用过腾讯云的接口&#xff0c;但总是卡在签名这一步&#xff0c;最后放弃选择SDK&#xff0c;这次终于自己代码实现。 可能腾讯云翻新了接口文档&#xff0c;现在阅读起来&#xff0c;清晰了很多&…...

PHP 8.5 即将发布:管道操作符、强力调试

前不久&#xff0c;PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5&#xff01;作为 PHP 语言的又一次重要迭代&#xff0c;PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是&#xff0c;借助强大的本地开发环境 ServBay&am…...

【Veristand】Veristand环境安装教程-Linux RT / Windows

首先声明&#xff0c;此教程是针对Simulink编译模型并导入Veristand中编写的&#xff0c;同时需要注意的是老用户编译可能用的是Veristand Model Framework&#xff0c;那个是历史版本&#xff0c;且NI不会再维护&#xff0c;新版本编译支持为VeriStand Model Generation Suppo…...

五子棋测试用例

一.项目背景 1.1 项目简介 传统棋类文化的推广 五子棋是一种古老的棋类游戏&#xff0c;有着深厚的文化底蕴。通过将五子棋制作成网页游戏&#xff0c;可以让更多的人了解和接触到这一传统棋类文化。无论是国内还是国外的玩家&#xff0c;都可以通过网页五子棋感受到东方棋类…...