[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 |
| DM8 | 8.1.4.27 |
| python | Python 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
- 头部 pthread_cond_timedwait 和 uevent_wait_timeout 都是自定义函数,而不是标准库提供的系统函数。
2) os_event2_wait_timeout:这是一个封装函数,它调用 pthread_cond_timedwait 并接受一个事件和超时时间(30秒)。
-
uevent_wait_timeout:这个函数在内核中用于等待 uevent 事件,传入的参数包括环境指针和事件指针,以及超时时间。
-
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, ×tamp);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 和线程 IDattach_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.总结与思考
- 利用ebpf技术在不登录数据库的情况下,通过对数据库的函数添加钩子,实时的对数据库是否存在阻塞判断
- 现有的监控逻辑都是新建数据库用户执行SQL语句来判断阻塞情况,告警的实时性取决于监控的周期频率,而使用ebpf技术能够解决这个痛点
- ebpf有多种实现方式,这里便于理解测试的话 使用python语言内置c语言的形式进行了说明。涉及到生产环境应该是使用go语言或者c语言去做能够有效避免源码泄露等问题
- 如给sql线程添加钩子,有代sql变量的偏移量的话,就能够不登录数据库的情况下捕获到慢SQL,就能够有效的解决很多问题了,有待探究
相关文章:
[EBPF] 实时捕获DM数据库是否存在SQL阻塞
1. 介绍 eBPF(extened Berkeley Packet Filter)是一种内核技术,它允许开发人员在不修改内核代码的情况下运行特定的功能。eBPF 的概念源自于 Berkeley Packet Filter(BPF),后者是由贝尔实验室开发的一种网…...
秋招内推--招联金融2025
【投递方式】 直接扫下方二维码,或点击内推官网https://wecruit.hotjob.cn/SU61025e262f9d247b98e0a2c2/mc/position/campus,使用内推码 igcefb 投递) 【招聘岗位】 后台开发 前端开发 数据开发 数据运营 算法开发 技术运维 软件测试 产品策…...
Unity2022.3.x各个版本bug集合及推荐稳定版本
最近升级到Unity2022,发现以下问题,仅作参考 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-性能调优
祝福 在这个举国同庆的时刻,我们首先献上对祖国的祝福: 第一,我们感谢您给我们和平的环境,让我们能快乐生活 第二,祝福我们国家未来的路越走越宽广,科技更发达,人民更幸福 第三,…...
leetcode-链表篇
leetcode-707 你可以选择使用单链表或者双链表,设计并实现自己的链表。 单链表中的节点应该具备两个属性:val 和 next 。val 是当前节点的值,next 是指向下一个节点的指针/引用。 如果是双向链表,则还需要属性 prev 以指示链表中的…...
JetLinks物联网平台微服务化系列文章介绍
橙蜂智能公司致力于提供先进的人工智能和物联网解决方案,帮助企业优化运营并实现技术潜能。公司主要服务包括AI数字人、AI翻译、AI知识库、大模型服务等。其核心价值观为创新、客户至上、质量、合作和可持续发展。 橙蜂智农的智慧农业产品涵盖了多方面的功能&#x…...
【QT Quick】基础语法:导入外部QML文件
在实际项目中,代码通常分为多个文件进行模块化管理,这样可以方便代码重用,例如统一风格或共享功能模块。我们将在此部分学习如何创建 QML 项目,并演示如何访问外部代码,包括其他 QML 文件、库文件以及 JS 代码。 准备…...
Llama 系列简介与 Llama3 预训练模型推理
1. Llama 系列简介 1.1 Llama1 由 Meta AI 发布,包含 7B、13B、33B 和 65B 四种参数规模的开源基座语言模型 数据集:模型训练数据集使用的都是开源的数据集,总共 1.4T token 模型结构:原始的 Transformer 由编码器(…...
【AIGC】ChatGPT提示词助力自媒体内容创作升级
博客主页: [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 💯前言💯高效仿写专家级文章提示词使用方法 💯CSDN博主账号分析提示词使用方法 💯自媒体爆款文案优化助手提示词使用方法 💯小结 💯…...
SSTI基础
<aside> 💡 简介 </aside> 原理 又名:Flask模版注入 模版种类 **Twig{{7*7}}结果49 jinja2{{7*7}}结果为7777777 //jinja2的常见参数是name smarty7{*comment*}7为77**<aside> 💡 flask实例 </aside> **from …...
10.1软件工程知识详解上
软件工程概述 软件开发生命周期 软件定义时期:包括可行性研究和详细需求分析过程,任务是确定软件开发工程必须完成的总目标,具体可分成问题定义、可行性研究、需求分析等。软件开发时期:就是软件的设计与实现,可分成…...
03Frenet与Cardesian坐标系(Frenet转Cardesian公式推导)
Frenet转Cardesian 1 明确目标 已知车辆质点在Frenet坐标系下的状态: Frenet 坐标系下的纵向坐标: s s s纵向速度: s ˙ \dot{s} s˙纵向加速度: s \ddot{s} s横向坐标: l l l横向速度: l ˙ \dot{l} l…...
knowLedge-Vue I18n 是 Vue.js 的国际化插件
1.简介 Vue I18n 是 Vue.js 的国际化插件,它允许开发者根据不同的语言环境显示不同的文本,支持多语言。 Vue I18n主要有两个版本:v8和v9。v8版本适用于Vue2框架。v9版本适用于Vue3框架。 2. 翻译实现原理 Vue I18n 插件通过在 Vue 实例中注…...
【开源免费】基于SpringBoot+Vue.JS微服务在线教育系统(JAVA毕业设计)
本文项目编号 T 060 ,文末自助获取源码 \color{red}{T060,文末自助获取源码} T060,文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析 六、核心代码6.1 查…...
expressjs 中的mysql.createConnection,execute 怎么使用
在 Express.js 应用中使用 MySQL 数据库,你通常会使用 mysql 或 mysql2 这样的库来创建和管理数据库连接,并执行查询。然而,mysql.createConnection 并不直接提供 execute 方法。相反,你可以使用 query 方法来执行 SQL 语句。 以…...
每日一题|983. 最低票价|动态规划、记忆化递归
本题求解最小值,思路是动态规划,但是遇到的问题是:动态规划更新的顺序和步长,以及可能存在的递归溢出问题。 1、确定dp数组含义 dp[i]表示第i天到最后一天(可能不在需要出行的天数里),需要花费…...
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]:第一位数字不能为0。 \d{5}:接下来…...
在树莓派上部署开源监控系统 ZoneMinder
原文:https://blog.iyatt.com/?p17425 前言 自己搭建,可以用手里已有的设备,不需要额外买。这套系统的源码是公开的,录像数据也掌握在自己手里,不经过不可控的三方。 支持设置访问账号 可以保存录像,启…...
2022年6月 Frontier 获得性能第一的论文翻译
为百万兆级加速架构做高性能 Linpack 优化 摘要 我们详细叙述了在 rocHPL 中做的性能优化,rocHPL 是 AMD 对 HPL 基准的开源实现,主要是针对节点进行优化的架构,是为百万兆级系统而设计的,比如:Frontier suppercomput…...
B2B商城交易解决方案:赋能企业有效重塑采购与销售新生态
在电商零售领域,商城系统始终是企业搭建商城的关键利器。 伴随着电商行业的蓬勃发展,各类新模式层出不穷,各种商城系统也应运而生,其中B2B商城更是最为常见的一种。 近年来,得益于电子商务的迅猛发展,B2B商…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
