【PostgreSQL】PG数据库表“膨胀”粗浅学习

news2024/10/7 13:55:00

文章目录

  • 1 为什么需要关注表膨胀?
  • 2 如何确定是否发生了表膨胀?
    • 2.1 通过查询表的死亡元组占比情况来判断膨胀率
      • 2.1.1 指定数据库和表名
      • 2.1.2 查询数据库里面所有表的膨胀情况
  • 3 膨胀的原理
    • 3.1 什么是膨胀?膨胀率?
    • 3.2 哪些数据库元素会发生膨胀?
    • 3.3 为什么会产生膨胀的现象?
    • 3.4 必须要做清理的原因?
    • 3.5 VACUUM进度报告
  • 4 如何处理表膨胀问题?
    • 4.1 简单粗暴但是有效彻底的空间回收:“vacuum full 表名”-不推荐
      • 4.1.1 FULL参数使用注意
      • 4.1.2 FULL参数使用示例
    • 4.2 相对优雅一些的回收方式:“vacuum 表名”-推荐
      • 4.2.1 标准的vacuum(不带full参数的方式)
      • 4.2.2 标准VACUUM回收清理使用示例
      • 4.2.3 标准vacuum支持多个option命令方式:vacuum (verbose,analyze) mytest;
  • 5 膨胀产生后的危害&如何长远应对?
    • 5.1 产生哪些危害?
    • 5.2 如何应对?

1 为什么需要关注表膨胀?

有一天,发现数据库所在的服务器上的空间在报不够用了,有一天发现某些和数据库有关的功能的莫名的变慢了,有一天发现某些功能时快时慢。。。
这些时候,我们可能要考虑一下是不是有表膨胀在发生?

2 如何确定是否发生了表膨胀?

2.1 通过查询表的死亡元组占比情况来判断膨胀率

pg_stat_all_tables里面的relname是表名。 可以看到如果类似最后一列dead_tup_ratior如果值很大,一般来说大于50了,那么一定要介入处理了。这个值相当于是无效数据的占比。

2.1.1 指定数据库和表名

下面的示例是:数据库名是test,数据库表是mytest

test=# select schemaname||'.'||relname as table_name,
       pg_size_pretty(pg_relation_size(schemaname||'.'||relname)) as table_size,
    n_dead_tup,
    n_live_tup,
    round(n_dead_tup*100/(n_live_tup+n_dead_tup),1) as dead_tup_ratio
from pg_stat_all_tables
where n_live_tup + n_dead_tup <> 0 and relname='mytest';
  table_name   | table_size | n_dead_tup | n_live_tup | dead_tup_ratio
---------------+------------+------------+------------+----------------
 public.mytest | 1042 MB    |   10000001 |    5999859 |           62.0
(1 row)

2.1.2 查询数据库里面所有表的膨胀情况

select schemaname||'.'||relname as table_name,
       pg_size_pretty(pg_relation_size(schemaname||'.'||relname)) as table_size,
	   n_dead_tup,
	   n_live_tup,
	   round(n_dead_tup*100/(n_live_tup+n_dead_tup),1) as dead_tup_ratio
from pg_stat_all_tables
where n_live_tup + n_dead_tup <> 0
order by dead_tup_ratio desc;

3 膨胀的原理

3.1 什么是膨胀?膨胀率?

顾名思义,本来应该是一个大小,但是因为某种原因,它的大小变得更大了,甚至超乎想象的那么大。这就是发生了膨胀,而其中的膨胀的程度的体现,就是膨胀率。因此膨胀率可以直观的体现膨胀到底有多厉害。
反观数据库的膨胀的理解,一张A表或者A表的索引正常应该是占用一个大小的空间,但是查出来实际占用超过了这个空间的大小,往往随着时间的推移可能会占用的越来越来离谱。

3.2 哪些数据库元素会发生膨胀?


数据库表、索引

*索引实际会和表强关联,因此,可以比较泛指到就是表膨胀。

3.3 为什么会产生膨胀的现象?

之所以产生膨胀的原因跟PostgreSQL数据库的数据维护方式是息息相关的,
PG使用MVCC(多版本并发控制),
实际上MVCC是oracle、sqlserver数据库也使用的核心原理,但是新旧版本的数据存储的机制有所不同,因此造就了各个数据库在膨胀现象的表现有所不同。
sqlserver数据库:旧版本的数据专门写入到临时表中,新数据写入日志,然后再去更改数据。新旧分别放在不同的地方,膨胀的情况相对低一点,但是也会有这种情况发生,发生后,也需要按照SQLSERVER相关的处理方式进行。
oracle数据库:旧版本的数据放到UNDO,新数据放到REDO,然后更改数据。oracle数据库本身对redo、undo文件有自动清理、扩展的机制,因此总体来说对膨胀的控制相对可控,但是也不排除处问题的情况。有的时候也需要有重建undo文件的事情发生。
PG数据库:旧版本标示为无效,新数据写入日志,执行成功后把新版本的数据写入到新的位置。旧版本的数据在仍然是存储在表中,只是标示为无效,如果不及时做清理,那么无效的数据会占用空间越来越大,这样就发生了膨胀。

对于PG数据库,它把旧版本、新版本的表数据都同时存储在业务实际访问的表中,也称为数据页中,只是对于就旧版本的数据元组做了一个标记。因此,如果没有及时清理的话,导致数据库表臃肿,会很容易导致正常访问表的操作因此发生异常的现象。
delete、update操作会引发数据上的变化,因此,如果实际使用表会频繁出现删除和更新数据,这种情况下会很容易出现死亡元组,如果经常有大量数据的删除和更新,那么这个表会比较容易出现大的膨胀现象。

3.4 必须要做清理的原因?

PostgreSQL的VACUUM命令出于几个原因必须定期处理每一个表:

恢复或重用被已更新或已删除行所占用的磁盘空间。
更新被PostgreSQL查询规划器使用的数据统计信息。
更新可见性映射,它可以加速只用索引的扫描。
保护老旧数据不会由于事务ID回卷或多事务ID回卷而丢失。

VACUUM后,会更新pg_class等其他的表,会优化索引查询、优化执行计划等,进而达到恢复数据库表相关操作的性能。

3.5 VACUUM进度报告

只要VACUUM正在运行,每一个当前正在清理的后端(包括autovacuum工作者进程)在pg_stat_progress_vacuum视图中都会有一行。下面的表描述了将被报告的信息并且提供了如何解释它们的信息。VACUUM FULL命令的进度是通过pg_stat_progress_cluster报告的,因为VACUUM FULL和CLUSTER都是重写表,而普通的VACUUM只是原地修改表。

pg_stat_progress_vacuum视图说明:

序号类型描述
1pidinteger后端的进程ID。
2datidoid这个后端连接的数据库的OID。
3datnamename这个后端连接的数据库的名称。
4relidoid被vacuum的表的OID。
5phasetextvacuum的当前处理阶段。
6heap_blks_totalbigint该表中堆块的总数。这个数字在扫描开始时报告,之后增加的块将不会(并且不需要)被这个VACUUM访问。
7heap_blks_scannedbigint被扫描的堆块数量。由于可见性映射被用来优化扫描,一些块将被跳过而不做检查,被跳过的块会被包括在这个总数中,因此当清理完成时这个数字最终将会等于heap_blks_total。仅当处于扫描堆阶段时这个计数器才会前进。
8heap_blks_vacuumedbigint被清理的堆块数量。除非表没有索引,这个计数器仅在处于清理堆阶段时才会前进。不包含死亡元组的块会被跳过,因此这个计数器可能有时会向前跳跃一个比较大的增量。
9index_vacuum_countbigint已完成的索引清理周期数。
10max_dead_tuplesbigint在需要执行一个索引清理周期之前我们可以存储的死亡元组数,取决于maintenance_work_mem。
11num_dead_tuplesbigint从上一个索引清理周期以来收集的死亡元组数。

在这里插入图片描述

VACUUM的阶段:

序号阶段描述
1初始化VACUUM正在准备开始扫描堆。这个阶段应该很简短。
2扫描堆VACUUM正在扫描堆。如果需要,它将会对每个页面进行修建以及碎片整理,并且可能会执行冻结动作。heap_blks_scanned列可以用来监控扫描的进度。
3清理索引VACUUM当前正在清理索引。如果一个表拥有索引,那么每次清理时这个阶段会在堆扫描完成后至少发生一次。如果maintenance_work_mem不足以存放找到的死亡元组,则每次清理时会多次清理索引。
4清理堆VACUUM当前正在清理堆。清理堆与扫描堆不是同一个概念,清理堆发生在每一次清理索引的实例之后。如果heap_blks_scanned小于heap_blks_total,系统将在这个阶段完成之后回去扫描堆;否则,系统将在这个阶段完成后开始清理索引。
5清除索引VACUUM当前正在清除索引。这个阶段发生在堆被完全扫描并且对堆和索引的所有清理都已经完成以后。
6截断堆VACUUM正在截断堆,以便把关系尾部的空页面返还给操作系统。这个阶段发生在清除完索引之后。
7执行最后的清除VACUUM在执行最终的清除。在这个阶段中,VACUUM将清理空闲空间映射、更新pg_class中的统计信息并且将统计信息报告给统计收集器。当这个阶段完成时,VACUUM也就结束了。

4 如何处理表膨胀问题?

*注意考虑到业务忙时影响

4.1 简单粗暴但是有效彻底的空间回收:“vacuum full 表名”-不推荐


注意有失败的可能:
vacuum full 需要注意看看是否操作的表多大,磁盘空闲空间是否充足,否则会命令执行失败。
如果遇到了该问题,或者做之前,提前在服务器上进行磁盘空间释放,确保无用的文件再去删除。务必注意生产环境实施该操作要谨慎!高危!

4.1.1 FULL参数使用注意

序号vacuum full使用注意具体说明
用途通常用于需要从表中回收庞大的空间时候,而且最好是释放给操作系统使用,一般不建议使用。
1缺点需要给清理的表加上排它锁,执行操作期间对该表的insert、update、select、delete等操作会被阻塞
2缺点需要比较长的时间,时间长短跟表本身的大小以及膨胀的程度相关
3缺点需要临时额外占用操作系统上的磁盘空间,用于创建该表的新的拷贝,在操作执行完成前不会释放旧的拷贝。
1优点可以回收更多空间
2优点回收到的空间可以释放给操作系统,真正的物理上清理释放

选择“FULL”清理,它可以收回更多空间,并且需要更长时间和表上的排他锁。这种方法还需要额外的磁盘空间,因为它会创建该表的一个新拷贝,并且在操作完成之前都不会释放旧的拷贝。通常这种方法只用于需要从表中收回数量庞大的空间时。

不引入其他插件的情况下,如果能够挑选到业务不繁忙的时候或者说能够接受短时间内的锁表、功能卡顿的话,可以执行下面的语句:VACUUM FULL 具体表名;
使用前,务必关注上述列出的缺点。

4.1.2 FULL参数使用示例

膨胀的时候的空间占用,1个G左右:

test=# select schemaname||'.'||relname as table_name,
       pg_size_pretty(pg_relation_size(schemaname||'.'||relname)) as table_size,
    n_dead_tup,
    n_live_tup,
    round(n_dead_tup*100/(n_live_tup+n_dead_tup),1) as dead_tup_ratio
from pg_stat_all_tables
where n_live_tup + n_dead_tup <> 0 and relname='mytest';
  table_name   | table_size | n_dead_tup | n_live_tup | dead_tup_ratio
---------------+------------+------------+------------+----------------
 public.mytest | 1042 MB    |   10000001 |    5999859 |           62.0
(1 row)

完成回收后,空间占用下降到了391MB

test=# VACUUM FULL mytest;
VACUUM
test=#
test=# select schemaname||'.'||relname as table_name,
       pg_size_pretty(pg_relation_size(schemaname||'.'||relname)) as table_size,
    n_dead_tup,
    n_live_tup,
    round(n_dead_tup*100/(n_live_tup+n_dead_tup),1) as dead_tup_ratio
from pg_stat_all_tables
where n_live_tup + n_dead_tup <> 0 and relname='mytest';
  table_name   | table_size | n_dead_tup | n_live_tup | dead_tup_ratio
---------------+------------+------------+------------+----------------
 public.mytest | 391 MB     |          0 |    7481453 |            0.0
(1 row)

vacuum命令帮助:
http://postgres.cn/docs/12/sql-vacuum.html

4.2 相对优雅一些的回收方式:“vacuum 表名”-推荐


注意可能有失败的可能:
1、长事务,如果当存在长时间运行的事务(长事务)对表进行操作(如insert、delete、update等操作且未提交),VACUUM操作会失效,因为此时的死元组对长事务是可见的,尽管对其他事务不可见,但仍然无法删除死元组‌。

如果碰到了,解决的办法就是,杀死长事务或者以后合理设置idle_in_transaction_session_timeout 参数,不要让连接不必要地“闲置在事务中”。配置参数idle_in_transaction_session_timeout可以被用来自动断开拖延会话的连接。
实际上,执行的失败提示信息中会写明有更旧的xmin水平

SELECT pid, datname, usename, state, backend_xmin
FROM pg_stat_activity
WHERE backend_xmin IS NOT NULL
ORDER BY age(backend_xmin) DESC;

查询到后,pg_terminate_backend(pid)来做终止事务
2、 废弃的复制槽 复制延迟或者备服务器关闭

SELECT slot_name, slot_type, database, xmin
FROM pg_replication_slots
ORDER BY age(xmin) DESC;

使用pg_drop_replication_slot()删除复制槽

test=# select  pg_drop_replication_slot('aaaa');

3、孤立的准备事务 某种异常情况下,导致事务处于准备好的状态但是未继续提交或者中止。

SELECT gid, prepared, owner, database, transaction AS xmin
FROM pg_prepared_xacts
ORDER BY age(transaction) DESC;
ROLLBACK PREPARED transaction_id
例如:ROLLBACK PREPARED '123'

4.2.1 标准的vacuum(不带full参数的方式)

序号标准vacuum使用注意使用说明
1用途推荐日常使用,设置合理定时在非忙时执行,但是VACUUM使用过程会带来I/O流量的的产生,会导致数据库其他会话的操作性能变差,因此使用过程中需要搭配一些策略参数来防护后台清理工作给数据库性能带来的冲击。例如:vacuum_cost_delay、vacuum_cost_page_hit 、vacuum_cost_page_miss 、vacuum_cost_page_dirty 、vacuum_cost_limit 将导致清理进程休眠的累计代价。默认值为200。
1缺点标准的vacuum完成回收后的空间不会实际释放给操作系统,只是标记为继续给当前的表或者索引复用。当膨胀的程度很高的时候,该方式无法释放占用空间给物理服务器操作系统使用。除非在特殊的情况中表尾部的一个或多个页面变成完全空闲并且能够很容易地得到一个排他表锁。
2缺点执行过程中会可能产生大量I/O流量,对数据库处理性能产生一定负面影响。
1优点不阻塞基础数据库表增删改查,标准形式的VACUUM可以和生产数据库操作并行运行(SELECT、INSERT、UPDATE和DELETE等命令将继续正常工作,但在清理期间你无法使用ALTER TABLE等命令来更新表的定义)
2优点执行耗时相对FULL参数方式较短

4.2.2 标准VACUUM回收清理使用示例

回收清理前,表占用的大小空间table_size是781M,膨胀比例为50%,
执行标准的回收后,表占用的大小空间table_size还是781M,死亡元组为0。
pg_stat_all_tables字段 last_autovacuum 表示最近一次自动回收的时间。

test=# select schemaname||'.'||relname as table_name,
       pg_size_pretty(pg_relation_size(schemaname||'.'||relname)) as table_size,
    n_dead_tup,
    n_live_tup,
    round(n_dead_tup*100/(n_live_tup+n_dead_tup),1) as dead_tup_ratio
from pg_stat_all_tables
where n_live_tup + n_dead_tup <> 0 and relname='mytest';
  table_name   | table_size | n_dead_tup | n_live_tup | dead_tup_ratio
---------------+------------+------------+------------+----------------
 public.mytest | 781 MB     |    6000001 |    5995257 |           50.0
(1 row)

test=# \timing on
Timing is on.
test=# vacuum mytest;
VACUUM
Time: 29512.550 ms (00:29.513)
test=# select schemaname||'.'||relname as table_name,
       pg_size_pretty(pg_relation_size(schemaname||'.'||relname)) as table_size,
    n_dead_tup,
    n_live_tup,
    round(n_dead_tup*100/(n_live_tup+n_dead_tup),1) as dead_tup_ratio
from pg_stat_all_tables
where n_live_tup + n_dead_tup <> 0 and relname='mytest';
  table_name   | table_size | n_dead_tup | n_live_tup | dead_tup_ratio
---------------+------------+------------+------------+----------------
 public.mytest | 781 MB     |          0 |    2997602 |            0.0
(1 row)

Time: 124.583 ms
test=#

再次执行vacuum full mytest,再查询表占用大小table_size为391M,空间直接释放了一半,这是把空间释放到了操作系统的效果。

test=# vacuum full mytest;
VACUUM
Time: 54052.374 ms (00:54.052)
test=# select schemaname||'.'||relname as table_name,
       pg_size_pretty(pg_relation_size(schemaname||'.'||relname)) as table_size,
    n_dead_tup,
    n_live_tup,
    round(n_dead_tup*100/(n_live_tup+n_dead_tup),1) as dead_tup_ratio
from pg_stat_all_tables
where n_live_tup + n_dead_tup <> 0 and relname='mytest';
  table_name   | table_size | n_dead_tup | n_live_tup | dead_tup_ratio
---------------+------------+------------+------------+----------------
 public.mytest | 391 MB     |          0 |    5972470 |            0.0
(1 row)

Time: 22.492 ms
test=#

4.2.3 标准vacuum支持多个option命令方式:vacuum (verbose,analyze) mytest;

VERBOSE
为每个表打印一份详细的清理活动报告。

ANALYZE
更新优化器用以决定最有效执行一个查询的方法的统计信息。

test=# vacuum (verbose,analyze) mytest;
INFO:  vacuuming "public.mytest"
INFO:  index "mytest_pkey" now contains 6000001 row versions in 32905 pages
DETAIL:  0 index row versions were removed.
16450 index pages have been deleted, 16450 are currently reusable.
CPU: user: 0.10 s, system: 0.27 s, elapsed: 0.65 s.
INFO:  "mytest": found 0 removable, 2 nonremovable row versions in 1 out of 100001 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 853
There were 0 unused item pointers.
Skipped 0 pages due to buffer pins, 50000 frozen pages.
0 pages are entirely empty.
CPU: user: 0.11 s, system: 0.27 s, elapsed: 0.66 s.
INFO:  vacuuming "pg_toast.pg_toast_16779"
INFO:  index "pg_toast_16779_index" now contains 0 row versions in 1 pages
DETAIL:  0 index row versions were removed.
0 index pages have been deleted, 0 are currently reusable.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO:  "pg_toast_16779": found 0 removable, 0 nonremovable row versions in 0 out of 0 pages
DETAIL:  0 dead row versions cannot be removed yet, oldest xmin: 853
There were 0 unused item pointers.
Skipped 0 pages due to buffer pins, 0 frozen pages.
0 pages are entirely empty.
CPU: user: 0.00 s, system: 0.00 s, elapsed: 0.00 s.
INFO:  analyzing "public.mytest"
INFO:  "mytest": scanned 30000 of 100001 pages, containing 1793880 live rows and 0 dead rows; 30000 rows in sample, 5979660 estimated total rows
VACUUM
Time: 2096.122 ms (00:02.096)
test=#

5 膨胀产生后的危害&如何长远应对?

5.1 产生哪些危害?

如果对于膨胀的情况听之任之的化,看得见的危害有哪些呢?按照出现的时间序来看:
第一、数据库表占用空间越来越大
第二、数据库对执行计划的选择不是最高效的
第三、普通的数据库表插入、删除、查询都变慢了
第四、突然有一天发现整个系统都慢起来了
第五、发现数据库磁盘配额报告警了
第六、扩展磁盘配额后,过段时间又继续报数据库磁盘配额不足
第七、数据库所在服务器磁盘空间不足
第八、所有和数据库部署在同一个服务器上的应用无法正常创建文件
第九、整个服务器系统宕机了

看起来就是慢慢恶化的过程,实际情况的确也会劣化的非常快。

5.2 如何应对?

序号产生膨胀的可能原因应对举措
1delete减少大量的删除动作,优化删除语句效率,减少耗时。常规建议开启autovacuum进行清理回收。
2update减少大量更新动作,优化更新语句效率,减少耗时。常规建议开启autovacuum进行清理回收。
3select长时间占用优化select查询语句,降低执行查询耗时。减少针对大表的全表扫描。
4索引创建常规建议开启autovacuum进行清理回收。
5数据库事务回滚常规建议开启autovacuum进行清理回收。
6系统异常导致的其他意外情况常规建议开启autovacuum进行清理回收。必要的时候执行vacuum full手动回收。
7IO性能较差优化磁盘使用计划,避免磁盘I/O浪费,减少任务堆积访问数据库配置SSD,或者调整raid模式到I/O更好的方式。
8内存资源紧张建议根据业务特性情况,考虑到业务峰值情况,尽量分配充分的内存资源。且内存的分配要充分考虑PG数据库系统参数的各个值,包括work_mem、shared_buffer等
9CPU资源紧张建议根据业务特性情况,考虑到业务峰值情况,尽量分配充分的CPU资源。
10磁盘资源不足max_wal_size和wal_segment_size,特别是前面的max_wal_size在业务量存在突发海量更新数据的情况下,这个参数需要扩大,具体可以扩大到多少需要充分考虑一下磁盘的空闲空间。 如果这个值设置不当会引起主备PG同步复制流中断。
10PG系统参数设置不合理适当针对部分PG参数进行调优,shared_buffers 、temp_buffers 、max_prepared_transactions 、work_mem 、maintenance_work_mem 等PG参数调优
11没有开启自动回收清理建议开启autovacuum,但是需要根据各自的业务特性确定自动运行回收的策略。另外注意,这个开关可以控制到具体的表级别。执行命令show autovacuum查看开启状态。它的目的是自动执行VACUUM和ANALYZE 命令。当它被启用时,自动清理会检查被大量插入、更新或删除元组的表。这些检查会利用统计信息收集功能,因此除非track_counts被设置为true,自动清理不能被使用。在默认配置下,自动清理是被启用的并且相关配置参数已被正确配置。
12操作系统或者服务器或者数据库异常关闭检查是否有发生膨胀,可以使用vacuum手动清理。

修改具体表的自动回收开关autovacuum,例如:

test=# show autovacuum;
 autovacuum
------------
 on
(1 row)

test=#
test=# alter table mytest set (autovacuum_enabled=on);
ALTER TABLE
test=# \d+ mytest
                                   Table "public.mytest"
 Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | D
escription
--------+---------+-----------+----------+---------+----------+--------------+--
-----------
 a      | integer |           | not null |         | plain    |              |
 b      | text    |           |          |         | extended |              |
Indexes:
    "mytest_pkey" PRIMARY KEY, btree (a)
Options: autovacuum_enabled=on

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2194274.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

服贸会上的科技闪耀之星:璞华易研PLM系统引领产品研发潮流

2024年中国国际服务贸易交易会&#xff08;以下简称为“服贸会”&#xff09;于9月在北京盛大开幕&#xff0c;再次汇聚全球目光&#xff0c;共襄智慧服务的盛宴。本届服贸会秉承“全球服务、互惠共享”的核心理念&#xff0c;聚焦“共享智慧服务&#xff0c;共促开放发展”&am…

计算机毕业设计 基于Python的社交音乐分享平台的设计与实现 Python+Django+Vue 前后端分离 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

【路径规划】A*(A星)搜索路径规划教程

摘要 A算法是一种用于图形搜索的启发式搜索算法&#xff0c;广泛应用于路径规划、游戏AI和机器人导航等领域。本教程将深入介绍A算法的理论基础&#xff0c;展示其在路径规划中的应用&#xff0c;并通过Matlab代码实现A*算法的实际运行。同时&#xff0c;我们将结合实验结果进…

qsort函数及其使用的方法分解讲解

qsort函数 默认排序升序 void qsort(void* base,//指向待排序数组的第一个元素的地址 size_t num,//base指向数组中元素的个数 size_t size,//base指向的数组中一个元素的大小&#xff0c;单位是字节 int (*compar)(const void*,const void*…

YOLO11改进|卷积篇|引入线性可变形卷积LDConv

目录 一、【LDConv】卷积1.1【LDConv】卷积介绍1.2【LDConv】核心代码 二、添加【LDConv】卷积2.1STEP12.2STEP22.3STEP32.4STEP4 三、yaml文件与运行3.1yaml文件3.2运行成功截图 一、【LDConv】卷积 1.1【LDConv】卷积介绍 下图是【LDCNV】的结构图&#xff0c;让我们简单分析…

Mysql高级篇(下)——主从复制

主从复制 一、概述二、作用&#x1f388; 场景示例&#x1f388; 综合示例 三、原理&#x1f388; 主从复制基本原则&#x1f388; 主从复制存在的问题 四、一主一从架构搭建&#x1f331;准备工作&#x1f31e;步骤1. 配置主库&#xff08;Master&#xff09;2. 配置从库&…

如何搭建基于大模型的智能知识库

自从2022年底ChatGPT横空出世引爆了大模型技术浪潮&#xff0c;时至今日已经一年有余&#xff0c;如何从技术侧向商业侧落地转化是一直以来业内普遍关注的问题。 从目前企业端观察到的情况来看&#xff0c;基于大模型的知识库是一个比较有潜力和价值的应用场景&#xff0c;能够…

落伍警告:不了解AI Agent,你可能会被编程界淘汰

AI Agent火爆到什么程度&#xff1f; OpenAI创始人奥特曼预测&#xff0c;未来各行各业&#xff0c;每一个人都可以拥有一个AI Agent&#xff1b;比尔盖茨在2023年层预言&#xff1a;AI Agent将彻底改变人机交互方式&#xff0c;并颠覆整个软件行业&#xff1b;吴恩达教授在AI…

UE5 武器IK瞄准系统

创建空项目 创建基础蓝图类My_GameMode,My_HUD,My_PlayChar,My_PlayController 项目设置地图模式 近裁平面 0.1 My_PlayChar蓝图中添加摄像机,角色骨骼网格体,武器骨骼网格体 编辑角色骨骼,预览控制器使用特定动画,动画选择ANM_ark-47-Idle hand_r 添加插槽WeaponMes…

Stable Diffusion绘画 | 如何做到不同动作表情,人物角色保持一致性(下篇)

在 人物角色保持一致性&#xff08;上篇&#xff09;中&#xff0c;我们已经得到了自己创造的角色的各个角度头像图片&#xff1a; 从中选择一个符合自己需求的角度&#xff0c;截图保存&#xff0c;例如下图&#xff1a; 更换人物表情 进入到「图生图」页面&#xff0c;把上一…

短视频时代,网站建设存在的意义还有多大?

在短视频时代&#xff0c;网站建设的存在意义依然具有多方面的价值和作用。尽管短视频作为一种新兴的传播方式迅速发展并受到广泛欢迎&#xff0c;但网站作为互联网的基础设施之一&#xff0c;仍然在许多领域发挥着不可替代的作用。以下是具体分析&#xff1a; 信息深度与完整性…

医院管理新思维:Spring Boot技术应用

5系统详细实现 5.1 医生模块的实现 5.1.1 病床信息管理 医院管理系统的医生可以管理病床信息&#xff0c;可以对病床信息添加修改删除操作。具体界面的展示如图5.1所示。 图5.1 病床信息管理界面 5.1.2 药房信息管理 医生可以对药房信息进行添加&#xff0c;修改&#xff0c;…

开源项目带来的思考

分享一位在Hacker News上的一个帖子&#xff0c;该开源作者在Github上年收入达到10万美元&#xff0c;你不得不承认&#xff0c;个人开源项目的影响力还是很大的。 这条帖子讲述了一位Laravel的开发者&#xff0c;是如何在Github上做到年收入10万美元。该帖子一发布&#xff0c…

rust使用tokio

Rust 是一种系统编程语言,它强调安全、并发和高性能。tokio 是一个基于 Rust 的异步运行时库,专门用于构建异步应用程序。使用 tokio 可以轻松地管理异步任务,并实现高效的并发。 添加依赖: cargo add tokio -F full 示例: 示例1: fn main() {let rt = tokio::runti…

RabbitMQ事务模块

目录 消息分发​​​​​​​ 负载均衡 幂等性保障 顺序性保障 顺序性保障方案 二号策略:分区消费 三号策略:消息确认机制 四号策略: 消息积压 RabbitMQ集群 选举过程 RabbitMQ是基于AMQP协议实现的,该协议实现了事务机制&#xff0c;要么全部成功&#xff0c;要么全…

软件设计师:03操作系统原理

文章目录 一、操作系统地位图二、前趋图&#xff08;PV操作&#xff09;三、移臂调度算法&#xff08;1&#xff09;最短移臂调度算法&#xff08;2&#xff09;先来先服务&#xff08;3&#xff09;最短寻道时间优先&#xff08;4&#xff09;扫描算法或电梯调度算法&#xff…

大模型~合集8

我自己的原文哦~ https://blog.51cto.com/whaosoft/11566472 # From r to Q∗ 这就是OpenAI神秘的Q*&#xff1f;斯坦福&#xff1a;语言模型就是Q函数 近日&#xff0c;斯坦福大学一个团队的一项新研究似乎为这一研究方向的潜力提供了佐证&#xff0c;其声称现在已经取得非…

【Linux-基础IO】磁盘的存储管理详解

磁盘的存储管理 由于一个磁盘中包含了大量的扇区&#xff0c;为了方便管理&#xff0c;我们对磁盘进行了分区&#xff0c;其中每个分区又进一步划分为多个块组&#xff08;Block Group&#xff09;&#xff0c;每个块组中包含该块组的数据存储情况以及具体的数据 假设有一个8…

分层解耦-01.三层架构

一.对案例的思考 所有的代码都在这一个controller文件中&#xff0c;虽然该代码不复杂。但是如果针对大型项目&#xff0c;代码会很复杂。而且不利于项目的维护&#xff0c;复用性差。因此要修改该代码&#xff0c;使其满足维护方便&#xff0c;复用性好的特点。因此要用到一个…

VMware ESXi更改https的TLS协议版本

简要概述 TLS 1.0 和 1.1 是已弃用的协议&#xff0c;具有广为人知的缺点和漏洞。应在所有接口上启用 TLS 1.2&#xff0c;并在支持的情况下禁用 SSLv3、TL 1.1 和 1.0。强制要求 TLS 1.2 可能会破坏 vSphere 的第三方集成和加载项。在实施 TLS 1.2 后仔细测试这些集成&#x…