Endless lseek导致的SQL异常
最近碰到同事咨询的一个问题,在执行一个函数时,发现会一直卡在那里。
strace抓了下发现会话一直在执行lseek,大致情况如下:
16:13:55.451832 lseek(33, 0, SEEK_END) = 1368064 <0.000037> 16:13:55.477216 lseek(33, 0, SEEK_END) = 1368064 <0.000026> 16:13:55.502579 lseek(33, 0, SEEK_END) = 1368064 <0.000026> 16:13:55.528162 lseek(33, 0, SEEK_END) = 1368064 <0.000024> 16:13:55.553714 lseek(33, 0, SEEK_END) = 1368064 <0.000025> 16:13:55.579242 lseek(33, 0, SEEK_END) = 1368064 <0.000022> ......% time seconds usecs/call calls errors syscall ------ ----------- ----------- --------- --------- ---------------- 0.00 0.000000 0 124 lseek ------ ----------- ----------- --------- --------- ---------------- 100.00 0.000000 124 total
而当手动去取消掉会话时也能发现,是卡在了其中一个insert语句:
[postgres@xxx/(rasesql)himsdpsods][02-22.16:13:24]M=# select pgawr_snap('cron based snapshot',59451);
^CCancel request sent
ERROR: 57014: canceling statement due to user request
CONTEXT: SQL statement "INSERT INTO pgawr_indexes
( snapid, idx_scan, idx_tup_read, idx_tup_fetch, idx_blks_read,
idx_blks_hit, index_name_id, table_name_id)
SELECT
spid as snapid,
i.idx_scan as idx_scan,
i.idx_tup_read as idx_tup_read,
i.idx_tup_fetch as idx_tup_fetch,
ii.idx_blks_read as idx_blks_read,
ii.idx_blks_hit as idx_blks_hit,
n1.nameid,
n2.nameid
FROM
pg_stat_all_indexes i
join pg_statio_all_indexes ii on i.indexrelid = ii.indexrelid
join pgawr_names n1 on i.schemaname ||'.'|| i.indexrelname=n1.name
join pgawr_names n2 on i.schemaname ||'.'|| i.relname=n2.name"
PL/pgSQL function pgawr_snap(character varying,bigint) line 104 at SQL statement
LOCATION: ProcessInterrupts, postgres.c:3203
Time: 203994.651 ms (03:23.995)
当然分析这种函数执行慢的,最常用的还是auto_explain,可以在会话中设置来打印函数中具体执行的情况:
load 'auto_explain';set client_min_messages='log'; set auto_explain.log_min_duration = 0; set auto_explain.log_analyze = true; set auto_explain.log_verbose = true; set auto_explain.log_buffers = true; set auto_explain.log_nested_statements = true;
根据上面得到的信息发现文件句柄33对应的恰好也是该SQL中的一张表,而lseek(33, 0, SEEK_END) = 1368064的返回值也的确是和该数据文件的大小一致,说明的确是扫描完该表了。
那就有点奇怪了,这个SQL也很简单,而且单独拿出来执行也都没问题,为什么会一直卡在lseek这个数据文件这里呢?
上网搜了下,发现有个类似的bug:BUG #15455: Endless lseek,其中的情况和我这个有些类似:

但是往后看了malilist里面的讨论也是不了了之,最终也没有个结论。。。
哎,没有办法,只能自己接着分析了。
为了方便查看,我这里把SQL简写了,insert也换成select。
[postgres@xxx/(rasesql)himsdpsods][02-22.16:40:10]M=# EXPLAIN ANALYZE SELECT
-> i.idx_scan as idx_scan,
-> i.idx_tup_read as idx_tup_read,
-> i.idx_tup_fetch as idx_tup_fetch,
-> ii.idx_blks_read as idx_blks_read,
-> ii.idx_blks_hit as idx_blks_hit,
-> n1.nameid
-> FROM
-> pg_stat_all_indexes i
-> join pg_statio_all_indexes ii on i.indexrelid = ii.indexrelid
-> join pgawr_names n1 on i.schemaname ||'.'|| i.indexrelname=n1.name;QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------Nested Loop (cost=1805.21..3055.18 rows=3 width=44) (actual time=0.381..0.384 rows=0 loops=1)Join Filter: ((((n.nspname)::text || '.'::text) || (i.relname)::text) = (n1.name)::text)-> Seq Scan on pgawr_names n1 (cost=0.00..228.00 rows=1 width=44) (actual time=0.380..0.381 rows=0 loops=1)-> Nested Loop (cost=1805.21..2815.83 rows=502 width=136) (never executed)-> Hash Join (cost=1804.92..2585.91 rows=502 width=140) (never executed)Hash Cond: (c.relnamespace = n.oid)-> Nested Loop (cost=1801.01..2580.62 rows=502 width=80) (never executed)-> Hash Join (cost=1800.73..2057.32 rows=900 width=12) (never executed)Hash Cond: (x.indexrelid = x_1.indexrelid)-> Hash Join (cost=766.65..1005.74 rows=2267 width=8) (never executed)Hash Cond: (x.indrelid = c.oid)-> Seq Scan on pg_index x (cost=0.00..224.09 rows=5709 width=8) (never executed)-> Hash (cost=715.81..715.81 rows=4067 width=8) (never executed)-> Seq Scan on pg_class c (cost=0.00..715.81 rows=4067 width=8) (never executed)Filter: (relkind = ANY ('{r,t,m}'::"char"[]))-> Hash (cost=1005.74..1005.74 rows=2267 width=4) (never executed)-> Hash Join (cost=766.65..1005.74 rows=2267 width=4) (never executed)Hash Cond: (x_1.indrelid = c_1.oid)-> Seq Scan on pg_index x_1 (cost=0.00..224.09 rows=5709 width=8) (never executed)-> Hash (cost=715.81..715.81 rows=4067 width=8) (never executed)-> Seq Scan on pg_class c_1 (cost=0.00..715.81 rows=4067 width=8) (never executed)Filter: (relkind = ANY ('{r,t,m}'::"char"[]))-> Index Scan using pg_class_oid_index on pg_class i (cost=0.29..0.58 rows=1 width=68) (never executed)Index Cond: (oid = x.indexrelid)-> Hash (cost=2.85..2.85 rows=85 width=68) (never executed)-> Seq Scan on pg_namespace n (cost=0.00..2.85 rows=85 width=68) (never executed)-> Index Only Scan using pg_class_oid_index on pg_class i_1 (cost=0.29..0.46 rows=1 width=4) (never executed)Index Cond: (oid = i.oid)Heap Fetches: 0
可以看到卡住的SQL拿出来单独执行是没有问题的,但是仔细观察可以发现,该执行计划中很多never executed的节点,说明下面的这些部分实际都没有执行,那是因为pgawr_names这张表是空的,因此对于这个嵌套循环来说,被驱动的部分其实就没有必要执行了。
而查看完该函数的内容之后发现,在执行这个SQL之前是有往pgawr_names这张表里面插入数据的。
这样一下子就有思路了:因为在同一个会话中,前一条SQL往pgawr_names表里面插入了大量数据,而表的统计信息在会话提交前是不会更新的。
[postgres@xxx/(rasesql)himsdpsods][02-22.16:54:40]M=# begin; BEGIN Time: 0.128 ms[postgres@xxx/(rasesql)himsdpsods][02-22.16:55:11]M=# select n_live_tup,last_analyze from pg_stat_all_tables where relname = 'pgawr_names'; n_live_tup | last_analyze ------------+------------------------------- 0 | 2023-02-22 15:09:43.348236+08 (1 row)Time: 11.319 ms [postgres@xxx/(rasesql)himsdpsods][02-22.16:55:27]M=# insert into pgawr_names (name) -> select distinct i.schemaname ||'.'|| i.indexrelname -> from pg_stat_all_indexes i -> left join pgawr_names on i.schemaname ||'.'|| i.indexrelname=name -> where -> name is null; INSERT 0 5709 Time: 207.526 ms[postgres@xxx/(rasesql)himsdpsods][02-22.16:55:41]M=# ANALYZE pgawr_names ; ANALYZE Time: 73.666 ms[postgres@xxx/(rasesql)himsdpsods][02-22.16:55:46]M=# select n_live_tup,last_analyze from pg_stat_all_tables where relname = 'pgawr_names'; n_live_tup | last_analyze ------------+------------------------------- 0 | 2023-02-22 15:09:43.348236+08 (1 row)Time: 0.876 ms
既然如此,看来前面看到的会话一直卡在lseek其实是执行计划后面的嵌套循环太多导致的,我们可以把pgawr_names表中手动插入较少的数据来验证下:
[postgres@xxx:6266/(rasesql)himsdpsods][02-22.17:02:00]M=# begin;
BEGIN
Time: 0.141 ms
[postgres@xxx:6266/(rasesql)himsdpsods][02-22.17:02:02]M=# select n_live_tup,last_analyze from pg_stat_all_tables where relname = 'pgawr_names';n_live_tup | last_analyze
------------+-------------------------------0 | 2023-02-22 17:01:53.272047+08
(1 row)Time: 11.615 ms
[postgres@xxx:6266/(rasesql)himsdpsods][02-22.17:02:03]M=# insert into pgawr_names(name) select md5(random()::text) from generate_series(1,200);
INSERT 0 200
Time: 52.083 ms
[postgres@xxx:6266/(rasesql)himsdpsods][02-22.17:02:28]M=# EXPLAIN ANALYZE SELECT
-> i.idx_scan as idx_scan,
-> i.idx_tup_read as idx_tup_read,
-> i.idx_tup_fetch as idx_tup_fetch,
-> ii.idx_blks_read as idx_blks_read,
-> ii.idx_blks_hit as idx_blks_hit,
-> n1.nameid
-> FROM
-> pg_stat_all_indexes i
-> join pg_statio_all_indexes ii on i.indexrelid = ii.indexrelid
-> join pgawr_names n1 on i.schemaname ||'.'|| i.indexrelname=n1.name;QUERY PLAN
--------------------------------------------------------------------------------------------------------------------------------------------------------------Nested Loop (cost=1805.21..3055.18 rows=3 width=44) (actual time=5618.220..5618.229 rows=0 loops=1)Join Filter: ((((n.nspname)::text || '.'::text) || (i.relname)::text) = (n1.name)::text)Rows Removed by Join Filter: 1141800-> Seq Scan on pgawr_names n1 (cost=0.00..228.00 rows=1 width=44) (actual time=0.014..0.417 rows=200 loops=1)-> Nested Loop (cost=1805.21..2815.83 rows=502 width=136) (actual time=0.071..26.143 rows=5709 loops=200)-> Hash Join (cost=1804.92..2585.91 rows=502 width=140) (actual time=0.069..16.342 rows=5709 loops=200)Hash Cond: (c.relnamespace = n.oid)-> Nested Loop (cost=1801.01..2580.62 rows=502 width=80) (actual time=0.068..14.519 rows=5709 loops=200)-> Hash Join (cost=1800.73..2057.32 rows=900 width=12) (actual time=0.066..4.280 rows=5709 loops=200)Hash Cond: (x.indexrelid = x_1.indexrelid)-> Hash Join (cost=766.65..1005.74 rows=2267 width=8) (actual time=0.028..2.815 rows=5709 loops=200)Hash Cond: (x.indrelid = c.oid)-> Seq Scan on pg_index x (cost=0.00..224.09 rows=5709 width=8) (actual time=0.002..0.833 rows=5709 loops=200)-> Hash (cost=715.81..715.81 rows=4067 width=8) (actual time=5.083..5.085 rows=4070 loops=1)Buckets: 4096 Batches: 1 Memory Usage: 191kB-> Seq Scan on pg_class c (cost=0.00..715.81 rows=4067 width=8) (actual time=0.010..4.506 rows=4070 loops=1)Filter: (relkind = ANY ('{r,t,m}'::"char"[]))Rows Removed by Filter: 6170-> Hash (cost=1005.74..1005.74 rows=2267 width=4) (actual time=7.443..7.445 rows=5709 loops=1)Buckets: 8192 (originally 4096) Batches: 1 (originally 1) Memory Usage: 265kB-> Hash Join (cost=766.65..1005.74 rows=2267 width=4) (actual time=4.328..6.637 rows=5709 loops=1)Hash Cond: (x_1.indrelid = c_1.oid)-> Seq Scan on pg_index x_1 (cost=0.00..224.09 rows=5709 width=8) (actual time=0.005..1.006 rows=5709 loops=1)-> Hash (cost=715.81..715.81 rows=4067 width=8) (actual time=4.312..4.313 rows=4070 loops=1)Buckets: 4096 Batches: 1 Memory Usage: 191kB-> Seq Scan on pg_class c_1 (cost=0.00..715.81 rows=4067 width=8) (actual time=0.009..3.746 rows=4070 loops=1)Filter: (relkind = ANY ('{r,t,m}'::"char"[]))Rows Removed by Filter: 6170-> Index Scan using pg_class_oid_index on pg_class i (cost=0.29..0.58 rows=1 width=68) (actual time=0.001..0.001 rows=1 loops=1141800)Index Cond: (oid = x.indexrelid)-> Hash (cost=2.85..2.85 rows=85 width=68) (actual time=0.038..0.039 rows=85 loops=1)Buckets: 1024 Batches: 1 Memory Usage: 17kB-> Seq Scan on pg_namespace n (cost=0.00..2.85 rows=85 width=68) (actual time=0.010..0.023 rows=85 loops=1)-> Index Only Scan using pg_class_oid_index on pg_class i_1 (cost=0.29..0.46 rows=1 width=4) (actual time=0.001..0.001 rows=1 loops=1141800)Index Cond: (oid = i.oid)Heap Fetches: 1141800Planning Time: 3.383 msExecution Time: 5618.715 ms
(38 rows)Time: 5623.090 ms (00:05.623)
发现果然如此,仅仅插入了200条数据而已,循环次数就达到了1141800次(5709*200)。而在原先的函数中往pgawr_names表中插入了有5000多条数据,这意味着至少要循环1千万次,这也是为什么会觉得SQL一直卡住在执行lseek的原因了。
回头再去看BUG #15455: Endless lseek,其实也是类似的原因,由于在会话中表数据量变化较多,而统计信息无法更新,同时SQL中有嵌套循环,导致性能异常,陷入了endless lseek中。

对此我们需要注意了,如果在同一个事务中先对某张表进行大量的增删操作,又由于其统计信息在事务结束前是不会更新的,而恰好该事务后面又有相关查询使用了该表,可能会对性能产生巨大影响,而如果该SQL中又包含较多嵌套循环,那么你也可能陷入看上去无休无止的lseek中了~
相关文章:
Endless lseek导致的SQL异常
最近碰到同事咨询的一个问题,在执行一个函数时,发现会一直卡在那里。 strace抓了下发现会话一直在执行lseek,大致情况如下: 16:13:55.451832 lseek(33, 0, SEEK_END) 1368064 <0.000037> 16:13:55.477216 lseek(33, 0, SE…...
JUC-day01
JUC-day01 什么是JUC线程的状态: wait sleep关键字:同步锁 原理(重点)Lock接口: ReentrantLock(可重入锁)—>AQS CAS线程之间的通讯 1 什么是JUC 1.1 JUC简介 在Java中,线程部分是一个重点,本篇文章说的JUC也是关于线程的。JUC就是java.util .con…...
Mind+Python+Mediapipe项目——AI健身之跳绳
原文:MindPythonMediapipe项目——AI健身之跳绳 - DF创客社区 - 分享创造的喜悦 【项目背景】跳绳是一个很好的健身项目,为了获知所跳个数,有的跳绳上会有计数器。但这也只能跳完这后看到,能不能在跳的过程中就能看到,…...
数据库概述
20世纪60年代后期,就出现了数据库技术。取得成就如下:造就了四位图灵奖得主发展成为以数据建模和DBMS核心技术为主,内容丰富的一门学科。带动了一个巨大的软件产业-DBMS产品及其相关工具和解决方案。四个基本概念数据数据是数据库中存储的基本…...
【已解决】解决IDEA的maven刷新依赖时出现Connot reconnect错误
前言 小编我将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识,有兴趣的小伙伴可以关注一下!也许一个人独行,可以走的很快,但是一群人结伴而行,才能走的更远!让我们在成长的道路上互相学习&#…...
动态链接库(.so)文件的变编译和引用、执行
动态链接库(.so)文件的变编译和引用 动态链接库:SO(Shared Object)是一种动态链接库,也被称为共享库。它是一种可被多个程序共享使用的二进制代码库,其中包含已编译的函数和代码。与静态链接库不同,动态链接…...
linux(centos8)文件解压命令
linux解压命令tar 解压命令常用解压命令1 [.tar] 文件 解压到当前文件夹2 [.tar.gz] 文件 解压到当前文件夹3 [.tar] 解压到指定文件夹 -C 必须是大写unzip 解压命令常用解压命令1 [.zip]解压到当前文件夹2 [.zip] 解压到指定文件夹2 [.zip] 解压到指定文件夹(强行覆…...
阅读笔记6——通道混洗
一、逐点卷积 当前先进的轻量化网络大都使用深度可分离卷积或组卷积,以降低网络的计算量,但这两种操作都无法改变特征图的通道数,因此需要使用11的卷积。总体来说,逐点的11卷积有如下两点特性: 可以促进通道之间的信息…...
上海亚商投顾:沪指失守3300点 卫星导航概念全天强势
上海亚商投顾前言:无惧大盘涨跌,解密龙虎榜资金,跟踪一线游资和机构资金动向,识别短期热点和强势个股。市场情绪指数早间低开后震荡回升,沪指盘中一度翻红,随后又再度走低,创业板指午后跌近1%。…...
疯狂的SOVA:Android银行木马“新标杆”
2021年8月初,一款针对Android银行APP的恶意软件出现在人们的视野中,ThreatFabric 安全研究人员首次发现了这一木马,在其C2服务器的登录面板,研究人员发现,攻击者将其称之为SOVA。 ** SO** ** V** ** A简介** 在俄语中…...
汽车零部件企业数字工厂管理系统建设方案
在汽车零部件制造领域,伴随工业信息化与机器人化,制造模式逐渐从 CAD/CAE/CAM 数字化设计及加工走向全产品周期虚拟现实的数字化工厂管理系统平台,实现虚拟现实设计制造,防范产品缺陷并预防设备故障,大幅提高生产效率。…...
【线程同步工具】Semaphore源码解析
控制对资源的一个或多个副本的并发访问 Java API 提供了一种信号量机制 Semaphore。 一个信号量就是一个计数器, 可用于保护对一个或多个共享资源的访问。 当一个线程要访问多个共享资源中的一个时,它首先需要获得一个信号量。如果信号量内部的计数器的…...
获取实时天气
一、用天气API(需要付费) 网址:https://www.tianqiapi.com/请求方式及url:请求方式:GET接口地址:https://tianqiapi.com/free/day请求示例https://www.tianqiapi.com/free/day?appid_____&appsecret__…...
【数据库】redis数据持久化
目录 数据持久化 一, RDB 1, 什么是RDB 2,持久化流程 3, 相关配置 案例演示: 4, 备份和恢复 1、备份 2、恢复 3,优势 4, 劣势 二,AOF 1,什么是A…...
前端编译、JIT编译、AOT编译
一、前端编译:java设计之初就是强调跨平台,通过javac将源文件编译成于平台无关的class文件, 它定义了执行 Java 程序所需的所有信息(许多Java"语法糖",是在这个阶段完成的,不依赖虚拟机ÿ…...
父子组件中,子组件调用父组件的方法
父子组件中,子组件调用父组件的方法 方法一:直接在子组件中通过this.$parent.event来调用父组件的方法 父组件 <template><p><child>父组件</child></p> </template> <script>import child from ~/compone…...
第七章.深度学习
第七章.深度学习 7.1 深度学习 深度学习是加深了层的深度神经网络。 1.加深层的好处 1).可以减少网络的参数数量 5*5的卷积运算示例: 重复两次3*3的卷积层示例: 图像说明: ①.一次5 * 5的卷积运算的区域可以由两次3 * 3的卷积运算抵消&a…...
小学生学Arduino---------点阵(三)动态的显示与清除
学习目标: 1、理解“整数值”的概念与使用 2、理解“N1”指令的意义 3、掌握“反复执行多次”指令的使用 4、掌握屏幕模块的清除功能指令 5、理解“反复执行”指令与“反复执行多次”指令的嵌套使用 6、搭建电路图 7、编写程序 效果: 整数包括…...
opencv图片处理
目录1 图片处理1.1 显示图片1.2 旋转图片1.3 合并图片1.4、Mat类1.4.1、像素的储存结构1.4.2、访问像素数据1.6、rgb转灰度图1.7、二值化1.8、对比度和亮度1.9、图片缩放1.9.1、resize临近点算法双线性内插值1.9.2、金字塔缩放1.10、图片叠加1 图片处理 1.1 显示图片 #includ…...
C++ Primer Plus 学习笔记(二)—— 复合类型
数组 当我们只是定义了数组,而没有对数组进行初始化时,那数组的值将是未定义的。 在对数组进行初始化时,如果只对数组的一部分进行初始化,编译器会将把其他元素自动设置为0。 #include <iostream>using namespace std;in…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
2025盘古石杯决赛【手机取证】
前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来,实在找不到,希望有大佬教一下我。 还有就会议时间,我感觉不是图片时间,因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...
深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
20个超级好用的 CSS 动画库
分享 20 个最佳 CSS 动画库。 它们中的大多数将生成纯 CSS 代码,而不需要任何外部库。 1.Animate.css 一个开箱即用型的跨浏览器动画库,可供你在项目中使用。 2.Magic Animations CSS3 一组简单的动画,可以包含在你的网页或应用项目中。 3.An…...
使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...
2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
基于PHP的连锁酒店管理系统
有需要请加文章底部Q哦 可远程调试 基于PHP的连锁酒店管理系统 一 介绍 连锁酒店管理系统基于原生PHP开发,数据库mysql,前端bootstrap。系统角色分为用户和管理员。 技术栈 phpmysqlbootstrapphpstudyvscode 二 功能 用户 1 注册/登录/注销 2 个人中…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...
