【PG-1】PostgreSQL体系结构概述
1. PostgreSQL体系结构概述
代码结构
其中,backend是后端核心代码,包括右边的几个dir:
access:处理数据访问方法和索引的代码。
bootstrap:数据库初始化相关的代码。
catalog:系统目录(如表和索引的元数据)的实现代码。
commands:实现SQL命令的代码。
executor:执行查询计划的代码。
foreign:处理外部数据源(如外部数据封装器和外部表)的代码。
jit:即时编译器优化代码。
lib:库函数。
libpq:PostgreSQL的C语言接口库。
main:后端主程序入口。
nodes:节点和树结构,用于内部查询表示。
optimizer:查询优化器代码。
parser:SQL解析器代码。
partitioning:分区表的处理代码。
postmaster:后端服务管理器。
regex:正则表达式处理代码。
replication:复制功能的代码。
rewrite:规则重写系统代码。
snowball:全文检索中用到的词干分析代码。
statistics:统计信息收集相关代码。
storage:数据存储相关代码。
tcop:交互式终端监控代码。
tsearch:全文搜索相关代码。
utils:工具函数,如数据类型转换等。
进程结构
pg的基本结构是进程,是多进程结构,这和基于pg的opengauss可能有所不同,og是单进程多线程。
与单进程多线程模型相比,多进程模型有一些优势和劣势:
优势:
- 稳健性:单个进程崩溃不会直接影响到运行在其他进程中的客户端会话。
- 安全:因为内存是隔离的,所以进程间的数据访问更加安全。
- 简单性:多进程模型通常更易于理解和调试。
劣势:
- 资源占用:每个进程都需要一定量的内存和系统资源,所以当并发连接数增加时,资源占用也会增加。
- 上下文切换:操作系统在多个进程间切换可能会带来额外的开销,尤其是在高并发环境下。
具体针对图中的各个部分来说是:
-
psql app1…
用于与 PostgreSQL 数据库进行交互和管理
-
Postmaster/Main Process:
这是主控进程,当PostgreSQL数据库启动时首先被创建。它负责监听并接受新的客户端连接请求,并为每个新的客户端连接产生一个新的服务器进程(backend process)。 -
Backend Processes:
为每个客户端连接创建的进程。每个客户端连接(如通过psql
或其他应用程序)通常会有一个对应的后台进程。这些进程负责处理实际的SQL命令,并与数据库内的数据进行交互。 -
Background Writer (bgwriter):
这个进程负责将缓存中的脏页(已修改的页)定期写入磁盘。它可以减轻服务器进程的负担,因为这些进程可以将页标记为脏,但不必立即写入磁盘。 -
WAL Writer:
WAL(Write-Ahead Logging)写入器进程负责将事务日志记录写入到磁盘的WAL文件中。这是确保数据完整性的关键步骤,允许系统在崩溃后恢复到一致状态。 -
Checkpointer:
这个进程负责创建检查点,这是一个系统状态,数据库可以从该状态安全地恢复。它周期性地将当前状态写入到磁盘,并告知bgwriter哪些页可以被安全地写入。 -
Autovacuum Launcher:
这个守护进程监控数据库,定期启动autovacuum worker进程来执行清理任务。它负责删除旧版本的行(也称为元组),这些行由于更新和删除操作而不再可达。 -
Statistics Collector:
收集有关数据库操作的统计信息,这些信息可以用来优化查询计划。 -
Syslogger:
负责记录系统日志,包括错误消息、查询日志和其他系统事件。 -
Archiver:
当开启归档模式时,该进程负责复制WAL记录到指定的归档位置,以便可以用于数据恢复。
postmaster
具体的去查看postmaster.c,首先读注释
/*-------------------------------------------------------------------------** postmaster.c* 该程序充当 POSTGRES 系统请求的中转站。前端程序发送启动消息* 给 Postmaster,Postmaster 根据消息中的信息设置后台进程。** Postmaster 还管理系统范围的操作,如启动和关闭。要注意的是,* Postmaster 本身并不执行这些操作——它只是在适当的时候派生一个* 子进程来执行。它还负责在后台进程崩溃时重置系统。** Postmaster 在启动期间创建共享内存和信号量池,但通常不直接操作它们。* 特别是,它不是 PGPROC 后台数组的成员,因此不能参与锁管理操作。* 让 Postmaster 远离共享内存操作,使得它更简单更可靠。Postmaster 几乎总是能够* 通过重置共享内存从单个后台进程的崩溃中恢复过来;如果它过多地与共享内存* 打交道,那么它也可能随着后台进程一起崩溃。** 当收到请求消息时,我们现在立即执行 fork()。* 子进程执行请求的认证,并在成功后变成一个后台进程。这允许认证代码* 以简单的单线程方式编写(与过去需要的“穷人的多任务”代码相反)。* 更重要的是,它确保了在非多线程库(如 SSL 或 PAM)阻塞时,* 不会对其他客户端造成服务拒绝。** 初始化:* Postmaster 为后台设置共享内存数据结构。** 同步:* Postmaster 与后台共享内存,但应避免touch共享内存,以免在崩溃的* 后台破坏锁或共享内存时变得卡住。同样,Postmaster 永远不应该* 阻塞在来自前端客户端的消息上。** 垃圾收集:* 如果后台紧急退出和/或核心转储,Postmaster 会清理后台。** 错误报告:* 使用 write_stderr() 仅报告“交互式”错误(本质上是命令行上的错误参数)。* 一旦启动了 postmaster,使用 ereport()。**-------------------------------------------------------------------------
首先是定义了一些进程的type以及进程开始过程的一些状态
#define BACKEND_TYPE_NORMAL 0x0001 /* normal backend */
#define BACKEND_TYPE_AUTOVAC 0x0002 /* autovacuum worker process */
#define BACKEND_TYPE_WALSND 0x0004 /* walsender process */
#define BACKEND_TYPE_BGWORKER 0x0008 /* bgworker process */
#define BACKEND_TYPE_ALL 0x000F /* OR of all the above *//* Startup process's status */
typedef enum
{STARTUP_NOT_RUNNING,STARTUP_RUNNING,STARTUP_SIGNALED, /* we sent it a SIGQUIT or SIGKILL */STARTUP_CRASHED
} StartupStatusEnum;
这里pg实际上使用了一个简单地state machine来控制startup shutdown和crash recovery
在postmasterMain函数里面,
1. 获取pid、starttime等信息
PostmasterPid = MyProcPid; captures the process ID of the postmaster.
PgStartTime = GetCurrentTimestamp(); records the startup time of the postmaster.2. 分配内存管理上下文环境
PostmasterContext = AllocSetContextCreate(...); creates a memory context for the postmaster.
MemoryContextSwitchTo(PostmasterContext); switches to the newly created memory context.3. *设置信号处理
pqsignal_pm(SIGCHLD, reaper);/* handle child termination */
pqsignal(SIGCHLD, handle_pm_child_exit_signal);4. 初始化系统配置选项[默认值] // assign_hook()-typedef
InitializeGUCOptions();5. 解析命令行参数
while ((opt = getopt(argc, argv, "B:bC:c:D:d:EeFf:h:ijk:lN:OPp:r:S:sTt:W:-:")) != -1)6. 根据postgresql.conf修改系统配置选项[小的解析器
/guc-file.l]
if (!SelectConfigFiles(userDoption, progname))ExitPostmaster(2);7. 监听socket端口
/** Establish input sockets.*/if (ListenAddresses){8. 创建IPC资源[共享内存+信号灯]
CreateSharedMemoryAndSemaphores();9. 处理pg_hba.conf和pg_ident.conf/** Load configuration files for client authentication.*/if (!load_hba()){/** It makes no sense to continue if we fail to load the HBA file,* since there is no way to connect to the database in this case.*/ereport(FATAL,/* translator: %s is a configuration file */(errmsg("could not load %s", HbaFileName)));}if (!load_ident()){/** We can start up without the IDENT file, although it means that you* cannot log in using any of the authentication methods that need a* user name mapping. load_ident() already logged the details of error* to the log.*/}10. 启动数据库[StartupDataBase] // StartChildProcess
StartupPID = StartupDataBase();11. 进入监控循环
status = ServerLoop();
系统启动
postgre [opts]
- 保存环境变量
- 设置本地化
- 检查命令行参数
- 进入不同执行模式
- —boot:booststrap,初始化数据库
- —describe-config:显示系统配置
- —single:单用户模式启动
- :启动多用户模式
postgres@torresの机革:/usr/local/pgsql$ /usr/local/pgsql/bin/postgres --help
postgres is the PostgreSQL server.Usage:postgres [OPTION]...Options:-B NBUFFERS number of shared buffers-c NAME=VALUE set run-time parameter-C NAME print value of run-time parameter, then exit-d 1-5 debugging level-D DATADIR database directory-e use European date input format (DMY)-F turn fsync off-h HOSTNAME host name or IP address to listen on-i enable TCP/IP connections (deprecated)-k DIRECTORY Unix-domain socket location-N MAX-CONNECT maximum number of allowed connections-p PORT port number to listen on-s show statistics after each query-S WORK-MEM set amount of memory for sorts (in kB)-V, --version output version information, then exit--NAME=VALUE set run-time parameter--describe-config describe configuration parameters, then exit-?, --help show this help, then exitDeveloper options:-f s|i|o|b|t|n|m|h forbid use of some plan types-O allow system table structure changes-P disable system indexes-t pa|pl|ex show timings after each query-T send SIGABRT to all backend processes if one dies-W NUM wait NUM seconds to allow attach from a debuggerOptions for single-user mode:--single selects single-user mode (must be first argument)DBNAME database name (defaults to user name)-d 0-5 override debugging level-E echo statement before execution-j do not use newline as interactive query delimiter-r FILENAME send stdout and stderr to given fileOptions for bootstrapping mode:--boot selects bootstrapping mode (must be first argument)--check selects check mode (must be first argument)DBNAME database name (mandatory argument in bootstrapping mode)-r FILENAME send stdout and stderr to given file
数据库创建和初始化
BKI:backend Interface 脚本文件:
- BKI文件就相当于一个模板文件,比如word空白文档的创建
- 位置: 安装目录下,其实src/backend/catalog/postgre.bki也有一个,create pg_proc 1255 bootstrap tableoid
- @bootstrap/bootstrap.c[+ bootparse.y],对BKI进行解析,在整个bootstrap目录下,进行解析、扫描、执行等
- 例子:建表
# PostgreSQL 16
# ( 上面是变化的,头处理一次,后面复用的吗oid=oid,重复的,属性的内容。
create pg_proc 1255 bootstrap rowtype_oid 81(oid = oid ,proname = name ,pronamespace = oid ,proowner = oid ,prolang = oid ,procost = float4 ,prorows = float4 ,provariadic = oid ,prosupport = regproc ,prokind = char ,prosecdef = bool ,proleakproof = bool ,proisstrict = bool ,proretset = bool ,provolatile = char ,proparallel = char ,pronargs = int2 ,pronargdefaults = int2 ,prorettype = oid ,proargtypes = oidvector FORCE NOT NULL ,proallargtypes = _oid ,proargmodes = _char ,proargnames = _text ,proargdefaults = pg_node_tree ,protrftypes = _oid ,prosrc = text FORCE NOT NULL ,probin = text ,prosqlbody = pg_node_tree ,proconfig = _text ,proacl = _aclitem)
# insert的省略,省略了into table 以及 values insert ( 1242 boolin 11 10 12 1 0 0 0 f f f t f i s 1 0 16 2275 _null_ _null_ _null_ _null_ _null_ boolin _null_ _null_ _null_ _null_ )
边解析边处理
static void
bootstrap_template1(void)
{PG_CMD_DECL;char **line;char **bki_lines;char headerline[MAXPGPATH];char buf[64];/** get the lines from a text file** The result is a malloc'd array of individually malloc'd strings.*/
static char **
readfile(const char *path)
{char **result;FILE *infile;StringInfoData line;int maxlines;int n;if ((infile = fopen(path, "r")) == NULL)pg_fatal("could not open file \"%s\" for reading: %m", path);initStringInfo(&line);maxlines = 1024;result = (char **) pg_malloc(maxlines * sizeof(char *));n = 0;while (pg_get_line_buf(infile, &line)){/* make sure there will be room for a trailing NULL pointer */if (n >= maxlines - 1){maxlines *= 2;result = (char **) pg_realloc(result, maxlines * sizeof(char *));}result[n++] = pg_strdup(line.data);}result[n] = NULL;pfree(line.data);fclose(infile);return result;
}
char **result; vs char *result[];
运行和维护—Client App
-
数据库创建(fromTemplate)
- createdb [opts]
bin/scripts/createdb.c
-
空间整理(gc&analyze)
– vacuumdb [opts] -
数据导出/导入(backup)
– pg_dump [opts]
– pg_restore [opts]
数据字典
系统元数据在src/backend/catalog目录下,结构和接口声明在include/catalog下
pg class.h pg proc.h
pg_class.h 系统表catalog的关系的定义,
in/out 类比于 重载操作符,方便输入输出
{ oid => '1242', descr => 'I/O',proname => 'boolin', prorettype => 'bool', proargtypes => 'cstring',prosrc => 'boolin' },
{ oid => '1243', descr => 'I/O',proname => 'boolout', prorettype => 'cstring', proargtypes => 'bool',prosrc => 'boolout' },
pg_proc.h能被C编译器和pm程序所处理。
函数宏,预编译的阶段
/* Introduces a catalog's structure definition */
#define CATALOG(name,oid,oidmacro) typedef struct CppConcat(FormData_,name)/* ----------------* pg_proc definition. cpp turns this into* typedef struct FormData_pg_proc* ----------------*/
CATALOG(pg_proc,1255,ProcedureRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(81,ProcedureRelation_Rowtype_Id) BKI_SCHEMA_MACRO
{Oid oid; /* oid *//* procedure name */NameData proname;/* OID of namespace containing this proc */Oid pronamespace BKI_DEFAULT(pg_catalog) BKI_LOOKUP(pg_namespace);/* procedure owner */Oid proowner BKI_DEFAULT(POSTGRES) BKI_LOOKUP(pg_authid);/* OID of pg_language entry */Oid prolang BKI_DEFAULT(internal) BKI_LOOKUP(pg_language);
/** CppAsString* Convert the argument to a string, using the C preprocessor.* CppAsString2* Convert the argument to a string, after one round of macro expansion.* CppConcat* Concatenate two arguments together, using the C preprocessor.** Note: There used to be support here for pre-ANSI C compilers that didn't* support # and ##. Nowadays, these macros are just for clarity and/or* backward compatibility with existing PostgreSQL code.*/
#define CppAsString(identifier) #identifier
#define CppAsString2(x) CppAsString(x)
#define CppConcat(x, y) x##y
主要代码阅读
主要包括src/backend/postmaster/postmaster.c 上面以及简单解析了,还有就是src/backend/main/main.c 和 src/bin/initdb.c 和 src/backend/pg_ctl_pg_ctl.c
src/backend/main/main.c
/** 任何 Postgres 服务器进程的执行都是从这里开始。*/
int
main(int argc, char *argv[])
{bool do_check_root = true;reached_main = true;// 在 Windows 平台上,如果后台进程崩溃,设置一个将被调用的处理函数。
#if defined(WIN32)pgwin32_install_crashdump_handler();
#endif// 获取程序名称。progname = get_progname(argv[0]);// 执行平台相关的启动准备。startup_hacks(progname);// 保存原始的 argv[] 数组的物理位置,以供 ps 显示使用。argv = save_ps_display_args(argc, argv);// 启动关键子系统:错误处理和内存管理。MemoryContextInit();// 设置本地化信息。set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("postgres"));// 初始化区域设置。init_locale("LC_COLLATE", LC_COLLATE, "");init_locale("LC_CTYPE", LC_CTYPE, "");
#ifdef LC_MESSAGESinit_locale("LC_MESSAGES", LC_MESSAGES, "");
#endifinit_locale("LC_MONETARY", LC_MONETARY, "C");init_locale("LC_NUMERIC", LC_NUMERIC, "C");init_locale("LC_TIME", LC_TIME, "C");// 移除 LC_ALL 设置。unsetenv("LC_ALL");// 检查标准选项。if (argc > 1){if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0){help(progname);exit(0);}if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0){fputs(PG_BACKEND_VERSIONSTR, stdout);exit(0);}if (strcmp(argv[1], "--describe-config") == 0)do_check_root = false;else if (argc > 2 && strcmp(argv[1], "-C") == 0)do_check_root = false;}// 确保不是以 root 用户身份运行。if (do_check_root)check_root(progname);/** Dispatch to one of various subprograms depending on first argument.*/if (argc > 1 && strcmp(argv[1], "--check") == 0)BootstrapModeMain(argc, argv, true);else if (argc > 1 && strcmp(argv[1], "--boot") == 0)BootstrapModeMain(argc, argv, false);
#ifdef EXEC_BACKENDelse if (argc > 1 && strncmp(argv[1], "--fork", 6) == 0)SubPostmasterMain(argc, argv);
#endifelse if (argc > 1 && strcmp(argv[1], "--describe-config") == 0)GucInfoMain();else if (argc > 1 && strcmp(argv[1], "--single") == 0)PostgresSingleUserMain(argc, argv,strdup(get_user_name_or_exit(progname)));else// 这里调用PostmasterMainPostmasterMain(argc, argv);// 这些函数不应该返回。abort();
}
src/bin/initdb.c
initdb也是一个进程
比如可以这样/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data
src/backend/pg_ctl/pg_ctl.c
pg_ctl — start/stops/restarts the PostgreSQL server
int main(int argc, char **argv) {static struct option long_options[] = {// 长格式的命令行选项定义// 例如,可以用 --pgdata 来指定数据目录{"help", no_argument, NULL, '?'},};// 初始化日志系统,并设置本地化服务pg_logging_init(argv[0]);progname = get_progname(argv[0]);set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_ctl"));start_time = time(NULL);// 保存 argv[0],以便 do_start() 函数在需要时可以寻找 postmasterargv0 = argv[0];// 设置默认的 umask,直到检查 PGDATA 权限umask(PG_MODE_MASK_OWNER);// 支持即使以 root 用户身份运行时也能接收 --help 和 --version 参数// 处理命令行选项,比如 -D 设置数据目录,-l 设置日志文件等while ((c = getopt_long(argc, argv, "cD:l:m:o:s:t:wW", long_options, &option_index)) != -1) {switch (c) {case 'D': // 数据目录选项// ...设置 PGDATA 环境变量break;// ...处理其他选项}}// 如果 optind 还没有超过 argc,那么处理操作命令,如 start, stop, restartif (optind < argc) {// 根据参数识别控制命令,如 "start"、"stop" 等// 如果 ctl_command 已经被设置过了,则报错退出// ...此处省略判断逻辑...}// 如果没有指定操作命令,则打印错误信息并给出建议if (ctl_command == NO_COMMAND) {// 错误处理...}// 设置环境变量 PGDATA 和其他相关的全局变量// 根据控制命令执行相应操作switch (ctl_command) {case INIT_COMMAND:// 执行初始化操作do_init();break;// ...处理其他命令...}// 正常退出exit(0);
}
补充-psql语法
数据库登录
使用postgres用户登录安装在本机的数据库:
$ psql -U postgres
Password for user postgres: //提示输入用户密码
输入用户密码后,登录成功
登录IP为192.168.1.3的服务器,并连接到名为"test"的数据库:
$ psql -U postgres -H 192.168.1.3 -d test
切换数据库
如果登录时未指定数据库,或需要切换到其它数据库,可以使用\c参数切换:
\c dbname
以上命令相当于mysql数据库的use dbname命令。
查看所有数据库
查看当前系统中有哪些数据库可以使用\l或\list参数:
\l
以上命令相当于mysql数据库的show databases命令。
查看数据库中的表
查看当前数据库中所有的表,使用\d参数:
\d
以上命令相当于mysql数据库的show tables命令。
查看表中的字段
查看指定表中的字段,使用\d dbtable参数:
\d mytable
以上命令相当于mysql数据库的desc dbtable或 show columns from dbtable命令。
查看表信息
查看表信息,使用\d+ dbtable参数:
\d+ mytable
以上命令相当于mysql数据库的describe dbtable命令。
退出登录
退出登录,使用\q参数:
\q
以上命令相当于mysql数据库的quit或\q命令。
原文链接:https://blog.csdn.net/lmmilove/article/details/122111192
补充-pg启动调用关系
PostgreSQL启动流程_pg的启动过程-CSDN博客
相关文章:
【PG-1】PostgreSQL体系结构概述
1. PostgreSQL体系结构概述 代码结构 其中,backend是后端核心代码,包括右边的几个dir: access:处理数据访问方法和索引的代码。 bootstrap:数据库初始化相关的代码。 catalog:系统目录(如表和索引的元数据…...
jq命令简易教程——Linux中处理JSON数据的利器
在shell脚本中,当我们需要对JSON数据(例如ceph、kubernetes等一些命令的输出,或是调用API获得的响应)进行处理和提取时,如果使用传统的文本三剑客sed、awk和grep,命令将会非常臃肿不可读。虽然这三个命令在…...
前端开发攻略---Vue实现防篡改水印的效果。删除元素无效!更改元素属性无效!支持图片、元素、视频等等。
1、演示 2、水印的目的 版权保护:水印可以在图片、文档或视频中嵌入作者、品牌或版权所有者的信息,以防止未经授权的复制、传播或使用。当其他人使用带有水印的内容时,可以追溯到原始作者或版权所有者,从而加强版权保护。 身份识…...
在Go语言中复制sync类型
sync包提供了基本的同步原语,例如互斥锁、条件变量和等待组。对于所有这些类型,有一个硬性规则要遵循:它们永远不应该被复制。让我们来理解下这个原理和可能发生的问题。 我们将创建一个线程安全的数据结构来存储计数器。它将包含一个map[string]int,表示每个计数器的当前值…...
Golang | Leetcode Golang题解之第25题K个一组翻转链表
题目: 题解: func reverseKGroup(head *ListNode, k int) *ListNode {hair : &ListNode{Next: head}pre : hairfor head ! nil {tail : prefor i : 0; i < k; i {tail tail.Nextif tail nil {return hair.Next}}nex : tail.Nexthead, tail my…...
【初学】前后端flask+vue组合GET案例
【CSDN 目录配置很不好用】 一、python配置 pip install flaskpip install flask-cors 二、vue配置 1.下载node.js 2.安装node.js 3.测试 node -v4.在vue项目文件夹中创建vue项目 npm create vue@latest第一次会安装一个东西,然后输入名称,一路回车 ✔ Project name…...
计算机科学与技术CS考研408资料
在github上整理了考研的一些资料: 内容包括: 参考书数据结构、组成原理、操作系统、计算机网络.408笔记PDF408思维导图408真题2009-2021真题无logo版408真题2029-2023王道真题(持续更新)历年真题考频统计灰灰考研择校࿰…...
ACID模型是什么
ACID模型是什么 ACID模型是数据库管理系统中保证事务处理安全性的一组特性。ACID是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)四个英文单词的…...
【Linux】基础IO----理解缓冲区
> 作者:დ旧言~ > 座右铭:松树千年终是朽,槿花一日自为荣。 > 目标:理解缓冲区 > 毒鸡汤:有些事情,总是不明白,所以我不会坚持。早安! > 专栏选自:Linux初阶 > 望…...
java学习之路-继承
文章目录 前言 目录 1.1继承的概念 1.2继承有什么好处,为何要继承 1.3继承的语句 1.4父类成员的访问 1.4.1 子类中访问父类的成员变量 1.4.2 子类中访问父类的成员方法 1.5 super关键字 2.子类构造方法 2.1如何创建构造方法 2.2创建构造方法 3.super和this 【相同点…...
Linux系统——Elasticsearch企业级日志分析系统
目录 前言 一、ELK概述 1.ELK简介 2.ELK特点 3.为什么要使用ELK 4.完整日志系统基本特征 5.ELK工作原理 6.Elasticsearch介绍 6.1Elasticsearch概述 6.2Elasticsearch核心概念 7.Logstash介绍 7.1Logstash简介 7.2Logstash主要组件 8.Kibana介绍 8.1Kibana简介 …...
多协议接入视频汇聚EasyCVR平台vs.RTSP安防视频EasyNVR平台:设备分组的区别
EasyCVR视频融合云平台则是旭帆科技TSINGSEE青犀旗下支持多协议接入的视频汇聚融合共享智能平台。平台可支持的接入协议比EasyNVR丰富,包括主流标准协议,有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海…...
Spring Security Oauth2 之 理解OAuth 2.0授权流程
1. Oauth 定义 1.1 角色 OAuth定义了四个角色: 资源所有者 一个能够授权访问受保护资源的实体。当资源所有者是一个人时,它被称为最终用户。 资源服务器 托管受保护资源的服务器能够使用访问令牌接受和响应受保护的资源请求。 客户 代表资源所有…...
mysql题目4
tj11: select count(*) 员工总人数 from tb_dept a join tb_employee b on a.deptnob.deptno where a.dname 市场部...
GFS部署实验
目录 1、部署环境 编辑 2、更改节点名称 3、准备环境 4、磁盘分区,并挂载 5. 做主机映射--/etc/hosts/ 6. 复制脚本文件 7. 执行脚本完成分区 8. 安装客户端软件 1. 安装解压源包 2. 创建gfs 3. 安装 gfs 4. 开启服务 9、 添加节点到存储信任池中 1…...
最前沿・量子退火建模方法(1) : subQUBO讲解和python实现
前言 量子退火机在小规模问题上的效果得到了有效验证,但是由于物理量子比特的大规模制备以及噪声的影响,还没有办法再大规模的场景下应用。 这时候就需要我们思考,如何通过软件的方法怎么样把大的问题分解成小的问题,以便通过现在…...
如何在Linux部署MeterSphere并实现公网访问进行远程测试工作
文章目录 前言1. 安装MeterSphere2. 本地访问MeterSphere3. 安装 cpolar内网穿透软件4. 配置MeterSphere公网访问地址5. 公网远程访问MeterSphere6. 固定MeterSphere公网地址 前言 MeterSphere 是一站式开源持续测试平台, 涵盖测试跟踪、接口测试、UI 测试和性能测试等功能&am…...
postgis导入shp数据时“dbf file (.dbf) can not be opened.“
作者进行矢量数据导入数据库中出现上述报错 导致报错原因 导入的shp文件路径太深导入的shp文件名称或路径中有中文将需要导入数据的shp 文件、dbf 文件、prj 等文件放在到同一个文件夹内,且名字要一致;导入失败: 导入成功:...
StarUML笔记之从C++代码生成UML图
StarUML笔记之从C代码生成UML图 —— 2024-04-14 文章目录 StarUML笔记之从C代码生成UML图1.安装C插件2.准备好一个C代码文件放某个路径下3.点击Reverse Code选择项目文件夹4.拖动(Class)到中间画面可以形成UML5.另外一种方式:双击Type Hierarchy,然后…...
sizeof()和strlen
一、什么是sizeof() sizeof()是一个在C和C中广泛使用的操作符,用于计算数据类型或变量所占内存的字节数。它返回一个size_t类型的值,表示其操作数所占的字节数。 在使用时,sizeof()可以接收一个数据类型作为参数,也可以接收一个…...
Python学习笔记13 - 元组
什么是元组 元组的创建方式 为什么要将元组设计为不可变序列? 元组的遍历...
[leetcode]remove-duplicates-from-sorted-list-ii
. - 力扣(LeetCode) 给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。 示例 1: 输入:head [1,2,3,3,4,4,5] 输出:[1,2,5]示例 2&…...
共享内存和Pytorch中的Dataloader结合
dataloader中通常使用num_workers来指定多线程来进行数据的读取。可以使用共享内存进行加速。 代码地址:https://github.com/POSTECH-CVLab/point-transformer/blob/master/util/s3dis.py 文章目录 1. 共享内存和dataloader结合1.1 在init中把所有的data存储到共享内…...
分享 WebStorm 2024 激活的方案,支持JetBrains全家桶
大家好,欢迎来到金榜探云手! WebStorm公司简介 JetBrains 是一家专注于开发工具的软件公司,总部位于捷克。他们以提供强大的集成开发环境(IDE)而闻名,如 IntelliJ IDEA、PyCharm、和 WebStorm等。这些工具…...
Android OOM问题定位、内存优化
一、OOM out of memory:简称OOM,内存溢出,申请的内存大于剩余的内存而抛出的异常。 对于Android平台,广义的OOM主要是以下几种类型 JavaNativeThread 线程数的上限默认为32768,部分华为设备的限制是500通常1000左右…...
棋盘(c++题解)
题目描述 有一个m m的棋盘,棋盘上每一个格子可能是红色、黄色或没有任何颜色的。你现在要从棋盘的最左上角走到棋盘的最右下角。 任何一个时刻,你所站在的位置必须是有颜色的(不能是无色的) ,你只能向上、下、 左、右…...
滑动窗口例题
一、209:长度最小的子数组 209:长度最小的子数组 思路:1、暴力解法:两层for循环遍历,当sum > target时计算子数组长度并与result比较,取最小的更新result。提交但是超出了时间限制。 class Solution {public int minSubArray…...
智过网:注册安全工程师注册有效期与周期解析
在职业领域,各种专业资格认证不仅是对从业者专业能力的认可,也是保障行业安全、规范发展的重要手段。其中,注册安全工程师证书在安全生产领域具有举足轻重的地位。那么,注册安全工程师的注册有效期是多久呢?又是几年一…...
腐蚀Rust 服务端搭建架设个人社区服务器Windows教程
腐蚀Rust 服务端搭建架设个人社区服务器Windows教程 大家好我是艾西,一个做服务器租用的网络架构师也是游戏热爱者。最近在steam发现rust腐蚀自建的服务器以及玩家还是非常多的,那么作为服务器供应商对这商机肯定是不会放过的哈哈哈! 艾西这…...
蓝桥杯备赛:考前注意事项
考前注意事项 1、DevCpp添加c11支持 点击 工具 - 编译选项 中添加: -stdc112、万能头文件 #include <bits/stdc.h>万能头文件的缺陷:y1 变量 在<cmath>中用过了y1变量。 #include <bits/stdc.h> using namespace std;// 错误示例 …...
张店党风廉政建设网站/百度收录刷排名
题库来源:安全生产模拟考试一点通公众号小程序 2020年美容师(中级)考试题及美容师(中级)多少分及格,包含美容师(中级)考试题答案和解析及美容师(中级)多少分…...
营销型网站建设文章/ 今日头条
atitit 点播系统 概览 v2 qb1.docx 1.1. 多界面(可以挂载多个不同的界面主题)1 1.2. 独立的选片模块(跨设备,跨平台)2 1.3. 跨设备平台(android安卓盒子,pc,htpc )2 1.4…...
分享社交电商十大平台/西安seo优化
点击上方“Java基基”,选择“设为星标”做积极的人,而不是积极废人!每天 14:00 更新文章,每天掉亿点点头发...源码精品专栏 原创 | Java 2021 超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络应用框…...
网页空间层次/seo服务价格表
这一系列文章原载于公众号 工程师milter,如果文章对大家有帮助,恳请大家动手关注下哈~matplotlib是优秀的python画图工具,功能十分强大,但是使用却很复杂。你有没有如下的经历:1、图形只差一点点就满足你的要求,可是怎…...
广州市网站建设品牌/网站seo服务公司
用过jQuery的朋友一定对jQuery中方法的链式调用印象深刻,貌似现在很多库都支持了方法的链式调用,比如YUI3等。链式调用是一个非常不错的语法特性,能让代码更加简洁、易读。很多时候链式调用可以避免多次重复使用一个对象变量。今天有人在群里说起javascr…...
有没有专门做网站的/关键词搜索排行榜
本文将带领大家领略Spring事务的风采,Spring事务是我们在日常开发中经常会遇到的,也是各种大小面试中的高频题,希望通过本文,能让大家对Spring事务有个深入的了解,无论开发还是面试,都不会让Spring事务成为…...