Mogdb 5.0新特性:SQL PATCH绑定执行计划

前言

熟悉Oracle的dba都知道,生产系统出现性能问题时,往往是SQL走错了执行计划,紧急情况下,无法及时修改应用代码,dba可以采用多种方式针对于某类SQL进行执行计划绑定,比如SQL Profile、SPM、SQL Plan Base、等等。 在MogDB 5.0版本引入了SQL PATCH的特性,SQL PATCH能够在避免直接修改用户业务语句的前提下对查询执行的方式做一定调整。在发现查询语句的执行计划、执行方式未达预期的场景下,可以通过创建查询补丁的方式,使用Hint对查询计划进行调优或对特定的语句进行报错短路处理。

SQL PATCH主要设计给DBA、运维人员及其他需要对SQL进行调优的角色使用,用户通过其他运维视图或定位手段识别到业务语句存在计划不优导致的性能问题时,可以通过创建SQL PATCH对业务语句进行基于Hint的调优。目前支持行数、扫描方式、连接方式、连接顺序、PBE custom/generic计划选择、语句级参数设置、参数化路径的Hint。

特性约束

  • 仅支持针对Unique SQL ID打PATCH,如果存在Unique SQL ID冲突,用于Hint调优的SQL PATCH可能影响性能,但不影响语义正确性。
  • 仅支持不改变SQL语义的Hint作为PATCH,不支持SQL改写。
  • 不支持逻辑备份、恢复。
  • 不支持创建时校验PATCH合法性,如果PATCH的Hint存在语法或语义错误,不影响查询正确执行。
  • 仅初始用户、运维管理员、监控管理员、系统管理员用户有权限执行。库之间不共享,创建SQL PATCH时需要连接目标库。
  • 配置集中式备机可读时,需要指定主机执行SQL PATCH创建/修改/删除函数调用,备机执行报错。
  • SQL PATCH同步给备机存在一定延迟,待备机回放相关日志后PATCH生效。
  • 不支持对存储过程中的SQL语句生效,当前机制不会对存储过程内语句生成Unique SQL ID。
  • 用于规避的Abort Patch不建议在数据库中长期使用,只应该作为临时规避方法。遇到内核问题所导致的特定语句触发数据库服务不可用问题,需要尽快修改业务或升级内核版本解决问题。并且升级后由于Unique SQL ID生成方法可能变化,可能导致规避方法失效。
  • 当前,除DML语句之外,其他SQL语句(如CREATE TABLE等)的Unique SQL ID是对语句文本直接哈希生成的,所以对于此类语句,SQL PATCH对大小写、空格、换行等敏感,即不同的文本的语句,即使语义相对,仍然需要对应不同的SQL PATCH。对于DML,则同一个SQL PATCH可以对不同入参的语句生效,并且忽略大小写和空格。

依赖关系

需要开启enable_resource_track=on、enable_stmt_track =on并且设置instr_unique_sql_count大于0。对于不同的语句,如果生成的Unique SQL ID冲突,会导致SQL PATCH错误的命中预期外的其他语句。其中用于调优的Hint PATCH副作用相对较小,Abort Patch需要谨慎使用。

实际案例

1、创建表

创建表t1和t2;

create table t1(name char(10),id int);
create table t2(name char(10),id int);

2、构造数据

INSERT INTO t1 (nameid)
SELECT 'data_'|| generate_series(11000), generate_series(11000);

INSERT INTO t2 (nameid)
SELECT 'data_'|| generate_series(11000), generate_series(11000);

CREATE INDEX idx_t1 ON t1 (id);
CREATE INDEX idx_t2 ON t2 (id);

3、获取unique_query_id

执行SQL并获取unique_query_id、执行计划

set track_stmt_stat_level = 'L1,L1'

再次检查参数
select name,setting ,unit
  from pg_catalog.pg_settings 
 where name in (
               'enable_resource_track',
               'enable_stmt_track',
               'log_min_duration_statement',
               'instr_unique_sql_count',
               'track_stmt_stat_level',
               'track_stmt_retention_time'
        );
            name            |   setting   | unit 
----------------------------+-------------+------
 enable_resource_track      | on          | 
 enable_stmt_track          | on          | 
 instr_unique_sql_count     | 100         | 
 log_min_duration_statement | 1800000     | ms
 track_stmt_retention_time  | 3600,604800 | 
 track_stmt_stat_level      | L1,L1       | 
(6 rows)

--track_stmt_stat_level解释:
该参数分为两部分:
--形式为'full sql stat level, slow sql stat level'。
--级别(L2 > L1 > L0),L1在L0的基础上记录了执行计划,L2在L1的基础上记录了锁的详细信息

select * from t1 a, t2 b where a.id = b.id;
   name    |  id  |    name    |  id  
------------+------+------------+------
 data_1     |    1 | data_1     |    1
 data_2     |    2 | data_2     |    2
 data_3     |    3 | data_3     |    3
 data_4     |    4 | data_4     |    4
 data_5     |    5 | data_5     |    5
 data_6     |    6 | data_6     |    6
 data_7     |    7 | data_7     |    7
 。。。。
(1000 row)

4、获取查看执行计划

走的全表扫描hash jion执行计划

explain select * from t1 a, t2 b where a.id = b.id;
                                QUERY PLAN  
--------------------------------------------------------------------------
 Aggregate  (cost=60.75..60.76 rows=1 width=8)
   ->  Hash Join  (cost=28.50..58.25 rows=1000 width=0)
         Hash Cond: (a.id = b.id)
         ->  Seq Scan on t1 a  (cost=0.00..16.00 rows=1000 width=4)
         ->  Hash  (cost=16.00..16.00 rows=1000 width=4)
               ->  Seq Scan on t2 b  (cost=0.00..16.00 rows=1000 width=4)

5、查询unique_query_id

select unique_query_id,query,start_time from dbe_perf.statement_history  where query like '%from t1 a%';
 unique_query_id |                       query                        |          start_time           
-----------------+----------------------------------------------------+-------------------------------
      3366573496 | select * from t1 a, t2 b where a.id = b.id;        | 2024-01-19 10:08:56.994391+08

也可以通过statement_history查询执行计划
select start_time,query_plan  from dbe_perf.statement_history  where unique_query_id = 3366573496;
          start_time           |                                query_plan                                
-------------------------------+--------------------------------------------------------------------------
 2024-01-19 10:08:56.994391+08 | Datanode Name: dn_6001_6002                                        +
                               | Hash Join  (cost=28.50..58.25 rows=1000 width=30)                  +
                               |   Hash Cond: (a.id = b.id)                                         +
                               |   ->  Seq Scan on t1 a  (cost=0.00..16.00 rows=1000 width=15)      +
                               |   ->  Hash  (cost=16.00..16.00 rows=1000 width=15)                 +
                               |         ->  Seq Scan on t2 b  (cost=0.00..16.00 rows=1000 width=15)+
                               |                                                                    +

6、SQL PATCH绑定执行计划

call dbe_sql_util.create_hint_sql_patch('enmo patch',3366573496,'indexscan(a)');
 create_hint_sql_patch 
-----------------------
 t
(1 row)

--参数说明:
enmo patch --SQL PATCH name
3366573496 --unique_query_id
indexscan(a) --Hint文本

7、验证SQL PATCH

执行并检查新的执行计划是否生效
select * from t1 a, t2 b where a.id = b.id;
   name    |  id  |    name    |  id  
------------+------+------------+------
 data_1     |    1 | data_1     |    1
 data_2     |    2 | data_2     |    2
 data_3     |    3 | data_3     |    3
 data_4     |    4 | data_4     |    4
 data_5     |    5 | data_5     |    5
 data_6     |    6 | data_6     |    6
 data_7     |    7 | data_7     |    7
 。。。。

explain select * from t1 a, t2 b where a.id = b.id;
NOTICE:  Plan influenced by SQL hint patch
                                  QUERY PLAN                                  
------------------------------------------------------------------------------
 Hash Join  (cost=28.50..86.50 rows=1000 width=30)
   Hash Cond: (a.id = b.id)
   ->  Index Scan using idx_t1 on t1 a  (cost=0.00..44.25 rows=1000 width=15) 
      --这里走了索引,表示SQL patch生效
   ->  Hash  (cost=16.00..16.00 rows=1000 width=15)
         ->  Seq Scan on t2 b  (cost=0.00..16.00 rows=1000 width=15)
(5 rows)

查看statement_history的执行计划
select query_plan,to_char(start_time,'yyyymmdd-hh24:mi:ss') starttime
from dbe_perf.statement_history 
where unique_query_id = 3366573496
order by start_time;
 Datanode Name: dn_6001_6002                                                 +| 20240119-10:09:54
 Hash Join  (cost=28.50..86.50 rows=1000 width=30)                           +| 
   Hash Cond: (a.id = b.id)                                                  +| 
   ->  Index Scan using idx_t1 on t1 a  (cost=0.00..44.25 rows=1000 width=15)+| 
   ->  Hash  (cost=16.00..16.00 rows=1000 width=15)                          +| 
         ->  Seq Scan on t2 b  (cost=0.00..16.00 rows=1000 width=15)         +| 
                                                                             +| 
                                                                              | 

参看数据库内已定义的SQL Patch
 select patch_name,unique_sql_id,enable,hint_string from gs_sql_patch;
 patch_name | unique_sql_id | enable | hint_string  
------------+---------------+--------+--------------
 enmo patch |    3366573496 | t      | indexscan(a)

show_sql_patch查看SQL PATCH内容
MogDB=# select  DBE_SQL_UTIL.show_sql_patch('enmo patch');
           show_sql_patch            
-------------------------------------
 (3366573496,t,f,"indexscan(a)")
(1 row)

8、Abort Patch

使用Abort PATCH对特定语句进行提前报错规避。

MogDB=# select * from dbe_sql_util.drop_sql_patch('enmo patch'); -- 删去enmo patch
 drop_sql_patch
----------------
 t
(1 row)
MogDB=# select * from dbe_sql_util.create_abort_sql_patch('patch2', 3366573496); -- 对该语句的Unique SQL ID创建Abort Patch
 create_abort_sql_patch
------------------------
 t
(1 row)

MogDB=# select * from t1 a, t2 b where a.id = b.id; -- 再次执行语句会提前报错
ERROR:  Statement 3366573496 canceled by abort patch patch2

9、关闭特定 SQL Patch

disable enmo patch
call dbe_sql_util.disable_sql_patch('enmo patch');

执行SQL并检查执行计划是否恢复原始状态
MogDB=# select  query_plan,to_char(start_time,'yyyymmdd-hh24:mi:ss') starttime
MogDB-#  from dbe_perf.statement_history 
MogDB-#  where  unique_query_id = 3366573496
MogDB-#  order by start_time;
                                query_plan                                |     starttime     
--------------------------------------------------------------------------+-------------------
 Datanode Name: dn_6001_6002                                             +| 20240119-13:24:52
 Nested Loop  (cost=0.00..340.00 rows=1000 width=30)                     +| 
   ->  Seq Scan on t1 a  (cost=0.00..16.00 rows=1000 width=15)           +| 
   ->  Index Scan using idx_t2 on t2 b  (cost=0.00..0.31 rows=1 width=15)+| 
         Index Cond: (id = a.id)                                         +| 
                                                                         +| 
                                                                          | 
 Datanode Name: dn_6001_6002                                             +| 20240119-13:31:49
 Hash Join  (cost=28.50..58.25 rows=1000 width=30)                       +| 
   Hash Cond: (a.id = b.id)                                              +| 
   ->  Seq Scan on t1 a  (cost=0.00..16.00 rows=1000 width=15)           +| 
   ->  Hash  (cost=16.00..16.00 rows=1000 width=15)                      +| 
         ->  Seq Scan on t2 b  (cost=0.00..16.00 rows=1000 width=15)     +| 
                                                                         +| 
 
最新的执行计划已经还原成hash jion 

技能延伸:Mogdb支持的hint

1、兼容Oracle的hint

Scan方式的Hint
  • tablescan 全表扫描 tablescan(表名/别名) no tablescan(表名/别名)
explain select /*+ tablescan(e) */ * from emp e where empno=3000;
  • indexscan 索引扫描 indexscan(表名/别名 [索引名]),如果where条件列没有合适的索引,会提示unused hint
explain select /*+ indexscan(t) */ * from test t where object_id >100;
  • indexonlyscan 仅索引扫描 indexonlyscan(表名/别名 索引名),如果where条件列没有合适的索引,会提示unused hint
explain select /*+ indexonlyscan(t) */ object_id from test t where object_id >100;
Join顺序的Hint

join table list中指定的表需要满足以下要求,否则会报语义错误。

  • list中的表必须在当前层或提升的子查询中存在。
  • list中的表在当前层或提升的子查询中必须是唯一的。如果不唯一,需要使用不同的别名进行区分。
  • 同一个表只能在list里出现一次。
  • 如果表存在别名,则list中的表需要使用别名。 leading 指定哪两个表先关联 leading(a b) 必须指定2个或2个表以上,如果要指定两个表的先后顺序,leading(( ))
explain select /*+ leading((e d) hashjoin(e d) ) */ * from emp e ,dept d where e.deptno =d.deptno;
explain select /*+ leading((e d) nestloop(e d) ) */ * from emp e ,dept d where e.deptno =d.deptno;
explain select /*+ leading((e dmergejoin(e d) )) */ * from emp e ,dept d where e.deptno =d.deptno;
子链接块名的hint

控制半连接执行计划,mogdb中给子查询取别名 blockname ,然后把它当成表名字与外面的表关联 示例

explain select /*+nestloop(store_sales tt) */ * from store_sales where ss_item_sk in (select /*+blockname(tt)*/ i_item_sk from item group by 1);
指定row的hint

rows 指定表或结果集返回rows 用法:

/*+ rows(e #100) */     指定e返回100行
/*+ rows(e +100) */     指定e在原来的预估上+100行
/*+ rows(e -100) */      指定e在原来的预估上-100行
/*+ rows(e *100) */      指定e在原来的预估上*100行
/*+ rows(e d #100) */   指定e和d关联之后返回100行

explain select /*+ rows(store_sales store_returns *50) */ i_product_name product_name

该hint表示: store_sales,store_returns关联的结果集估算行数在原估算行数基础上乘以50。生成计划如下所示: image.png

指定参数的Hint

目前支持使用Hint设置生效的参数有

  • 布尔类: enable_bitmapscan, enable_hashagg,enable_hashjoin, enable_indexscan,enable_indexonlyscan, enable_material,enable_mergejoin, enable_nestloop,enable_index_nestloop, enable_seqscan,enable_sort, enable_tidscan,partition_iterator_elimination,partition_page_estimation,enable_functional_dependency,var_eq_const_selectivity,enable_inner_unique_opt

  • 整形类: query_dop

  • 浮点类: cost_weight_index, default_limit_rows, seq_page_cost, random_page_cost, cpu_tuple_cost, cpu_index_tuple_cost, cpu_operator_cost, effective_cache_size

  • 枚举类型: try_vector_engine_strategy

用法: set(param value) 设置优化器参数

/*+ set(enable_hashjoin false) */  ---关闭hashjoin
/*+ set(query_dop 2) */                 ---设置并行2
/*+ set(work_mem 131072) */      ---work_mem没在白名单里面
子查询不展开的Hint

用法: /+ no_expand/

正常的查询执行

explain select * from t1 where t1.a in (select t2.a from t2);

加入no_expand

explain select * from t1 where t1.a in (select /*+ no_expand*/ t2.a from t2);
image.png
image.png
同层参数化路径的Hint

通过predpush_same_level Hint来指定同层表或物化视图之间参数化路径生成。 用法: predpush_same_level(src, dest) predpush_same_level(src1 src2 ..., dest)

  • 本参数仅在rewrite_rule中的predpushforce选项打开时生效。
MogDB=# set rewrite_rule = 'predpushforce';
SET
MogDB=# explain select * from t1, t2 where t1.a = t2.a;
                            QUERY PLAN
------------------------------------------------------------------
 Hash Join  (cost=27.50..56.25 rows=1000 width=16)
   Hash Cond: (t1.a = t2.a)  --可以看到t1.a = t2.a条件过滤在Join上面
   ->  Seq Scan on t1  (cost=0.00..15.00 rows=1000 width=8)
   ->  Hash  (cost=15.00..15.00 rows=1000 width=8)
         ->  Seq Scan on t2  (cost=0.00..15.00 rows=1000 width=8)
(5 rows)

可以看到t1.a = t2.a条件过滤在Join上面,此时可以通过predpush_same_level(t1, t2)将条件下推至t2的扫描算子上

MogDB=# explain select /*+predpush_same_level(t1, t2)*/ * from t1, t2 where t1.a = t2.a;
                             QUERY PLAN
---------------------------------------------------------------------
 Nested Loop  (cost=0.00..335.00 rows=1000 width=16)
   ->  Seq Scan on t1  (cost=0.00..15.00 rows=1000 width=8)
   ->  Index Scan using idx2 on t2  (cost=0.00..0.31 rows=1 width=8)
         Index Cond: (a = t1.a)
(4 rows)

2、兼容Mysql的hint

INDEX HINTS

用法: tbl_name [ partition_clause ] [ [ AS ] alias ] [ index_hint_list ] index_hint_list: index_hint [ index_hint ] index_hint: USE INDEX KEY ( [ index_list ] ) | FORCE INDEX KEY ( index_list ) index_list: index_name [ , index_name ] ...

MogDB=# explain (costs off,verbose true  )select * from db_1097149_tb force key (index_1097149_4) where col2= 3 and col4 = 'a';
                        QUERY PLAN                        
----------------------------------------------------------
 Index Scan using index_1097149_4 on public.db_1097149_tb
   Output: col1, col2, col3, col4
   Index Cond: ((db_1097149_tb.col4)::text = 'a'::text)
   Filter: (db_1097149_tb.col2 = 3)
(4 rows)

3、将部分Error降级为Warning的Hint

指定执行INSERT、UPDATE语句时可将部分Error降级为Warning,且不影响语句执行完成的hint。

db_ignore=# set sql_ignore_strategy = 'ignore_null';
SET
db_ignore=# insert /*+ ignore_error */ into t_not_null values(null), (1);
WARNING:  null value in column "num" violates not-null constraint
DETAIL:  Failing row contains (null).
INSERT 0 1
db_ignore=# select * from t_not_null ;
 num 
-----
   1
(1 row)

4、Hint的错误增强

Mogdb常用HINT对比Oracle的hint做了增强,更加人性化。当出现语法错误、语义错误、hint重复或冲突、子链接提升后hint失效、列类型不支持重分布、hint未被使用会根据语句类型以不同方式提示用户

5、不使用全局计划缓存的Hint

全局计划缓存打开时,可以通过no_gpc Hint来强制单个查询语句不在全局共享计划缓存,只保留会话生命周期的计划缓存。 用法: /+ no_gpc/

  • 本参数仅在enable_global_plancache=on时对PBE执行的语句生效。 image.png

6、Custom Plan和Generic Plan选择的Hint

用法: /*+ use_cplan / /+ use_gplan */

MogDB=# create table t (a int, b int, c int);
CREATE TABLE
MogDB=# prepare p as select /*+ use_cplan */ * from t where a = $1;
PREPARE
MogDB=# explain execute p(1);
                     QUERY PLAN                     
----------------------------------------------------
 Seq Scan on t  (cost=0.00..34.31 rows=10 width=12)
   Filter: (a = 1)
(2 rows)

MogDB=# show enable_pbe_optimization;
 enable_pbe_optimization 
-------------------------
 on
(1 row)

MogDB=# deallocate p;
DEALLOCATE
MogDB=# prepare p as select /*+ use_gplan */ * from t where a = $1;
PREPARE
MogDB=# explain execute p(1);
                     QUERY PLAN                     
----------------------------------------------------
 Seq Scan on t  (cost=0.00..34.31 rows=10 width=12)
   Filter: (a = $1)
(2 rows)

详细内容请参考如下链接: OpenGauss/MogDB基于绑定变量的SQL优化

  • MogDB官方文档参考:
    sql-patch#特性描述 track_stmt_stat_level Mogdb Plan Hint进行调优

本文由 mdnice 多平台发布

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

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

相关文章

Linux——网络管理nmcli

nmcli 不能独立使用,需要对应的服务启动 1. NetworkManager.service 2. 网络配置和服务不相关 3. 通过 nmcl i 建立网络配置和网卡之前的映射关系 网卡 简称:nmcli d DEVICE :物理设备 TYPE: 物理设备类型 ethernet 以太网…

C++设计模式:适配器模式(十四)

1、定义与动机 定义:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作。 动机: 在软件系统中,由于应用环境的变化,常常需要将“一些现存的对象”放在新的环境…

强固型工业电脑在码头智能闸口、OCR(箱号识别)、集装箱卡车车载电脑行业应用

集装箱卡车车载电脑应用 背景介绍 针对码头集装箱卡车的调度运用, 结合码头TOS系统设计出了各种平台的车载电脑(VT系列)和车载LED显示屏(VLD系列),同时提供各种安装支架,把车载电脑固定到狭小的驾驶室中;同时提供了各种天线选择(…

【JVM常见问题总结】

文章目录 jvm介绍jvm内存模型jvm内存分配参数jvm堆中存储对象:对象在堆中创建分配内存过程 jvm 堆垃圾收集器垃圾回收算法标记阶段引用计数算法可达性分析算法 清除阶段标记清除算法复制算法标记压缩算法 实际jvm参数实战jvm调优jvm常用命令常用工具 jvm介绍 Java虚…

高速公路交通运输大数据平台解决方案

前言 交通运输行业面临着多重挑战。其管控困难,涉及广泛地理范围,导致监控成本高且难以及时响应;同时,行业内数据量大,地理信息数据繁多,缺乏高效的可视化工具来揭示数据规律并优化业务;货运和…

回溯算法-组合问题

回溯算法-组合问题 77. 组合 问题描述 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1: 输入:n 4, k 2 输出: [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4], ]示例 2&a…

05集合-CollectionListSet

Collection体系的特点、使用场景总结 如果希望元素可以重复,又有索引,索引查询要快? 用ArrayList集合, 基于数组的。(用的最多) 如果希望元素可以重复,又有索引,增删首尾操作快? 用LinkedList集合, 基于链表的。 如果希望增…

基于SpringBoot + Vue实现的奖学金管理系统设计与实现+毕业论文+答辩PPT

介绍 角色:管理员、学院负责人、学校负责人、学生 管理员:管理员登录进入高校奖助学金系统的实现可以查看系统首页、个人中心、学生管理、学院负责人管理、学校负责人管理、奖学金类型管理、奖学金申请管理、申请提交管理、系统管理等信息 学院负责人:学院负责人登录系统后&am…

python3--lxml pytoml.core.TomlError expected_equals报错解决

文章目录 一、问题二. 解决方法:三. 参考:四. 总结 一、问题 在ubuntu的armbian上的python3中安装lxml时报错了 安装命令是 pip3 install lxml报错简略信息如下图 File "/usr/share/python-wheels/pytoml-0.1.2-py2.py3-none-any.whl/pytoml/par…

2.1K Star微软开源的高质量 iot库

功能描述 该项目是一个开源的 .NET Core 实现,旨在帮助开发者构建适用于物联网(IoT)设备和场景的应用程序。它提供了与传感器、显示器和输入设备等相互作用所需的 GPIO 引脚、串口等硬件的接口。该仓库包含 System.Device.Gpio 库以及针对各种板卡(如 Ra…

redis底层数据结构之ziplist

目录 一、概述二、ziplist结构三、Entry结构四、为什么ZipList特别省内存五、ziplist的缺点 上一篇 redis底层数据结构之SDS 下一篇 明天更新 一、概述 一种连续内存空间存储的顺序数据结构,每个元素可以是字符串或整数。优点:节省内存空间。适用于存储小规模的列表…

STM32 | USART实战案例

STM32 | 通用同步/异步串行接收/发送器USART带蓝牙(第六天)随着扩展的内容越来越多,很多小伙伴已经忘记了之前的学习内容,然后后面这些都很难理解。STM32合集已在专栏创建,方面大家学习。1、通过电脑串口助手发送数据,控制开发板LED灯 从题目中可以挖掘出,本次使用led、延…

【Linux文件系统开发】认知篇

【Linux文件系统开发】认知篇 文章目录 【Linux文件系统开发】认知篇一、文件系统的概念二、文件系统的种类(文件管理系统的方法)三、分区四、文件系统目录结构五、虚拟文件系统(Virtual File System)1.概念2.原因3.作用4.总结 一…

减肥变成一种趋势!足球直播是一种刺激——早读(逆天打工人爬取热门微信文章解读)

看直播是打发时间的好方式 引言Python 代码第一篇 洞见 跌入粪坑的钟美美,才是真正的“人间清醒”第二篇 人民日报 来了!新闻早班车要闻社会政策 结尾 变化是生活的法则 而直播的比赛则是这一法则的缩影 每一秒都可能带来转折和惊喜 充满了未知和奇迹 引…

磁盘损坏无法读取:原因、恢复方案与防范之道

在数字化信息爆炸的时代,磁盘作为数据存储的重要载体,承载着无数重要的文件和资料。然而,当磁盘突然损坏,无法读取数据时,我们往往会陷入困境,焦虑不已。面对这种情况,我们该如何应对&#xff1…

Yolo-world使用

1、安装 python pip install ultralytics 前往官网下载模型:https://docs.ultralytics.com/models/yolo-world/#key-features 我这里使用yolov8s-world.pt举例 最简单的使用示例 if __name__ __main__:model YOLO(model/yolov8s-world.pt)results model.pre…

中仕公考:考公还是考编?区别是什么?

公务员和事业编应该如何选择?区别在哪里?中仕为大家总结以下几点,看完就明白了! 事业编制:主要指从事事业单位工作人员所获得的稳定的事业单位编制。 公务员:是指在各级政府机关中,行使国家行政职权,执行国家公务的…

2024HW ---->内网横向移动

在蓝队的面试过程中,如果你会内网渗透的话,那是肯定的一个加分选项!!! 那么从今天开始,我们就来讲一下内网的横向移动!!! 目录 1.域内任意用户枚举 2.Password-Sprayi…

ffmpeg入门

ffmpeg入——安装 Fmpeg地址 FFmpeg源码地址:GitHub - FFmpeg/FFmpeg: Mirror of https://git.ffmpeg.org/ffmpeg.git FFmpeg可执行文件地址:Download FFmpeg Windows平台 ​ ​ Windows平台下载解压后如图所示(文件名称以-share结尾的…

深入剖析Spring框架:循环依赖的解决机制

你好,我是柳岸花开。 什么是循环依赖? 很简单,就是A对象依赖了B对象,B对象依赖了A对象。 在Spring中,一个对象并不是简单new出来了,而是会经过一系列的Bean的生命周期,就是因为Bean的生命周期所…