从多个大版本一路升级到 Nextcloud 34:数据目录分离、App 兼容性、数据库索引与完整性修复

长期运行的 Nextcloud 实例,升级通常不是简单地执行一次: 就可以结束。 随着运行时间增加,实例会逐渐积累: 因此,一次跨越多个主要版本的升级,本质上更像是一次系统整理。 这次升级最终依次完成: 最终版本为: 一、没有跨主要版本跳跃 整个升级过程采用官方支持的逐版本路线。 例如: 这样做的主要原因不是保守,而是每一个主要版本都可能包含自己的: 如果跳过中间版本,就可能绕过原本应该执行的升级阶段。 二、数据目录分离显著改变了 updater 的行为 在早期升级过程中,一个非常明显的瓶颈出现在: 某次升级中,这一步曾经持续: 后来数据目录从应用程序目录中彻底分离。 原来的结构类似: 调整后变成: Nextcloud 配置中的: 也同步修改。 而且没有通过符号链接伪装旧数据目录。 之后再次进行: 升级时, 几乎变成瞬时完成。 这说明此前 updater 很大一部分时间很可能消耗在庞大的数据目录树检查上。 应用代码和数据目录分离后,更新器只需要处理真正属于程序的文件。 三、升级使用 updater.phar,并明确关闭 updater 自己的备份 其中一次升级命令类似: 这里使用: 并不是表示系统不需要备份。 而是因为该实例已经有独立的备份策略,不需要 updater 再额外生成一份完整程序备份。 更新完成后,继续执行: 最终状态为: 四、第三方 App 是升级中最需要单独处理的部分 Nextcloud Core 与第三方 …

一次持续近一周的 Nextcloud 后台数据库迁移:PreviewMigrationJob 的资源失控、限速执行与最终完成

在一次 Nextcloud 大版本升级之后,系统表面上已经完成版本更新,维护模式也已经解除,但数据库和存储层仍然存在一个持续运行的后台迁移任务: 这个任务最终持续了接近一周。 它并不是传统意义上“数据库 Schema 升级跑了一个星期”,而是 Nextcloud 把一部分历史数据迁移拆成了后台任务,使主版本升级可以提前结束,而大规模历史数据转换则在服务恢复之后继续进行。 这类设计可以缩短维护窗口,但也带来了一个容易被忽略的问题: 升级完成,不代表升级相关的所有数据迁移都已经结束。 一、迁移的实际规模 该实例积累了大量历史 Preview 数据。 当时统计到的迁移规模大致为: 因此,这并不是一个几十秒能够结束的普通后台任务。 Nextcloud 会让 PreviewMigrationJob 分批处理数据,而不是在版本升级过程中一次性完成全部迁移。 这也是为什么: 已经执行成功, 也都已经恢复正常, 但后台仍然持续进行数据迁移。 二、真正的问题不是“慢”,而是普通 cron 调度下出现资源失控 最开始,这项任务完全交给 Nextcloud 正常的 cron 机制运行。 例如: 正常情况下,这种方式没有问题。 但对于一个规模达到十万级数据库记录、百万级历史 Preview 文件的迁移任务来说,问题开始出现。 后台 PHP 任务逐渐堆积,部分进程进入: 也就是 Linux 中的不可中断 I/O 等待状态。 随后系统出现了明显异常: CPU 本身并不是主要瓶颈。 真正的问题更接近: …

在 Linux 上为特定 USB 网络设备设置稳定接口名:摆脱 MAC 地址和 USB 端口变化

在 Linux 上使用 USB 蜂窝网络设备、便携式路由器或手机 USB 网络共享时,经常会遇到一个看似不起眼、实际上很影响自动化的问题: 同一台 USB 网络设备重新启动后,网卡名称可能发生变化。 如果系统配置、路由优先级、监控脚本或自动化服务依赖固定接口名,这种变化就会带来麻烦。 一种常见做法是根据 MAC 地址生成接口名,另一种做法是绑定 USB 物理端口。但这两种方式都有局限。 更稳妥的方案是: 识别设备本身,而不是识别它当前的 MAC 地址或插在哪一个 USB 口。 本文记录一种基于 systemd.link 和 udev 设备属性的实现方式。 一、问题:USB 网络接口名称并不一定稳定 许多 USB 网络共享设备通过 RNDIS、CDC Ethernet 等方式向 Linux 暴露网络接口。 系统可能根据 MAC 地址生成类似这样的名称: 如果设备每次重新启动都会生成新的 MAC 地址,那么就可能出现: 对于普通桌面使用,这通常没有太大问题。 但对于一台长期运行的 Linux 主机,如果配置中存在: 或者脚本中需要: 那么接口名变化就会破坏自动化。 二、第一种解决方法:绑定 …

全球食品安全标准谁更严格?欧盟、日本、美国、中国等主要体系对比

讨论不同国家和地区的食品安全标准时,经常会出现一个很直观的问题: 到底谁最严格? 欧盟、日本、美国、中国、加拿大、澳大利亚、新西兰、韩国、新加坡等经济体,都建立了相当完整的食品安全法律体系。然而,如果试图简单地把这些国家排成“第一名、第二名、第三名”,很容易产生误导。 原因在于,所谓“严格”,实际上包含很多完全不同的维度。 有的体系更强调食品添加剂的上市前审批,有的更强调生产过程中的风险控制;有的采用明显的预防原则,有的则更重视科学证据和风险收益平衡;还有一些国家会允许历史上长期使用的传统添加物继续存在。 因此,食品安全制度并不存在一个绝对统一的“严格程度”。 不过,如果把主要制度放在一起比较,仍然能够看到非常鲜明的监管哲学差异。 一个大致的全球梯队 如果比较的是以下几个因素: 食品添加剂和新食品的上市准入门槛、正面清单制度、预防原则、企业合规责任、风险评估体系、食品追溯制度,以及进口食品监管等,可以粗略地把主要体系分成几个梯队。 大致梯队 国家或地区 主要特点 第一梯队 欧盟、日本 食品添加剂准入相对保守,正面清单制度明显 第二梯队 加拿大、澳大利亚/新西兰、韩国 成熟的科学风险管理体系,生产和追溯要求严格 第三梯队 中国、美国、新加坡 制度完整,但监管哲学各有明显特色 持续发展型 印度等大型新兴市场 法规体系快速完善,但制度成熟度仍存在差异 如果一定要压缩成一个近似顺序,可以写成: 欧盟 ≳ 日本 > 加拿大 ≈ 澳新 ≈ 韩国 > 中国 ≈ 美国 ≈ 新加坡 > 印度 但这个排序只能理解为一种宏观概括。 一旦改变评价指标,顺序就会发生变化。 欧盟:最典型的“宁可谨慎一些”体系 如果讨论的是食品监管中的“保守程度”,欧盟通常会排在非常靠前的位置。 欧盟食品安全体系一个非常重要的特点,是明确采用了: 预防原则(Precautionary Principle) …

日本の「就労ビザ」は何種類ある?在留資格ごとの特徴と人数を政府統計から整理

日本で外国人が働く際によく使われる「就労ビザ」という言葉。実は、日本の法律上「就労ビザ」という一つの在留資格が存在するわけではない。 日本では、外国人が日本で行う活動の内容に応じて「在留資格」が細かく分けられており、その中に、就労が認められている複数の在留資格が存在する。 出入国在留管理庁の分類では、教授、技術・人文知識・国際業務、経営・管理、特定技能、技能実習など、多数の在留資格で就労が認められている。 では、それぞれどのような仕事を対象としており、実際に日本には何人くらいの在留者がいるのだろうか。 この記事では、出入国在留管理庁・政府統計「在留外国人統計」の2025年12月末時点のデータを基に整理する。 日本の在留外国人数は400万人を突破 2025年12月末時点の日本の在留外国人数は、 4,125,395人 となり、初めて400万人を超えた。 前年末の3,768,977人から356,418人増加し、前年比では9.5%の増加となっている。 ただし、この412万人すべてが「就労ビザ」で滞在しているわけではない。 永住者、留学生、家族滞在、日本人の配偶者等なども含まれているためである。 就労を主目的とする在留資格だけを見ると、以下のようになる。 主な就労系在留資格と在留者数 在留資格 2025年末の人数 主な特徴 技術・人文知識・国際業務 475,790人 IT、技術職、事務・企画、貿易、翻訳など 技能実習 456,618人 技能移転を目的とする現行制度 特定技能 390,296人 人手不足分野で働く外国人向け制度 技能 54,574人 外国料理調理師など熟練技能職 経営・管理 46,781人 日本で事業を経営・管理する人 高度専門職 32,953人 高度人材ポイント制による専門人材 企業内転勤 19,161人 海外企業から日本拠点への転勤 介護 15,891人 介護福祉士としての介護業務 教育 15,496人 小中高校などでの教育活動 教授 8,024人 大学などでの教育・研究 宗教 5,130人 外国宗教団体から派遣される宗教活動家 …

让 AI Agent 安全管理 WordPress:一次分类与标签重构中的失败、回滚与最终方法

让 AI Agent 安全管理 WordPress:一次分类与标签重构中的失败、回滚与最终方法 AI Agent 很适合处理重复的 WordPress 管理任务,但“可以调用 API”并不等于“适合自由决定网站结构”。 一次较大规模的分类与标签重构,很容易暴露这个差异。 表面目标可能很简单: 减少过度细分的 Category; 将三级结构压缩为较稳定的两级结构; 清理明显错误的 Tag; 保留真正有检索价值的细粒度主题; 不改变正文、Slug、发布时间和文章状态。 真正困难的部分,却不是 REST API,而是如何把语义决策和机械执行彻底分开。 第一类失败:用字符串代替语义 最早出现的问题,是使用简单字符串规则生成 Tag。 这种方法对长而明确的关键词有时有效,但对短词非常危险。 例如,一个只有几个字母的技术名词,可能恰好出现在: directory operator monitor editor vector 等完全不相关的单词内部。 如果使用: if keyword in body: add_tag() 就会产生大量假阳性。 这类错误的危险之处在于:系统表面上运行成功,API 返回 200,数据库也没有损坏,但网站语义已经被污染。 因此,HTTP 成功不等于任务成功。 第二类失败:过度依赖“语义审计” 发现字符串规则不可靠之后,一个自然的想法是:让模型重新阅读文章,然后判断 Tag 是否应该保留。 …

把临时操作变成可复用能力:为 OpenClaw 设计一个安全的 WordPress 管理 Skill

把临时操作变成可复用能力:为 OpenClaw 设计一个安全的 WordPress 管理 Skill 让 AI Agent 管理 WordPress,看起来只需要“给它一个 API,然后让它发文章”。真正开始长期使用之后,很快会发现事情没有这么简单。 发布文章只是最表层的能力。实际还会遇到分类、标签、草稿、私密文章、Slug、特色图片、批量更新、权限控制、备份、回滚、异常中止等问题。如果这些规则只存在于某一次聊天里,那么下一次任务仍然要重新解释,执行结果也容易漂移。 更可靠的做法,是把已经验证过的规则整理成一个可复用的 Skill。这样,模型负责理解任务,Skill 负责约束行为,底层脚本负责与 WordPress API 交互。 为什么需要 Skill 一次性的提示词适合临时任务,但不适合作为长期运维规范。 例如,同样是“更新一篇文章”,实际可能有完全不同的风险: 修改正文可能意外覆盖原始 HTML; 更新分类时可能把原来的标签一起清空; 重新提交整篇 Post 对象可能改变 Slug、时间或状态; 批量操作时,一篇文章失败可能影响后续数百篇; REST API 中某些统计字段并不能完整反映 private 内容; 分类和标签虽然都属于 taxonomy,但它们的业务语义并不相同。 如果每次都让模型临场决定,很容易出现“技术上能执行,但业务上不应该执行”的情况。 Skill 的价值,就是把这些已经确认的规则固定下来。 一个合适的职责分层 比较稳妥的结构可以分成三层。 第一层是自然语言层。用户只需要描述目标,例如: 将一批文章重新分类,但不要改变正文、Slug 和发布状态。 第二层是 Skill。Skill 明确告诉 Agent: …