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

[EBPF] 实时捕获DM数据库是否存在SQL阻塞

1. 介绍

eBPF(extened Berkeley Packet Filter)是一种内核技术,它允许开发人员在不修改内核代码的情况下运行特定的功能。eBPF 的概念源自于 Berkeley Packet Filter(BPF),后者是由贝尔实验室开发的一种网络过滤器,可以捕获和过滤网络数据包。

eBPF 可以在不侵入任何业务代码的基础上实现应用的可观测性。但是 eBPF 对 Linux 内核版本是有一定要求的(4.14 以上)。

2. 工作原理

eBPF 的工作原理主要分为三个步骤:加载、编译和执行。

eBPF 需要在内核中运行。这通常是由用户态的应用程序完成的,它会通过系统调用来加载 eBPF 程序。在加载过程中,内核会将 eBPF 程序的代码复制到内核空间。

eBPF 程序需要经过编译和执行。这通常是由Clang/LLVM的编译器完成,然后形成字节码后,将用户态的字节码装载进内核,并通过一个JIT编译步骤将程序的通用字节码转换为机器特定指令集,以优化程序的执行速度。

在内核中运行时,eBPF 程序通常会挂载到一个内核钩子(hook)上,以便在特定的事件发生时被执行。例如,可以将 eBPF 程序挂载到网络协议栈的某个位置,以便在收到网络数据包时被执行。

最后,eBPF 程序还需要经过内核安全机制的检查。这是为了确保 eBPF 程序不会破坏内核的稳定性和安全性。在检查过程中,内核会对 eBPF 程序的代码进行分析,以确保它不会进行恶意操作,如系统调用、内存访问等。如果 eBPF 程序通过了内核安全机制的检查,它就可以在内核中正常运行了。在运行过程中,eBPF 程序可以访问内核的数据结构,并通过内核接口与其他组件进行交互。例如,eBPF 程序可以捕获网络数据包,并通过内核接口将它们转发给用户态的应用程序。总之,eBPF 的工作原理是通过动态加载、执行和检查无损编译过的代码来实现的。

3.环境介绍

名称版本
linux版本(centos8.5)4.18.0-348.el8.x86_64
DM88.1.4.27
pythonPython 3.6.8

4.安装环境

4.1检查环境

CONFIG_DEBUG_INFO_BTF=y必须项,否则就是操作系统不支持

[root@localhost opt]# uname -r
4.18.0-348.el8.x86_64
[root@localhost opt]# cat /boot/config-`uname -r` | grep CONFIG_DEBUG_INFO_BTF
CONFIG_DEBUG_INFO_BTF=y

4.2安装依赖包

[root@localhost opt]# dnf install -y bison cmake ethtool flex git iperf3 libstdc++-devel python3-netaddr python3-pip gcc gcc-c++ make zlib-devel elfutils-libelf-devel
[root@localhost opt]# dnf install -y clang clang-devel llvm llvm-devel llvm-static ncurses-devel
[root@localhost opt]# dnf -y install netperf
[root@localhost opt]# pip3 install pyroute2
[root@localhost opt]# ln -s /usr/bin/python3 /usr/bin/python

4.3安装并编译bcc

[root@localhost opt]# git clone https://github.com/iovisor/bcc.git
[root@localhost opt]# mkdir bcc-build
[root@localhost opt]# cd bcc-build/
[root@localhost opt]# cmake ../bcc -DCMAKE_INSTALL_PREFIX=/usr -DENABLE_LLVM_SHARED=1
[root@localhost opt]# make -j10
[root@localhost opt]# make install 

4.4添加环境变量

安装后,可以将 bcc 目录添加到$PATH,可以将其添加到 ~/.bashrc

[root@localhost opt]# vim ~/.bashrc
bcctools=/usr/share/bcc/tools
export PATH=$bcctools:$PATH
[root@localhost opt]# source ~/.bashrc

4.5安装DM并初始化实例

此步骤忽略

5.思路

5.1模拟阻塞场景

建表sql

create table lock_test01(id int primary key, name varchar(20));
create table lock_test02(id int primary key, name varchar(20));insert into lock_test01(id, name) values(1, '1cheng');
insert into lock_test01(id, name) values(2, '1gao');insert into lock_test02(id, name) values(1, '2cheng');
insert into lock_test02(id, name) values(2, '2gao');

阻塞场景

-- Session A 执行insert 不提交
insert into "SYSDBA"."LOCK_TEST01"("ID", "NAME")  VALUES(3, '3zzzz');
-- Session B 执行insert  会发生阻塞
insert into "SYSDBA"."LOCK_TEST01"("ID", "NAME")  VALUES(3, '4zzzz');

5.2判断堆栈中的核心函数

下面的堆栈是阻塞SQL的线程堆栈

Thread 127 (Thread 0x7fb29dfeb700 (LWP 19089)):
#0  0x00007fb64d8a77e8 in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x0000000000752f72 in os_event2_wait_timeout (event=event@entry=0x7fb6315e1fb0, s_time=s_time@entry=30) at /home/dmops/build/svns/1725521374498/os/osevent2.c:303
#2  0x0000000001e571cb in uevent_wait_timeout (env=env@entry=0x7fb29dfe6020, event=event@entry=0x7fb6315e1fa8, s_time=s_time@entry=30) at /home/dmops/build/svns/1725521374498/knl/uevent.c:111
#3  0x0000000000ccc186 in trx4_waiting_timeout (env=env@entry=0x7fb29dfe6020, trx=trx@entry=0x7fb6315e0898, w_time=w_time@entry=3) at /home/dmops/build/svns/1725521374498/trx/trx4.c:14642
#4  0x0000000000ccc32a in trx4_waiting_interval (env=env@entry=0x7fb29dfe6020, trx=trx@entry=0x7fb6315e0898, s_time=s_time@entry=0) at /home/dmops/build/svns/1725521374498/trx/trx4.c:14217
#5  0x0000000000cd69e4 in trx4_waiting (env=env@entry=0x7fb29dfe6020, trx=trx@entry=0x7fb6315e0898, s_time=s_time@entry=0) at /home/dmops/build/svns/1725521374498/trx/trx4.c:14383
#6  0x00000000018446f0 in nins2_check_second_unique (memobj=memobj@entry=0x7fb2e000d3b8, trx=trx@entry=0x7fb6315e0898, ptx=ptx@entry=0x7fb29dfdd2c0, pbc=pbc@entry=0x7fb29dfdcf30, bcur=bcur@entry=0x7fb29dfdce90, key=key@entry=0x7fb34c417a60, desc=desc@entry=0x7fb2ee14c098, tableid=tableid@entry=1017, search_mode=search_mode@entry=2, need_lock_row=need_lock_row@entry=1, cflt_rowid=cflt_rowid@entry=0x0, need_modify=need_modify@entry=0x7fb29dfdfb6c, pll_index_fill=pll_index_fill@entry=0) at /home/dmops/build/svns/1725521374498/op/nins2.c:8616
#7  0x0000000001847789 in nins2_second_unique_search_and_check (memobj=memobj@entry=0x7fb2e000d3b8, trx=trx@entry=0x7fb6315e0898, ptx=ptx@entry=0x7fb29dfdd2c0, pbc=pbc@entry=0x7fb29dfdcf30, index=index@entry=0x7fb2ee14bd70, table=table@entry=0x7fb2ee14aae8, key=key@entry=0x7fb34c417a60, need_lock_row=need_lock_row@entry=1, search_mode=search_mode@entry=2, desc=desc@entry=0x7fb2ee14c098, rec_len=19, rowid=rowid@entry=4, ign_cflt=ign_cflt@entry=0, cflt_rowid=cflt_rowid@entry=0x0, need_modify=need_modify@entry=0x7fb29dfdfb6c, bcur=bcur@entry=0x7fb29dfdce90, pll_index_fill=pll_index_fill@entry=0) at /home/dmops/build/svns/1725521374498/op/nins2.c:10126
#8  0x0000000001848fd9 in nins2_second_unique_insert_low (memobj=memobj@entry=0x7fb2e000d3b8, trx=0x7fb6315e0898, ptx=0x7fb29dfdd2c0, pbc=0x7fb29dfdcf30, index=index@entry=0x7fb2ee14bd70, table=0x7fb2ee14aae8, tuple=tuple@entry=0x7fb34c417998, key=key@entry=0x7fb34c417a60, need_lock_row=need_lock_row@entry=1, search_mode=search_mode@entry=2, n_rol_len_fixed_part=n_rol_len_fixed_part@entry=45, rowid=rowid@entry=4, with_trxid=with_trxid@entry=0, ign_cflt=ign_cflt@entry=0, cflt_rowid=cflt_rowid@entry=0x0, need_modify=need_modify@entry=0x7fb29dfdfb6c, bcur=bcur@entry=0x7fb29dfdce90, pll_index_fill=pll_index_fill@entry=0, org_trx_id_out=org_trx_id_out@entry=0x0) at /home/dmops/build/svns/1725521374498/op/nins2.c:10222
#9  0x00000000018492c5 in nins2_second_unique_insert (memobj=memobj@entry=0x7fb2e000d3b8, trx=<optimized out>, ptx=<optimized out>, pbc=<optimized out>, index=index@entry=0x7fb2ee14bd70, table=<optimized out>, tuple=0x7fb34c417998, key=0x7fb34c417a60, need_lock_row=1, search_mode=2, n_rol_len_fixed_part=45, rowid=4, ign_cflt=0, cflt_rowid=0x0, need_modify=0x7fb29dfdfb6c, bcur=0x7fb29dfdce90, pll_index_fill=0) at /home/dmops/build/svns/1725521374498/op/nins2.c:10267
#10 0x0000000001849a39 in nins2_index_insert_entry_low (memobj=memobj@entry=0x7fb2e000d3b8, trx=<optimized out>, ptx=ptx@entry=0x7fb29dfdd2c0, pbc=pbc@entry=0x7fb29dfdcf30, index=index@entry=0x7fb2ee14bd70, tuple=tuple@entry=0x7fb34c417998, key=0x7fb34c417998, key@entry=0x7fb34c417a60, need_lock_row=1279359584, need_lock_row@entry=1, search_mode=1, search_mode@entry=2, n_rol_len_fixed_part=2, n_rol_len_fixed_part@entry=45, rowid=0x7fb20000002d, rowid@entry=0x7fb29dfdff50, ign_cflt=4, ign_cflt@entry=0, cflt_rowid=cflt_rowid@entry=0x0, need_modify=0x0, need_modify@entry=0x7fb29dfdfb6c, table=0x7fb29dfdfb6c, table@entry=0x7fb2ee14aae8, with_rowid=2650656400, with_rowid@entry=0, vm_node=0x7fb300000000, vm_node@entry=0x7fb34c416fd0, bcur=bcur@entry=0x7fb29dfdce90, pll_index_fill=0) at /home/dmops/build/svns/1725521374498/op/nins2.c:10508
#11 0x000000000185c1f8 in nins2_index_insert_entry (env=0x7fb29dfe6020, memobj=0x7fb2e000d3b8, vm=vm@entry=0x7fb2e000d350, index=index@entry=0x7fb2ee14bd70, tuple=0x7fb34c417998, key=key@entry=0x7fb34c417a60, need_lock_low=1, n_rol_len_fixed_part=45, rowid=rowid@entry=0x7fb29dfdff50, ign_cflt=ign_cflt@entry=0, cflt_rowid=cflt_rowid@entry=0x0, need_modify=need_modify@entry=0x7fb29dfdfb6c, table=0x7fb2ee14aae8, with_rowid=0, vm_node=vm_node@entry=0x7fb34c416fd0) at /home/dmops/build/svns/1725521374498/op/nins2.c:11889
#12 0x000000000185ceea in nins2_exec_insert_low (nins2_vm=nins2_vm@entry=0x7fb34c416fd0) at /home/dmops/build/svns/1725521374498/op/nins2.c:12796
#13 0x000000000185da5f in nins2_exec_insert (nins2_vm=nins2_vm@entry=0x7fb34c416fd0) at /home/dmops/build/svns/1725521374498/op/nins2.c:13492
#14 0x000000000186077f in nins2_exec (nins2_vm=0x7fb34c416fd0) at /home/dmops/build/svns/1725521374498/op/nins2.c:18904
#15 0x000000000195eab8 in vm_run_low (vm=vm@entry=0x7fb2e000d350) at /home/dmops/build/svns/1725521374498/op/vm.c:6115
#16 0x000000000195ef30 in vm_run (vm=vm@entry=0x7fb2e000d350) at /home/dmops/build/svns/1725521374498/op/vm.c:6196
#17 0x000000000195f080 in vm_run_pln_low (env=env@entry=0x7fb29dfe6020, stmt=stmt@entry=0x7fb2e000c8f0, pln=pln@entry=0x7fb2ee138ac8, ret_ident_flag=ret_ident_flag@entry=0 '\000', n_ret_col=n_ret_col@entry=0, ret_col_ident=ret_col_ident@entry=0x0, err_desc=err_desc@entry=0x0) at /home/dmops/build/svns/1725521374498/op/vm.c:11602
#18 0x0000000001fae1d0 in ntsk_process_exec_low (env=env@entry=0x7fb29dfe6020, stmt=0x7fb2e000c8f0, pln=pln@entry=0x7fb2ee138ac8, ret_ident_flag=ret_ident_flag@entry=0 '\000', n_ret_col=<optimized out>, ret_col_ident=0x0, dlck_reprepare=dlck_reprepare@entry=0x7fb29dfe46bc) at /home/dmops/build/svns/1725521374498/mgr/ntsk.c:12603
#19 0x0000000001fb2256 in ntsk_process_prepare_and_exec (env=env@entry=0x7fb29dfe6020, sess=sess@entry=0x7fb2e00110f0, msg_in=msg_in@entry=0x7fb2e00029a8 "", stmtsql_out=stmtsql_out@entry=0x7fb29dfe57c8) at /home/dmops/build/svns/1725521374498/mgr/ntsk.c:13063
#20 0x0000000001fde785 in ntsk_process_cop (env=0x7fb29dfe6020, task=<optimized out>) at /home/dmops/build/svns/1725521374498/mgr/ntsk.c:21389
#21 0x0000000001e5b755 in uthr_db_main_for_sess (sess2=0x7fb2e00110f0) at /home/dmops/build/svns/1725521374498/knl/uthr.c:1367
#22 0x00007fb64d8a117a in start_thread () from /lib64/libpthread.so.0
#23 0x00007fb64ccb5dc3 in clone () from /lib64/libc.so.6
  1. 头部 pthread_cond_timedwait 和 uevent_wait_timeout 都是自定义函数,而不是标准库提供的系统函数。

2) os_event2_wait_timeout:这是一个封装函数,它调用 pthread_cond_timedwait 并接受一个事件和超时时间(30秒)。

  1. uevent_wait_timeout:这个函数在内核中用于等待 uevent 事件,传入的参数包括环境指针和事件指针,以及超时时间。

  2. trx4_waiting_timeout:这个函数可能是一个事务相关的等待函数,传入了环境、事务和等待时间(3秒)

根据函数命名以及堆栈的含义,pthread_cond_timedwait 和 uevent_wait_timeout 肯定是代码底层的通用函数,所以初步判断SQL阻塞使用 trx4_waiting_timeout 函数就可以 我们此时进行测试。

6.编写代码

[root@localhost opt]# vim ebpf_trx.pyfrom bcc import BPF# 定义 eBPF 程序
bpf_text = """
#include <uapi/linux/ptrace.h>
#include <linux/sched.h>
#include <linux/timekeeping.h>BPF_HASH(start_time, u64);// 处理 uprobe 事件
int trace_ntsk_process_cop(struct pt_regs *ctx) {u64 pid_tgid = bpf_get_current_pid_tgid(); // 获取 PID 和 TGIDu64 thread_id = pid_tgid >> 32; // 获取线程号u64 timestamp = bpf_ktime_get_ns();// 记录开始时间start_time.update(&pid_tgid, &timestamp);bpf_trace_printk("ntsk_process_cop called: pid=%d, thread_id=%d, timestamp=%llu", pid_tgid & 0xFFFFFFFF, thread_id, timestamp);return 0;
}// 处理返回事件
int trace_ret_ntsk_process_cop(struct pt_regs *ctx) {u64 pid_tgid = bpf_get_current_pid_tgid(); // 获取 PID 和 TGIDu64 thread_id = pid_tgid >> 32; // 获取线程号u64 *start_ts = start_time.lookup(&pid_tgid);if (start_ts != 0) {u64 end_time = bpf_ktime_get_ns();u64 total_time = end_time - *start_ts;u64 total_time_ms = total_time / 1000000;bpf_trace_printk("ntsk_process_cop exited: pid=%d, thread_id=%d, total_time=%llu ms", pid_tgid & 0xFFFFFFFF, thread_id, total_time_ms);start_time.delete(&pid_tgid);}return 0;
}
"""# 加载 eBPF 程序
b = BPF(text=bpf_text)# 设置 uprobe
b.attach_uprobe(name="/opt/dmdbms/bin/dmserver", sym="trx4_waiting_timeout", fn_name="trace_ntsk_process_cop")
b.attach_uretprobe(name="/opt/dmdbms/bin/dmserver", sym="trx4_waiting_timeout", fn_name="trace_ret_ntsk_process_cop")# 输出跟踪信息
print("正在跟踪 uprobe... 按 Ctrl-C 结束。")# 输出追踪信息
b.trace_print()

代码解释

  • BPF_HASH(start_time, u64); 创建一个哈希表 start_time,键类型为 u64,用于存储每个进程的开始时间。它通过 PID(进程标识符)来索引
  • bpf_get_current_pid_tgid(): 获取当前进程的 PID 和线程 ID
  • attach_uprobe ()表示将钩子附加到dmserver的trx4_waiting_timeout函数的头部位置
  • attach_uretprobe()表示将钩子附加到dmserver的trx4_waiting_timeout函数的结尾位置
  • 在函数开始的时候存储开始时间在函数结尾时相减就是执行该函数的耗时,并输出PID 以及 threadID即可。

7.验证代码

[root@localhost opt]# python ebpf_trx.py 

验证结果说明

  • 运行程序以后,会发现只有当SQL阻塞的时候才会输出信息(进程号、线程号、函数的执行耗时) 说明对trx4_waiting_timeout函数添加钩子是没有问题
  • 运行时会发现每隔3S输出一次,添加符号文件的堆栈可以看到trx4_waiting_timeout函数的w_time=3,这块可以一一对应。
  • 有了这些信息就能够做很多事情,比如说将信息推送到监控平台等。

8.总结与思考

  1. 利用ebpf技术在不登录数据库的情况下,通过对数据库的函数添加钩子,实时的对数据库是否存在阻塞判断
  2. 现有的监控逻辑都是新建数据库用户执行SQL语句来判断阻塞情况,告警的实时性取决于监控的周期频率,而使用ebpf技术能够解决这个痛点
  3. ebpf有多种实现方式,这里便于理解测试的话 使用python语言内置c语言的形式进行了说明。涉及到生产环境应该是使用go语言或者c语言去做能够有效避免源码泄露等问题
  4. 如给sql线程添加钩子,有代sql变量的偏移量的话,就能够不登录数据库的情况下捕获到慢SQL,就能够有效的解决很多问题了,有待探究

相关文章:

[EBPF] 实时捕获DM数据库是否存在SQL阻塞

1. 介绍 eBPF&#xff08;extened Berkeley Packet Filter&#xff09;是一种内核技术&#xff0c;它允许开发人员在不修改内核代码的情况下运行特定的功能。eBPF 的概念源自于 Berkeley Packet Filter&#xff08;BPF&#xff09;&#xff0c;后者是由贝尔实验室开发的一种网…...

秋招内推--招联金融2025

【投递方式】 直接扫下方二维码&#xff0c;或点击内推官网https://wecruit.hotjob.cn/SU61025e262f9d247b98e0a2c2/mc/position/campus&#xff0c;使用内推码 igcefb 投递&#xff09; 【招聘岗位】 后台开发 前端开发 数据开发 数据运营 算法开发 技术运维 软件测试 产品策…...

Unity2022.3.x各个版本bug集合及推荐稳定版本

最近升级到Unity2022&#xff0c;发现以下问题&#xff0c;仅作参考 2022.3.0f1 - 2022.3.6f1 粒子渲染到RenderTexture闪屏 https://issuetracker.unity3d.com/issues/android-vulkan-visualisation-corruption-occurs-when-rendering-particles-to-render-texture 2022.3.…...

SparkSQL-性能调优

祝福 在这个举国同庆的时刻&#xff0c;我们首先献上对祖国的祝福&#xff1a; 第一&#xff0c;我们感谢您给我们和平的环境&#xff0c;让我们能快乐生活 第二&#xff0c;祝福我们国家未来的路越走越宽广&#xff0c;科技更发达&#xff0c;人民更幸福 第三&#xff0c;…...

leetcode-链表篇

leetcode-707 你可以选择使用单链表或者双链表&#xff0c;设计并实现自己的链表。 单链表中的节点应该具备两个属性&#xff1a;val 和 next 。val 是当前节点的值&#xff0c;next 是指向下一个节点的指针/引用。 如果是双向链表&#xff0c;则还需要属性 prev 以指示链表中的…...

JetLinks物联网平台微服务化系列文章介绍

橙蜂智能公司致力于提供先进的人工智能和物联网解决方案&#xff0c;帮助企业优化运营并实现技术潜能。公司主要服务包括AI数字人、AI翻译、AI知识库、大模型服务等。其核心价值观为创新、客户至上、质量、合作和可持续发展。 橙蜂智农的智慧农业产品涵盖了多方面的功能&#x…...

【QT Quick】基础语法:导入外部QML文件

在实际项目中&#xff0c;代码通常分为多个文件进行模块化管理&#xff0c;这样可以方便代码重用&#xff0c;例如统一风格或共享功能模块。我们将在此部分学习如何创建 QML 项目&#xff0c;并演示如何访问外部代码&#xff0c;包括其他 QML 文件、库文件以及 JS 代码。 准备…...

Llama 系列简介与 Llama3 预训练模型推理

1. Llama 系列简介 1.1 Llama1 由 Meta AI 发布&#xff0c;包含 7B、13B、33B 和 65B 四种参数规模的开源基座语言模型 数据集&#xff1a;模型训练数据集使用的都是开源的数据集&#xff0c;总共 1.4T token 模型结构&#xff1a;原始的 Transformer 由编码器&#xff08…...

【AIGC】ChatGPT提示词助力自媒体内容创作升级

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;高效仿写专家级文章提示词使用方法 &#x1f4af;CSDN博主账号分析提示词使用方法 &#x1f4af;自媒体爆款文案优化助手提示词使用方法 &#x1f4af;小结 &#x1f4af…...

SSTI基础

<aside> &#x1f4a1; 简介 </aside> 原理 又名&#xff1a;Flask模版注入 模版种类 **Twig{{7*7}}结果49 jinja2{{7*7}}结果为7777777 //jinja2的常见参数是name smarty7{*comment*}7为77**<aside> &#x1f4a1; flask实例 </aside> **from …...

10.1软件工程知识详解上

软件工程概述 软件开发生命周期 软件定义时期&#xff1a;包括可行性研究和详细需求分析过程&#xff0c;任务是确定软件开发工程必须完成的总目标&#xff0c;具体可分成问题定义、可行性研究、需求分析等。软件开发时期&#xff1a;就是软件的设计与实现&#xff0c;可分成…...

03Frenet与Cardesian坐标系(Frenet转Cardesian公式推导)

Frenet转Cardesian 1 明确目标 已知车辆质点在Frenet坐标系下的状态&#xff1a; Frenet 坐标系下的纵向坐标&#xff1a; s s s纵向速度&#xff1a; s ˙ \dot{s} s˙纵向加速度&#xff1a; s \ddot{s} s横向坐标&#xff1a; l l l横向速度&#xff1a; l ˙ \dot{l} l…...

knowLedge-Vue I18n 是 Vue.js 的国际化插件

1.简介 Vue I18n 是 Vue.js 的国际化插件&#xff0c;它允许开发者根据不同的语言环境显示不同的文本&#xff0c;支持多语言。 Vue I18n主要有两个版本&#xff1a;v8和v9。v8版本适用于Vue2框架。v9版本适用于Vue3框架。 2. 翻译实现原理 Vue I18n 插件通过在 Vue 实例中注…...

【开源免费】基于SpringBoot+Vue.JS微服务在线教育系统(JAVA毕业设计)

本文项目编号 T 060 &#xff0c;文末自助获取源码 \color{red}{T060&#xff0c;文末自助获取源码} T060&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…...

expressjs 中的mysql.createConnection,execute 怎么使用

在 Express.js 应用中使用 MySQL 数据库&#xff0c;你通常会使用 mysql 或 mysql2 这样的库来创建和管理数据库连接&#xff0c;并执行查询。然而&#xff0c;mysql.createConnection 并不直接提供 execute 方法。相反&#xff0c;你可以使用 query 方法来执行 SQL 语句。 以…...

每日一题|983. 最低票价|动态规划、记忆化递归

本题求解最小值&#xff0c;思路是动态规划&#xff0c;但是遇到的问题是&#xff1a;动态规划更新的顺序和步长&#xff0c;以及可能存在的递归溢出问题。 1、确定dp数组含义 dp[i]表示第i天到最后一天&#xff08;可能不在需要出行的天数里&#xff09;&#xff0c;需要花费…...

oracle 正则 匹配 身份正 手机号

1.正则匹配身份证号: regexp_like(card_id,^[1-9]\d{5}(18|19|20)?\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$) ^[1-9]\d{5}(18|19|20)?\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$ ^[1-9]&#xff1a;第一位数字不能为0。 \d{5}&#xff1a;接下来…...

在树莓派上部署开源监控系统 ZoneMinder

原文&#xff1a;https://blog.iyatt.com/?p17425 前言 自己搭建&#xff0c;可以用手里已有的设备&#xff0c;不需要额外买。这套系统的源码是公开的&#xff0c;录像数据也掌握在自己手里&#xff0c;不经过不可控的三方。 支持设置访问账号 可以保存录像&#xff0c;启…...

2022年6月 Frontier 获得性能第一的论文翻译

为百万兆级加速架构做高性能 Linpack 优化 摘要 我们详细叙述了在 rocHPL 中做的性能优化&#xff0c;rocHPL 是 AMD 对 HPL 基准的开源实现&#xff0c;主要是针对节点进行优化的架构&#xff0c;是为百万兆级系统而设计的&#xff0c;比如&#xff1a;Frontier suppercomput…...

B2B商城交易解决方案:赋能企业有效重塑采购与销售新生态

在电商零售领域&#xff0c;商城系统始终是企业搭建商城的关键利器。 伴随着电商行业的蓬勃发展&#xff0c;各类新模式层出不穷&#xff0c;各种商城系统也应运而生&#xff0c;其中B2B商城更是最为常见的一种。 近年来&#xff0c;得益于电子商务的迅猛发展&#xff0c;B2B商…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

React第五十七节 Router中RouterProvider使用详解及注意事项

前言 在 React Router v6.4 中&#xff0c;RouterProvider 是一个核心组件&#xff0c;用于提供基于数据路由&#xff08;data routers&#xff09;的新型路由方案。 它替代了传统的 <BrowserRouter>&#xff0c;支持更强大的数据加载和操作功能&#xff08;如 loader 和…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

大模型多显卡多服务器并行计算方法与实践指南

一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别

OpenPrompt 和直接对提示词的嵌入向量进行训练有什么区别 直接训练提示词嵌入向量的核心区别 您提到的代码: prompt_embedding = initial_embedding.clone().requires_grad_(True) optimizer = torch.optim.Adam([prompt_embedding...

智能仓储的未来:自动化、AI与数据分析如何重塑物流中心

当仓库学会“思考”&#xff0c;物流的终极形态正在诞生 想象这样的场景&#xff1a; 凌晨3点&#xff0c;某物流中心灯火通明却空无一人。AGV机器人集群根据实时订单动态规划路径&#xff1b;AI视觉系统在0.1秒内扫描包裹信息&#xff1b;数字孪生平台正模拟次日峰值流量压力…...

Java多线程实现之Thread类深度解析

Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

基于TurtleBot3在Gazebo地图实现机器人远程控制

1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...

协议转换利器,profinet转ethercat网关的两大派系,各有千秋

随着工业以太网的发展&#xff0c;其高效、便捷、协议开放、易于冗余等诸多优点&#xff0c;被越来越多的工业现场所采用。西门子SIMATIC S7-1200/1500系列PLC集成有Profinet接口&#xff0c;具有实时性、开放性&#xff0c;使用TCP/IP和IT标准&#xff0c;符合基于工业以太网的…...