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

PostgreSQL ash —— pgsentinel插件 学习与踩坑记录

零、 注意事项

       测试发现,pgsentinel插件在pg_active_session_history视图记录条数较多时,存在严重的内存占用问题,群里的其他朋友反馈还可能存在严重的内存泄漏问题。本文仅用于学习和测试,未用于生产环境。

       设置 pgsentinel_ash.max_entries=10000000,启动DB报错需请求28G内存。对于负载稍高的数据库,例如每秒40个活跃会话,按照每秒收集一次的频率,1000万行也仅够保存不到3天的数据,该插件就需要占掉28G内存,实用性太低。

-bash-4.2$ pg_ctl start -D $PGDATA
waiting for server to start....2023-10-07 19:43:09.865 CST [2210] FATAL:  could not map anonymous shared memory: Cannot allocate memory
2023-10-07 19:43:09.865 CST [2210] HINT:  This error usually means that PostgreSQL's request for a shared memory segment exceeded available memory, swap space, or huge pages. To reduce the request size (currently 29601538048 bytes), reduce PostgreSQL's shared memory usage, perhaps by reducing shared_buffers or max_connections.
2023-10-07 19:43:09.865 CST [2210] LOG:  database system is shut down
 stopped waiting
pg_ctl: could not start server
Examine the log output

一、 插件作用

       众所周知,pg是没有像oracle那样的ash视图的,因此要回溯历史问题不太方便。pgsentinel插件会将pg_stat_activity与pg_stat_statements视图内容定期快照,并存入pg_active_session_history和pg_stat_statements_history视图中(重启数据库其中数据会被清空)。

1. pg_active_session_history视图字段

重启数据库其中数据会被清空

ColumnType备注
ash_timetimestamp with time zone采样时间
datidoid
datnametext
pidinteger
leader_pidinteger若有并行,其leader进程的pid
usesysidoiduser id
usenametext
application_nametext
client_addrtext
client_hostnametext
client_portinteger
backend_starttimestamp with time zone
xact_starttimestamp with time zone
query_starttimestamp with time zone
state_changetimestamp with time zone
wait_event_typetext
wait_eventtext
statetext
backend_xidxid
backend_xminxid
top_level_querytext执行函数、存储过程时的外层SQL(开pg_stat_statements.track = all才会有区别)
querytext
cmdtypetext

queryidbigint
backend_typetext
blockersintegerblockers数量
blockerpidinteger
blocker_statetext

2. pg_stat_statements_history视图字段

重启数据库其中数据会被清空,与对应版本的pg_stat_statements视图字段含义相同

ColumnType备注
ash_timetimestamp with time zone
useridoid
dbidoid
queryidbigint
callsbigint
total_exec_timedouble precision
rowsbigint
shared_blks_hitbigint
shared_blks_readbigint
shared_blks_dirtiedbigint
shared_blks_writtenbigint
local_blks_hitbigint
local_blks_readbigint
local_blks_dirtiedbigint
local_blks_writtenbigint
temp_blks_readbigint
temp_blks_writtenbigint
blk_read_timedouble precision
blk_write_timedouble precision
plansbigint
total_plan_timedouble precision
wal_recordsbigint
wal_fpibigint
wal_bytesnumeric

二、 插件安装配置

1. 下载

GitHub - pgsentinel/pgsentinel: postgresql extension providing Active session history

2. 安装

# poatgres用户执行
unzip pgsentinel-master.zip 
cd pgsentinel-master/src
make# root用户执行(要配环境变量,参考下面)
make install

具体安装过程

-bash-4.2$ unzip pgsentinel-master.zip 
-bash-4.2$ cd pgsentinel-master/src
-bash-4.2$ make
gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -g -O2 -fPIC -I. -I./ -I/data/postgres/base/14.0/include/server -I/data/postgres/base/14.0/include/internal  -D_GNU_SOURCE   -c -o pgsentinel.o pgsentinel.c
gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -g -O2 -fPIC -I. -I./ -I/data/postgres/base/14.0/include/server -I/data/postgres/base/14.0/include/internal  -D_GNU_SOURCE   -c -o get_parsedinfo.o get_parsedinfo.c
gcc -std=gnu99 -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Werror=vla -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -fexcess-precision=standard -g -O2 -fPIC -shared -o pgsentinel.so pgsentinel.o get_parsedinfo.o -L/data/postgres/base/14.0/lib    -Wl,--as-needed -Wl,-rpath,'/data/postgres/base/14.0/lib',--enable-new-dtags -lm  

[root@linux01 ~]# vi .bash_profile
# .bash_profile

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

# User specific environment and startup programs

PATH=$PATH:$HOME/bin

export PATH
 
export PGHOME=/data/postgres/base/14.0
export PGDATA=/data/postgres/pg5432/data
export PATH=$PGHOME/bin:$PATH:$HOME/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PGHOME/lib
export LANG=en_US.UTF-8                                                  
~                                 
[root@linux01 ~]# source .bash_profile
[root@linux01 ~]# 
[root@linux01 ~]# cd .../pgsentinel-master/src
[root@linux01 src]# make install 
/usr/bin/mkdir -p '/data/postgres/base/14.0/lib'
/usr/bin/mkdir -p '/data/postgres/base/14.0/share/extension'
/usr/bin/mkdir -p '/data/postgres/base/14.0/share/extension'
/usr/bin/install -c -m 755  pgsentinel.so '/data/postgres/base/14.0/lib/pgsentinel.so'
/usr/bin/install -c -m 644 .//pgsentinel.control '/data/postgres/base/14.0/share/extension/'
/usr/bin/install -c -m 644 .//pgsentinel--1.0.sql  '/data/postgres/base/14.0/share/extension/'

创建插件

CREATE EXTENSION pgsentinel;

3. 插件配置

  • 必须配置
vi postgresql.conf
shared_preload_libraries = 'pg_stat_statements,auto_explain,pgsentinel'

若未配置,查询会报错

postgres=# select * from pg_active_session_history ; 
ERROR:  pg_active_session_history must be loaded via shared_preload_libraries

重启db生效

pg_ctl stop -m fast
pg_ctl start -D $PGDATApostgres=# select * from pg_active_session_history ;
(0 rows)

  • 可选配置

可以直接在postgresql.conf中修改,也可以alter system设置

 alter system set pgsentinel_pgssh.enable=on;
参数名参数含义默认值建议值备注
pgsentinel_ash.sampling_period采样时间(秒)110,视业务负载及需求而定reload生效
pgsentinel_ash.max_entries

pg_active_session_history

最大记录条数(占用ring buffer大小,单位为字节)

1000视业务负载及需求而定。注意非常耗内存,设置1000万约占内存28G重启生效。设置过大可能内存不足,DB启动失败
pgsentinel.db_name数据存在哪个db中postgrespgawr重启生效
pgsentinel_ash.track_idle_trans是否记录 idle in transaction 状态会话offonreload生效
pgsentinel_pgssh.max_entries

pg_stat_statements_history

最大记录条数(占用ring buffer大小,单位为字节)

10000视业务负载及需求而定重启生效。设置过大可能内存不足,DB启动失败
pgsentinel_pgssh.enable是否启用 pg_stat_statements_historyoffon重启生效

这部分对应源码

从中也可以看到各参数含义、默认值、最小最大值,是否需重启生效等

static void
pgsentinel_load_params(void)
{DefineCustomIntVariable("pgsentinel_ash.sampling_period","Duration between each pull (in seconds).",NULL,&ash_sampling_period,1,1,INT_MAX,PGC_SIGHUP,0,NULL,NULL,NULL);DefineCustomBoolVariable("pgsentinel_ash.track_idle_trans","Track session in idle transaction state.",NULL,&ash_track_idle_trans,false,PGC_SIGHUP,0,NULL,NULL,NULL);if (!process_shared_preload_libraries_in_progress)return;/* can't define PGC_POSTMASTER variable after startup */DefineCustomIntVariable("pgsentinel_ash.max_entries","Maximum number of ash entries.",NULL,&ash_max_entries,1000,1000,INT_MAX,PGC_POSTMASTER,0,NULL,NULL,NULL);EmitWarningsOnPlaceholders("pgsentinel_ash");DefineCustomIntVariable("pgsentinel_pgssh.max_entries","Maximum number of pgssh entries.",NULL,&pgssh_max_entries,10000,10000,INT_MAX,PGC_POSTMASTER,0,NULL,NULL,NULL);DefineCustomBoolVariable("pgsentinel_pgssh.enable","Enable pg_stat_statements_history.",NULL,&pgssh_enable,false,PGC_POSTMASTER,0,NULL,NULL,NULL);EmitWarningsOnPlaceholders("pgsentinel_pgssh");DefineCustomStringVariable("pgsentinel.db_name",gettext_noop("Database on which the worker connect."),NULL,&pgsentinelDbName,"postgres",PGC_POSTMASTER,GUC_SUPERUSER_ONLY,NULL, NULL, NULL);
}

  • 其他相关参数

查询语句保留长度

# 为每个活动会话的pg_stat_activity.query字段所保留的内存量(字节,默认1024)
track_activity_query_size = 2048

跟踪层级

       pgsentinel依赖于pg_stat_statements插件的数据,如果想要更详细,可以调整相应参数(但必须注意对系统的负载)

# 记录函数和存储过程中的子语句
pg_stat_statements.track = all

四、 实现原理

       插件最核心的就是pg_active_session_history,pg_stat_statements_history两个视图,所以源码中最重要的,也就是这两个视图的创建。

1. 视图创建

源码中的 pgsentinel--1.0.sql,可以看到这两个视图内容来自两个函数,并进行授权

CREATE VIEW pg_active_session_history ASSELECT * FROM pg_active_session_history();GRANT SELECT ON pg_active_session_history TO PUBLIC;CREATE VIEW pg_stat_statements_history ASSELECT * FROM pg_stat_statements_history();GRANT SELECT ON pg_stat_statements_history TO PUBLIC;

而这两个函数实际是用c语言编写的

2. 函数创建


CREATE FUNCTION pg_active_session_history(OUT ash_time timestamptz,OUT datid Oid,OUT datname text,OUT pid integer,OUT leader_pid integer,OUT usesysid Oid,OUT usename text,OUT application_name text,OUT client_addr text,OUT client_hostname text,OUT client_port integer,OUT backend_start timestamptz,OUT xact_start timestamptz,OUT query_start timestamptz,OUT state_change timestamptz,OUT wait_event_type text,OUT wait_event text,OUT state text,OUT backend_xid xid,OUT backend_xmin xid,OUT top_level_query text,OUT query text,OUT cmdtype text,OUT queryid bigint,OUT backend_type text,OUT blockers integer,OUT blockerpid integer,OUT blocker_state text
)
RETURNS SETOF record
AS 'MODULE_PATHNAME', 'pg_active_session_history'
LANGUAGE C STRICT VOLATILE PARALLEL SAFE;-- Register a view on the function for ease of use.
CREATE VIEW pg_active_session_history ASSELECT * FROM pg_active_session_history();GRANT SELECT ON pg_active_session_history TO PUBLIC;CREATE FUNCTION pg_stat_statements_history(OUT ash_time timestamptz,OUT userid Oid,OUT dbid Oid,OUT queryid bigint,OUT calls bigint,OUT total_exec_time double precision,OUT rows bigint,OUT shared_blks_hit bigint,OUT shared_blks_read bigint,OUT shared_blks_dirtied bigint,OUT shared_blks_written bigint,OUT local_blks_hit bigint,OUT local_blks_read bigint,OUT local_blks_dirtied bigint,OUT local_blks_written bigint,OUT temp_blks_read bigint,OUT temp_blks_written bigint,OUT blk_read_time double precision,OUT blk_write_time double precision,OUT plans bigint,OUT total_plan_time double precision,OUT wal_records bigint,OUT wal_fpi bigint,OUT wal_bytes numeric
)
RETURNS SETOF record
AS 'MODULE_PATHNAME', 'pg_stat_statements_history'
LANGUAGE C STRICT VOLATILE PARALLEL SAFE;

既然如此,我们看看源码中究竟是怎么实现的这些函数


五、 源码学习

1. pg_active_session_history函数内容

它有两个分支,另外根据不同pg版本有不同语句(这里只挑了一个版本):

  • 启用pgsa_query_no_track_idle,即只记录active会话
select act.datid, act.datname, act.pid, act.usesysid, act.usename, \act.application_name, text(act.client_addr), act.client_hostname, \act.client_port, act.backend_start, act.xact_start, act.query_start,  \act.state_change, case when act.wait_event_type is null then 'CPU' \else act.wait_event_type end as wait_event_type,case when act.wait_event is null \then 'CPU' else act.wait_event end as wait_event, act.state, act.backend_xid, \act.backend_xmin, act.query, act.backend_type,(pg_blocking_pids(act.pid))[1], \cardinality(pg_blocking_pids(act.pid)),blk.state,gpi.*, act.leader_pid \from pg_stat_activity act left join pg_stat_activity blk  \on (pg_blocking_pids(act.pid))[1] = blk.pid,get_parsedinfo(act.pid) gpi \where act.state ='active' and act.pid != pg_backend_pid()";
  • 启用 pgsa_query_track_idle,即记录active和idle in transaction会话
select act.datid, act.datname, act.pid, act.usesysid, act.usename, \act.application_name, text(act.client_addr), act.client_hostname, \act.client_port, act.backend_start, act.xact_start, act.query_start,  \act.state_change, case when act.wait_event_type is null then 'CPU' \else act.wait_event_type end as wait_event_type,case when act.wait_event is null \then 'CPU' else act.wait_event end as wait_event, act.state, act.backend_xid, \act.backend_xmin, act.query, act.backend_type,(pg_blocking_pids(act.pid))[1], \cardinality(pg_blocking_pids(act.pid)),blk.state,gpi.*, act.leader_pid \from pg_stat_activity act left join pg_stat_activity blk  \on (pg_blocking_pids(act.pid))[1] = blk.pid,get_parsedinfo(act.pid) gpi \where act.state in ('active', 'idle in transaction') and act.pid != pg_backend_pid()";

2. pg_stat_statements_query函数内容

也有版本区分,这里只取其中一版

 select userid, dbid, queryid, calls, total_exec_time, rows, shared_blks_hit, \shared_blks_read, shared_blks_dirtied, shared_blks_written, local_blks_hit, \local_blks_read, local_blks_dirtied, local_blks_written, temp_blks_read, \temp_blks_written, blk_read_time, blk_write_time, \plans, total_plan_time, wal_records, wal_fpi, wal_bytes \from pg_stat_statements \where queryid in  (select queryid from pg_active_session_history  \where ash_time in (select ash_time from pg_active_session_history  \order by ash_time desc limit 1))";

3. 记录内容

每一行记录叫做一个entry

  • pg_active_session_history对应叫ashEntry
  • pg_stat_statements_query对应叫pgsshEntry
/* ash entry */
typedef struct ashEntry
{int pid;
#if PG_VERSION_NUM >= 130000int leader_pid;
#endifint client_port;uint64 queryid;TimestampTz ash_time;Oid datid;Oid usesysid;char *usename;char *datname;char *application_name;char *wait_event_type;char *wait_event;char *state;char *blocker_state;char *client_hostname;int blockers;int blockerpid;char *top_level_query;char *query;char *cmdtype;char *backend_type;char *client_addr;TransactionId backend_xmin;TransactionId backend_xid;TimestampTz backend_start;TimestampTz xact_start;TimestampTz query_start;TimestampTz state_change;
} ashEntry;/* pg_stat_statement_history entry */
typedef struct pgsshEntry
{TimestampTz ash_time;Oid userid;Oid dbid;uint64 queryid;int64 calls;double total_time;int64 rows;int64 shared_blks_hit;int64 shared_blks_read;int64 shared_blks_dirtied;int64 shared_blks_written;int64 local_blks_hit;int64 local_blks_read;int64 local_blks_dirtied;int64 local_blks_written;int64 temp_blks_read;int64 temp_blks_written;double blk_read_time;double blk_write_time;
#if PG_VERSION_NUM >= 130000int64 plans;double total_plan_time;int64 wal_records;int64 wal_fpi;uint64 wal_bytes;
#endif
} pgsshEntry; 

每个字段有一个buffer变量,记录共享内存用量,例如

static char *AshEntryUsenameBuffer = NULL;
static char *AshEntryDatnameBuffer = NULL;
static char *AshEntryAppnameBuffer = NULL;

       ash_entry_memsize和pgssh_entry_memsize估算entry所需内存,如果占用量过大,DB启动可能会失败。基本原理是:

  • 每行占用内存 = 各字段占用内存之和
  • 总占用内存 = 每行占用内存 * 最大行数 ash_max_entries
/* Estimate amount of shared memory needed for ash entry */
static Size
ash_entry_memsize(void)
{Size            size;/* AshEntryArray */size = mul_size(sizeof(ashEntry), ash_max_entries);/* AshEntryUsenameBuffer */size = add_size(size, mul_size(NAMEDATALEN, ash_max_entries));/* AshEntryDatnameBuffer */size = add_size(size, mul_size(NAMEDATALEN, ash_max_entries));/* AshEntryAppnameBuffer */size = add_size(size, mul_size(NAMEDATALEN, ash_max_entries));/* AshEntryClientaddrBuffer */size = add_size(size, mul_size(NAMEDATALEN, ash_max_entries));/* AshEntryWaitEventTypeBuffer */size = add_size(size, mul_size(NAMEDATALEN, ash_max_entries));/* AshEntryWaitEventBuffer */size = add_size(size, mul_size(NAMEDATALEN, ash_max_entries));/* AshEntryStateBuffer */size = add_size(size, mul_size(NAMEDATALEN, ash_max_entries));/* AshEntryClientHostnameBuffer */size = add_size(size, mul_size(NAMEDATALEN, ash_max_entries));/* AshEntryQueryBuffer */size = add_size(size, mul_size(pgstat_track_activity_query_size,ash_max_entries));/* AshEntryCmdTypeBuffer */size = add_size(size, mul_size(NAMEDATALEN, ash_max_entries));/* AshEntryTopLevelQueryBuffer */size = add_size(size, mul_size(pgstat_track_activity_query_size,ash_max_entries));/* AshEntryBackendTypeBuffer */size = add_size(size, mul_size(NAMEDATALEN, ash_max_entries));/* AshEntryBlockerStateBuffer */size = add_size(size, mul_size(NAMEDATALEN, ash_max_entries));return size;
}

参考:

GitHub - pgsentinel/pgsentinel: postgresql extension providing Active session history

一种PostgreSQL数据库监控和溯源分析的方法和系统与流程

PostgreSQL 12.2官方手册学习( 第19章 运行时统计数据) - 墨天轮

相关文章:

PostgreSQL ash —— pgsentinel插件 学习与踩坑记录

零、 注意事项 测试发现,pgsentinel插件在pg_active_session_history视图记录条数较多时,存在严重的内存占用问题,群里的其他朋友反馈还可能存在严重的内存泄漏问题。本文仅用于学习和测试,未用于生产环境。 设置 pgsentinel_ash.…...

HarmonyOS/OpenHarmony原生应用开发-华为Serverless云端服务支持说明(一)

云端服务的实现是HarmonyOS/OpenHarmony原生应用开发的一个重要的环节,如果用户端是鸿蒙原生应用,但是服务端即云端还是基于传统的各种WEB网络框架、数据库与云服务器,那么所谓的原生应用开发实现的数据即后端服务是和以前、现在的互联网、移…...

3分钟基于Chat GPT完成工作中的小程序

1. 写在前面 GPT自从去年爆发以来,各大公司在大模型方面持续发力,行业大模型也如雨后春笋一般发展迅速,日常工作中比较多的应用场景还是问答模式,作为写程序的辅助也偶尔使用。今天看到一篇翻译的博客“我用 ChatGPT,…...

使用hugo+github搭建免费个人博客

使用hugogithub搭建免费个人博客 前提条件 win11电脑一台电脑安装了git电脑安装了hugogithub账号一个 个人博客本地搭建 初始化一个博客 打开cmd窗口,使用hugo新建一个博客工程 hugo new site blogtest下载主题 主题官网:themes.gohugo.io 在上面…...

打印字节流和字符流

打印字节流和字符流 printStream/ printWriter的构造器和方法都是一样的 package printfile;import java.io.FileOutputStream; import java.io.OutputStream; import java.io.PrintStream; import java.io.PrintWriter; import java.nio.charset.Charset;public class Prin…...

elementplus下载表格为excel格式

安装xlsx npm i --save https://cdn.sheetjs.com/xlsx-0.20.0/xlsx-0.20.0.tgz引入xlsx并使用 import XLSX from xlsx;const tableRef ref<any>(null); // 导出为 Excel const exportToExcel () > {// 获取 el-table 的引用tableRef.value tableRef.value || doc…...

聊聊僵尸进程

文章目录 1. 前言1.1 什么是僵尸进程1.2 为什么需要关注僵尸进程 2. 僵尸进程的产生2.2 为什么会产生僵尸进程2.3 举个栗子 3. 僵尸进程的影响3.1 僵尸进程为何会占用系统资源3.2 操作系统如何知道哪个资源需要被释放3.3 什么是进程表3.4 什么是PCB 5. 如何处理僵尸进程4.1 识别…...

stm32的时钟、中断的配置(针对寄存器),一些基础知识

一、学习参考资料 &#xff08;1&#xff09;正点原子的寄存器源码。 &#xff08;2&#xff09;STM32F103最小系统板开发指南-寄存器版本_V1.1&#xff08;正点&#xff09; &#xff08;3&#xff09;STM32F103最小系统板开发指南-库函数版本_V1.1&#xff08;正点&#xff0…...

Vue14 监视属性简写

监视属性简写 当监视属性只有handler时&#xff0c;可以使用简写 <!DOCTYPE html> <html><head><meta charset"UTF-8" /><title>天气案例_监视属性_简写</title><!-- 引入Vue --><script type"text/javascript&…...

基于docker+Keepalived+Haproxy高可用前后的分离技术

基于dockerKeepalivedHaproxy高可用前后端分离技术 架构图 服务名docker-ip地址docker-keepalived-vip-iphaproxy-01docker-ip自动分配 未指定ip192.168.31.252haproxy-02docker-ip自动分配 未指定ip192.168.31.253 安装haproxy 宿主机ip 192.168.31.254 宿主机keepalived虚…...

安装配置deep learning开发环境

1. 下载安装anacondahttps://www.anaconda.com/download-success vim ~/.condarcchannels: - bioconda - https://mirrors.ustc.edu.cn/anaconda/pkgs/main/ - https://mirrors.ustc.edu.cn/anaconda/cloud/conda-forge/ - https://mirrors.tuna.tsinghua.edu.cn/anaco…...

Docker基础(CentOS 7)

参考资料 hub.docker.com 查看docker官方仓库&#xff0c;需要梯子 Docker命令大全 黑马程序员docker实操教程 &#xff08;黑马讲的真的不错 容器与虚拟机 安装 yum install -y docker Docker服务命令 启动服务 systemctl start docker停止服务 systemctl stop docker重启…...

HTTP的基本格式

HTTP/HTTPS HTTPhttp的协议格式 HTTP 应用层,一方面是需要自定义协议,一方面也会用到一些现成的协议. HTTP协议,就是最常用到的应用层协议. 使用浏览器,打开网站,使用手机app,加载数据,这些过程大概率都是HTTP来支持的 HTTP是一个超文本传输协议, 文本>字符串 超文本>除…...

Qt元对象系统 day5

Qt元对象系统 day5 内存管理 QObject以对象树的形式组织起来&#xff0c;当为一个对象创建子对象时&#xff0c;子对象回自动添加到父对象的children()列表中。父对象拥有子对象所有权&#xff0c;比如父对象可以在自己的析构函数中删除它的孩子对象。使用findChild()或findC…...

【audio】alsa pcm音频路径

文章目录 AML方案音频路径分析dump alsa pcm各个音频路径的原始音频流数据 AML方案音频路径分析 一个Audio Patch用来表示一个或多个source端到一个或多个sink端。这个是从代码的注释翻译来的&#xff0c;大家可以把它比作大坝&#xff0c;可以有好几个入水口和出水口&#xf…...

NLP - 数据预处理 - 文本按句子进行切分

NLP - 数据预处理 - 文本按句子进行切分 文章目录 NLP - 数据预处理 - 文本按句子进行切分一、前言二、环境配置1、安装nltk库2、下载punkt分句器 三、运行程序四、额外补充 一、前言 在学习对数据训练的预处理的时候遇到了一个问题&#xff0c;就是如何将文本按句子切分&#…...

【轻松玩转MacOS】常用软件篇

引言 在本篇文章中&#xff0c;我将介绍如何安装和使用一些常用的软件&#xff0c;如Safari浏览器、邮件、日历、地图等。让我们一起来看看吧&#xff01; 一、Safari浏览器 Safari是MacOS自带的浏览器&#xff0c;具有简洁、快速、安全的特点。 以下是一些Safari浏览器的使…...

Akshare简记

文章目录 基本信息安装Anaconda安装(推荐)Anaconda设置AKShare安装使用AKShare更新数据接口一览数据字典用例Hello WorldMFI指标SMA指标BOLL线指标股市新闻情绪判断市场情绪指标ARBR条件选股回测配对交易策略日线策略计算相近产品基本信息 线上文档:...

Jmeter常用断言之断言持续时间简介

Duration Assertion&#xff1a;断言持续时间。 断言持续时间通常用于做性能测试&#xff0c;一般用于检查HTTP请求的响应时间是否超过预期值。而这个响应时间是性能测试中常关注的一个性能指标。 一、添加断言方式 根据需要可在【测试计划】、【线程组】、【线程请求】下添加…...

C/C++/VS2022/指针/数组 调试出现debug

这个情况就很难受&#xff0c;编译没错&#xff0c;但是运行出现问题了&#xff0c;如果点击中止&#xff08;重试、忽略&#xff09;下一次运行还是会出现&#xff0c;看了显示的大致意思是在数组arry上出现了什么错误&#xff0c;经过检查发现&#xff0c;原来是数组在数入时…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

线程同步:确保多线程程序的安全与高效!

全文目录&#xff1a; 开篇语前序前言第一部分&#xff1a;线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分&#xff1a;synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

Qt Widget类解析与代码注释

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码&#xff0c;写上注释 当然可以&#xff01;这段代码是 Qt …...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)

引言&#xff1a;为什么 Eureka 依然是存量系统的核心&#xff1f; 尽管 Nacos 等新注册中心崛起&#xff0c;但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制&#xff0c;是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

在Ubuntu24上采用Wine打开SourceInsight

1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

腾讯云V3签名

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