PostgreSQL 16 → 18 官方升级实践(Ubuntu 24.04)

一次真实的升级记录。 从 Ubuntu 默认 Cluster 管理模式,迁移到 PostgreSQL 官方推荐目录结构。 全程使用 pg_upgrade,保留所有数据库,最终实现: PostgreSQL 18 官方数据目录 systemd 管理 MacBook 远程访问 完整踩坑记录 一、为什么升级? 原环境: 项目 版本 Ubuntu 24.04 PostgreSQL 16.14 数据目录 /srv/data/db/postgres/16/main 希望升级到: PostgreSQL 18.4 PostgreSQL 18 vs 16 关键改进 特性 PostgreSQL 16 PostgreSQL 18 增量备份 ❌ 仅全量 ✅ pg_basebackup 支持增量,备份时间减少 50%+ 逻辑复制 基础支持 ✅ 支持序列和大对象复制 并行查询 有限并行 ✅ 更多场景支持并行(VACUUM、CREATE INDEX) JSON 处理 JSONB 基础 ✅ JSON_TABLE 增强,复杂查询更高效 SSD 优化 无特殊处理 ✅ 强制 I/O 调度优化(见下文) 连接池 需外部工具 ✅ 内置连接池改进 SSD 专项优化(重要) PostgreSQL 18 对 NVMe/SSD 做了底层优化,这是升级的核心理由: ...

July 25, 2026 · FXIO

家用 PostgreSQL 调优实战:从默认配置到性能翻倍

一台 16GB 内存的家用服务器,PostgreSQL 跑起来总觉得慢,改配置又怕改坏——这篇文章用真实的配置文件逐项拆解,告诉你哪些参数值得动,动多少合适。 开场:一次"改坏"的调优经历 上周帮朋友调一台家用服务器上的 PostgreSQL,他信誓旦旦说"我照着网上的教程改了 shared_buffers 到 8GB,结果数据库直接起不来了"。我一看配置——16GB 的机器,shared_buffers 给了 8GB,再加上操作系统缓存、其他服务,内存直接 OOM。 这种故事在家庭服务器圈子里太常见了。PostgreSQL 的 postgresql.conf 有几百个参数,但真正需要动的也就十来个。今天我们用一台真实的家用机器配置,逐项拆解。 硬件家底:你的机器够干多大的活 先看看今天的实验对象: 项目 配置 CPU 12th Gen Intel i5-1240P(12核16线程) 内存 16GB 磁盘 SSD 系统 Ubuntu 24.04 LTS PG 版本 PostgreSQL 16 16GB 内存、SSD、12 代酷睿——这是典型的家用 NAS 或者小型工作站配置。够用,但没有太多余量可以挥霍。 第一梯队:内存分配三兄弟 PostgreSQL 的性能调优,80% 就是调内存分配。搞明白三个参数,基本就入门了。 shared_buffers — 数据库的"工作台" shared_buffers = 2GB 这是 PostgreSQL 自己用来缓存数据页的内存。你可以把它想象成厨师的工作台——台面越大,能同时摊开的食材越多,不用反复跑冰箱拿东西。 经验法则:物理内存的 25%。16GB 的机器给 2GB 是合理的。给太大(比如 8GB),操作系统缓存会被挤掉,反而变慢;给太小,频繁读磁盘,性能拉胯。 验证方法: SELECT pg_size_pretty(pg_database_size(current_database())) AS db_size, pg_size_pretty(pg_total_relation_size('projects')) AS table_size; 如果你的数据库总量小于 shared_buffers,那说明数据全在缓存里,调大没意义。 ...

July 24, 2026 · FXIO

Chromatic · 色彩主题实验室

<!DOCTYPE html> Chromatic · 色彩主题实验室 克莱因蓝 勃艮第红 马尔斯绿 蒂芙尼蓝 申布伦黄 🌙 深色模式 Chromatic · 色彩叙事 ...

July 24, 2026 · FXIO

PostgreSQL 百万级数据实战:查询计划与索引策略全解析

上一篇聊了家用 PostgreSQL 的配置调优,这篇来点硬的——100 万条数据,PostgreSQL 的查询计划选择会发生什么变化?索引策略又该怎么调? 开场:当 30 条变成 100 万条 上篇博客里,我们的 projects 表只有 30 条数据。COUNT 一下 0.97ms,排序一下 0.54ms,快得飞起。但你心里清楚——30 条数据,任何数据库都不会慢。 真正的考验是:数据量上来之后,你的索引还管用吗?优化器还会乖乖走 Index Scan 吗? 今天我们用 100 万条真实数据,把 PostgreSQL 的查询计划拆个底朝天。 实验环境 项目 配置 CPU 12th Gen Intel i5-1240P(12核16线程) 内存 16GB 磁盘 SSD PG 版本 PostgreSQL 16 数据量 1,000,000 行 数据大小 174 MB 索引大小 74 MB 总大小 248 MB 100 万行,248MB——不大不小,刚好是很多真实项目的规模。 插入性能:100 万条要多久 1,000,000 条批量插入: 12.7 秒 平均每秒约 7.8 万条。用的是逐批 10000 条的 INSERT ... VALUES 拼接方式,没有用 COPY。如果用 COPY FROM STDIN,速度还能再快 2-3 倍。 ...

July 24, 2026 · FXIO

深度学习实战——从标注到部署的完整闭环

核心问题:怎么让一个“不会看”的模型,学会识别工业零件表面的划痕? 质检员的 0.5 秒困境 想象你是一个质检员,面前是传送带上飞速流动的钢板。每秒几十张,你要在 0.5 秒内判断:这张有没有划痕?有没有夹杂物?有没有裂纹? 人眼做不到。但神经网络可以。 目标——用深度学习,把这双"眼睛"训练出来。从 CNN 的底层原理开始,经过 YOLO 目标检测实战、LabelMe 数据标注,到用 trace-cn 辅助写训练代码,最终走完**“标注→训练→推理”**的完整闭环。 CNN 基础:卷积神经网络到底在"看"什么? 从生物视觉到数学公式 CNN 的设计灵感来自人类视觉皮层。你看到一张照片,不是逐个像素分析的——你先看到边缘,再看到形状,最后组合出"这是一张脸"。CNN 干的是同样的事: 浅层卷积核提取边缘、纹理(“这里有条线”) 中层把边缘组合成形状(“这是个圆形”) 深层把形状组合成语义(“这是个齿轮”) 核心操作是卷积:一个小的权重矩阵(比如 3×3)在图像上滑动,每个位置做加权求和。一个 3×3 的卷积核只有 9 个参数,却能扫描整个图像——这就是参数共享的威力。全连接网络处理一张 224×224 的图片需要上亿参数,CNN 可能只需要几万。 为什么卷积核能提取特征? 假设你有一个检测水平边缘的卷积核: [[-1, -1, -1], [ 0, 0, 0], [ 1, 1, 1]] 当它滑过图像时,遇到"上暗下亮"的区域,输出值就很大;遇到均匀区域,输出接近零。所以卷积核本质上就是一个模式匹配器——每个核负责匹配一种特定的视觉模式。 池化层:压缩但不丢失 卷积之后通常接一个池化层(最常见的是 2×2 最大池化)。它做的事情很简单:把 2×2 区域里的最大值保留下来,其余扔掉。 为什么这么"浪费"?因为池化做了两件事: 降低计算量:特征图尺寸减半,参数量降到 25% 增加鲁棒性:目标稍微平移一点,最大池化的输出不变 这就像你看一个人,不需要记住他脸上每个像素的位置,只需要知道"眼睛在鼻子上面"这种相对关系。 训练的三驾马车:损失函数、学习率、早停 损失函数衡量模型预测和真实值的差距。不同任务用不同的损失: 分类用交叉熵(“你预测是猫,但其实是狗,惩罚!") 目标检测用 CIoU Loss(同时考虑框的重叠面积、中心距离、宽高比) 分割用 Dice Loss(对小目标特别敏感,比如医学影像里的肿瘤) 学习率控制每次更新参数的步长。太大了来回震荡,太小了原地踏步。实际训练中常用自适应学习率(如 Adam),它会根据梯度自动调整步长——梯度大就小步走,梯度小就大步跑。 ...

July 11, 2026 · FXIO

识别技术——让机器从"看见"到"读懂"

机器视觉采集到图像之后,怎么从中提取有意义的信息?识别技术给出了答案。 双十一仓库的条码失明事件 想象一下这个场景:双十一仓库高峰期,传送带上每秒飞过上百个包裹。你设计的条码识别系统突然大批量"失明"——不是算法不对,而是条码印得太浅、包裹朝向随机、曲面包装拉伸变形。客户在电话那头吼:“你们的系统废了!” 这是工业视觉工程师的日常。识别不是一个算法问题,而是一个工程问题。条形码识别、二维码识别、几何识别、大豆检测——用四个真实场景告诉我们:让机器"读懂"图像,远比"看见"它难得多。 条形码识别:工业世界的基础语言 条形码是工业自动化的"老前辈",从超市收银到物流分拣,无处不在。但你以为识别条码就是"扫一下"?太天真了。 课程用 DobotVisionStudio 搭建了一个食品包装盒识别系统,流程是: 图像采集 → 摄像头拍下包装盒 快速匹配 → 用模板定位条码区域 仿射变换 → 校正角度和位置 字符识别 → 读取包装上的文字信息 条码识别 → 解码条形码 脚本判断 → 对比字符与条码,判断是否匹配 听起来顺理成章,但坑在细节里。课程特别提到:有时候条形码根本识别不出来。为什么? 静区宽度不够:条码两侧的空白区域被压缩,解码器找不到起始位置。 码制没选对:系统默认只识别常见码制,如果遇到特殊编码,需要手动开启"所有码"选项。 定位不准:用快速匹配做模板时,矩形掩膜画得太小或太大都会翻车。 解决方案:调参数 + 试错。把静区宽度逐步调大,把码制选项全开,把匹配框精调到刚好包含条码。这没有银弹,只有耐心。 💡 经验之谈:条码识别的工程难度往往不在算法,而在"最后一公里"——印刷质量、安装角度、光照条件。这些才是现场调试工程师的噩梦。 二维码识别:比条码多一个维度 二维码识别的流程和条形码类似,但多了一个关键能力:抗变形。二维码可以贴在曲面、歪斜、甚至部分遮挡的物体上,依然能解码——靠的是 Reed-Solomon 纠错算法。 课程演示的完整流程: 快速匹配 → 定位二维码区域(创建模板 → 矩形掩膜 → 编辑模板) 仿射变换 → 校正透视变形(继承方式选"按区域") 二维码识别 → 绘制识别区域,解码内容 脚本编写 → 把结果存入变量,做后续逻辑判断 这里有个有趣的工程细节:仿射变换的继承方式选"按区域"而不是"按图像"。为什么?因为二维码可能出现在画面的任何位置,你需要让变换矩阵跟着定位结果走,而不是固定死。 课程还展示了脚本编写——把识别结果存入 strEWMSB 变量,输出 RESULT 作为判断依据。这体现了工业视觉的核心思想:识别只是第一步,判断和决策才是目的。 几何识别:从像素到精确测量 如果说条码/二维码解决的是"读"的问题,几何识别解决的是"量"的问题。 课程用 DobotVisionStudio 的测量工具,演示了如何测量: ...

July 4, 2026 · FXIO

用 YOLO 数筷子——从 OpenCV 到深度学习的目标检测实战

不锈钢筷子头挨着头、反光闪瞎眼,OpenCV 霍夫圆直接投降。这个小项目走了一遍从传统 CV 到深度学习的完整路径。 那些反光的筷子头,把 OpenCV 逼疯了 事情是这样的:要数一把不锈钢筷子有多少根。听起来很简单对吧?拿个相机拍一下,数圆圈就行了。 用 OpenCV 的霍夫圆变换(HoughCircles)试了一下——惨不忍睹。不锈钢顶部的金属反光和阴影被边缘检测器当成独立实体,满屏幕乱飞的假阳性圆圈。筷子头挨得又近,阴影轮廓互相粘连,算法根本分不清这是 16 根筷子还是 2 个异形物体。 更要命的是调参。换个光照条件,param1、param2 又得重来。换个桌面背景,再来一遍。这不是写代码,这是在做手工。 这就是传统 CV 的死穴:它只认几何形状,不认"东西"。霍夫圆变换的逻辑是"找到符合圆方程的像素点集合",它不理解"这是一根筷子的截面"这个概念。光照一变、角度一变、排列一变,像素梯度就变了,算法就废了。 为什么 YOLO 能搞定 YOLO 的思路完全不同。它不是在像素层面找几何形状,而是从数百万张图片里学会了"什么是筷子头"。它理解的是语义特征,不是像素梯度。 具体到这个场景: 问题 OpenCV (霍夫圆) YOLO 不锈钢高光 把光斑误判为实体 能通过上下文推理出这是光斑 筷子头紧密排列 把多个物体融合成一个 擅长分辨紧密排列的多个实例 换光照/换背景 每次都要重调参 一次训练,到处通用 简单说:OpenCV 是"按规则找",YOLO 是"凭经验认"。规则怕变化,经验怕没见过——但筷子头这种常见物体,YOLO 的训练集里见得多了。 从标注到训练:三步走 第一步:安装标注工具 先检查 Python 版本: python --version Python ≥ 3.9 → 用 LabelMe,支持圆形/多边形标注,本项目用的就是它 Python ≤ 3.8 → 建议用 LabelImg,只支持矩形框,但兼容性更好 💡 LabelMe 依赖的 pyqt5 在 Python 3.8 以下版本经常装不上,折腾半小时不如直接换工具。 ...

June 28, 2026 · FXIO

从数据到系统——当工业视觉遇上 AI 工程化

核心问题:光有技术不够,怎么把它变成一个能落地的系统? 那个"模型做出来了但用不了"的尴尬时刻 你有没有遇到过这种情况:团队花了一个月训练出一个效果不错的模型,兴冲冲拿给客户看,客户问"那我怎么用?",然后就尴尬了。 工程化——从“我懂原理”到“我能交付”的转变。下面从预测性维护的数据分析开始,一路走到成像系统的智能选型,最后把行业知识封装成可复用的工具。整个过程,与其说是在学技术,不如说是在学怎么把技术变成产品。 预测性维护:用数据讲故事 上午的切入点是 AI4I 2020 预测性维护数据集。这个数据集模拟了工业设备的运行参数:空气温度、工艺温度、转速、扭矩、刀具磨损量,共 10,000 条记录,其中只有 3.39% 是故障样本。 先别急着建模 很多工程师拿到数据第一反应是"赶紧上模型"。但课程的做法是:先做 EDA(探索性数据分析)。 为什么?因为如果你不理解数据,模型给你的结果你也看不懂。就好比你不懂电路图就去修电器,运气好能修好,运气差就炸了。 具体做了什么?几个关键发现: 扭矩和转速的散点图一画出来,故障样本和正常样本的分布区域一目了然。OSF(过冲故障)集中在高扭矩(>50 Nm)+ 高刀具磨损(>180 min)区域 故障率按产品类型递减:L(3.92%) > M(2.77%) > H(2.09%),这个规律可以直接指导备件策略和质保定价 RNF(随机故障)只有 19 条,这种极端不均衡的数据,直接丢进模型训练大概率会出问题 从分析报告到交互看板 最终产出的不只是一个分析报告,而是一个交互式的数据看板(HTML)。可以点选、筛选、动态展示。 这个思路在工业场景里特别实用。你给产线管理者一份 PDF 报告,他可能看都不看;但你给他一个能点来点去的看板,他至少会好奇地点两下。这两下,可能就是他理解数据的开始。 课程还给出了一个很实用的规则引擎建议:不用部署 ML 模型,直接把阈值规则嵌入 SCADA 系统,就能覆盖约 70% 的故障预警场景。有时候,够用就好。 从提示词到智能体:把经验变成工具 下午画风一转,开始讲怎么把行业知识封装成 AI 智能体。 成像系统选型专家 核心案例是"成像系统选型专家"。传统做法是找一个有十年经验的工程师,你告诉他"我要检测手机壳表面划痕",他会问你一堆问题(精度多少?节拍多快?材质是什么?),然后给出一套方案。 现在要做的事情是:把这个工程师的经验变成一个可复用的智能体。 课程展示了一段很长的 System Prompt,里面系统性地整理了成像系统的选型规则: 相机怎么选:视场 = 产品尺寸 + 各种余量,像素精度要做到公差的 1/5 到 1/10 镜头怎么算:焦距 f = 工作距离 × 芯片尺寸 / 视场,远心镜头适合高精度测量 光源怎么选:轮廓检测用背光,表面划伤用暗场光,反光件用穹顶光 成像方式判断:2D 面阵、线扫、3D 结构光、智能相机……每种都有适用场景 这不是简单的"让 AI 回答问题",而是把领域专家的决策逻辑结构化地注入到 AI 中。好比你把一个老师傅的经验写成了标准作业指导书,但这个指导书还能根据具体情况灵活调整。 ...

June 28, 2026 · FXIO

机器视觉入门——光、镜头、相机,以及为什么选错一个全白搭

工业产线上,机器怎么"看"东西?答案不在算法里,在硬件选型的每一个细节里。 开场:一个真实的翻车现场 去年帮一个朋友调一条五金件检测线。缺陷检测算法在实验室跑得好好的,一上产线就各种误报。排查了半天,最后发现原因特别朴素——光源选小了。光源有效发光面积没覆盖住整个视野,画面中间亮、两边暗,边缘的工件特征被算法当成了缺陷。 一个两千块的光源问题,浪费了三天调算法。 这就是机器视觉的第一课:它是一个链式系统,光→镜头→相机→算法,环环相扣。任何一个环节的短板都会被后续环节放大。 算法再牛,喂给它的图像质量不行,结果就是垃圾进、垃圾出。 下面记录这条链路的学习要点。 硬件三件套:光源、镜头、相机 光源:最容易被低估的环节 很多工程师(包括以前的我)觉得光源就是"把东西照亮"。错。光源的核心目标是让目标特征和背景之间的对比度最大化。 打个比方:你要在白纸上检测白色划痕,用白光正面打,什么都看不到。但换成低角度的条形光源,光线擦过表面,划痕边缘产生反射,背景是暗的,划痕是亮的——缺陷就"跳"出来了。 课程里讲了五六种常见光源,我按使用频率排个序: 环形光源:最通用,360° 均匀照明,适合大多数表面检测。如果不知道用什么,先试环形光。 条形光源:方向性强,擅长消除镜面反光。检测金属平面字符时,条形光比环形光好用得多——环形光容易在光滑表面打出大面积光晕。 背光源:从底部打光,物体轮廓变成剪影。做尺寸测量、孔径检测时的标配。 同轴光源:内置分光镜,光线垂直照射。专门对付高反光的镜面、抛光金属,能消除凹凸产生的阴影。 穹顶光源:半球形漫射,360° 无死角。检测曲面工件(比如球形外壳)时的首选,普通光源打上去全是反光斑点。 还有一个容易忽略的点:光源颜色选择遵循互补色原理。红光照绿色物体,黑白相机下物体是黑色的;红光照红色物体,物体是白色的。想让红色字符在白色背景上更突出?用蓝色光源——红色字符吸收蓝光变黑,白色背景反射蓝光变亮,对比度直接拉满。 镜头:焦距只是起点 镜头选型的第一步是算焦距,公式不复杂: 焦距 = 工作距离 × 芯片尺寸 / 视场 但焦距选对了只是及格线。真正容易踩坑的是两个参数: 景深——简单理解就是"前后多大范围内的东西是清楚的"。景深越小,对焦平面以外的物体就越模糊。影响景深的三个因素:光圈越大景深越小,焦距越长景深越小,工作距离越近景深越小。做尺寸测量时,如果工件有厚度(比如一个盒子),景深不够就会出现"上面清楚、下面模糊"的问题。 畸变——普通定焦镜头天然有畸变,短焦是桶形畸变(像被捏扁了),长焦是枕形畸变(像被拉长了)。人眼看不出小于 2% 的畸变,但做精密测量时,边缘 1mm 的畸变就是实打实的误差。这时候就得上远心镜头——它的特点是"无论物体离镜头远近,在图像里的大小不变"。类比一下:普通镜头像人眼看东西,近大远小;远心镜头像用尺子量,不管尺子放多远,读数不变。 另外注意镜头和相机的接口匹配:C 口后截距 17.5mm,CS 口 12.5mm,差 5mm。CS 口相机接 C 口镜头要加 5mm 接圈,反过来不行。接口不匹配,图像就是糊的。 相机:一个公式定成败 相机选型的核心公式: 像素精度 = 视场 / 分辨率 意思是:图像上一个像素代表实际空间中多大的尺寸。 举个例子:用 500 万像素相机(2592×1944)拍 80mm 宽的视野,像素精度 = 80 / 2592 ≈ 0.031 mm/pixel。也就是说图像里一个像素对应实际 0.031mm。 经验值:要检测的最小特征,至少要在图像中占 2~3 个像素。 如果你要检测 0.1mm 的缺陷,像素精度至少要到 0.03~0.05mm/pixel,否则缺陷在图像里就一两个模糊的点,算法根本抓不住。 ...

June 27, 2026 · FXIO

Presto 驱动升级引发的生产事故:超长 SQL 400 报错排查记

问题现象 普通 SQL 正常,stg 环境没发现异常。但生产环境用户反馈:超长 SQL(超过 1MB)会触发 400 报错。 恰好生产环境的用户有很多那种业务逻辑复杂、拼接出来的超长 SQL。 排查过程 第一步是对比。把报错的 SQL 和不报错的 SQL 摆在一起看,唯一的共同点就是——长。 短 SQL 跑得好好的,长到一定长度就 400。这不是 SQL 语法问题,是传输层的问题。 根因 查到最后,原因是这样的: 安全合规要求,把普通的 Statement 升级为 PreparedStatement。因为普通 Statement 有 SQL 注入风险,安全团队要求整改。 Presto 驱动版本太低,低版本的 Presto JDBC 驱动对 PreparedStatement 的支持不完善,特别是对超长 SQL 的处理有 bug。 服务端 Presto 没有同步升级。原因很简单——影响太大,涉及的下游服务和业务太多,不敢动。 所以就出现了一个尴尬的局面:客户端驱动升级了(为了安全),服务端没升级(为了稳定),两边版本不一致,超长 SQL 直接 400。 解决方案 还原升级。 把客户端驱动退回到兼容当前服务端的版本。安全问题用其他方式规避(比如在应用层做参数化查询、输入校验等)。 这不是最优解,但在"安全"和"可用"之间,先保可用。 避坑建议 1. 灰度环境重点覆盖验证 stg 环境为什么没发现?因为测试用的 SQL 都是短的。灰度环境应该重点覆盖边界场景: 超长 SQL(1MB+) 特殊字符 高并发场景 2. 客户端和服务端版本要对齐 升级驱动前,先确认服务端版本兼容性。不要客户端升了、服务端没升,两边版本不一致是定时炸弹。 3. 安全整改要评估影响面 ...

June 10, 2026 · FXIO