简介Liquibase 4.31.0 的 Windows 版本面向需要在 Windows 环境下管理数据库变更的开发人员、DBA 与运维工程师。Liquibase 作为成熟的数据库版本控制工具能够以声明方式定义结构变更并在多环境间保持一致特别适合敏捷开发与持续集成/持续部署流程。压缩包共包含 134 个文件整体约 333.42MB其中 yaml 文件用于变更集与配置定义jar 为运行所需依赖库txt 提供说明文档conf/flow/bat 等涵盖启动脚本、环境配置与自动化流程示例。用户可从中获得完整的运行环境、示例配置与快速入门指南包括启动脚本、lib 依赖库、examples 示例目录及变更日志能够快速上手并实际管理 MySQL、PostgreSQL、Oracle、SQL Server 等多种数据库的版本变更。同时包内附带的说明文档和配置示例也有助于理解 Changelog 机制、回滚操作以及多环境一致性管理显著提升数据库开发和维护效率。目前已有 118 人学习下载。1. Liquibase 4.31.0 的 Windows 版本先解决“为什么会跑不起来”再谈迁移Liquibase 4.31.0 的 Windows 版本听起来只是把一个 Java 数据库迁移工具换了个打包后缀但真正在 Windows 上落地时卡住的往往不是 SQL 和 changelog而是路径分隔符、JAVA_HOME、控制台代码页和 PowerShell 的转义规则。这篇文章不打算把官网文档复述一遍我会从装机、配置、跑通 update一路拆到回滚和发布前校验尽量把你大概率会撞上的坑提前标出来。适合刚接手数据库变更管理、被迫在 Windows 开发机上跑 Liquibase 的工程师——尤其是那种以前只用过 Flyway现在被项目历史逼着切换工具的人。2. Windows 包的真实结构与运行前检查把 JDK 和 PATH 当作第一道关卡2.1 这版工具在 Windows 下的形态一个批处理壳加上一堆 jarLiquibase 4.31.0 的 Windows 发行包本质上不是一个原生的 Windows 程序而是一个 ZIP 解压后的目录。里面除了LICENSE、internal这些配置文件之外最关键的其实是两个可执行入口liquibaseLinux/macOS 用的 shell 脚本和liquibase.batWindows 用的批处理。很多第一次用的人会直接双击liquibase.bat发现窗口闪了一下就没了然后误以为工具本身有问题。实际原因是这个批处理需要参数没有参数的时候它会把 usage 输出打印到控制台窗口关闭后什么都看不到。更准确地说liquibase.bat只是外层包装真正干活的是internal目录下的liquibase.jar和lib目录里的一堆依赖包。Liquibase 官方要求最低 Java 8但在 4.31.0 这个时间点上JDK 17 是更稳妥的选择因为高版本在 TLS 协议、加密算法和部分数据库驱动上兼容性更好。我在 Windows 11, version 26H2 和 Windows Server 2019 上都跑过这个版本行为基本一致。唯一需要额外留意的是 32 位 JDK 和 64 位 JDK 的差别Liquibase 本身不挑位数但如果你在 64 位系统上装了 32 位 JDK个别数据库驱动的 native 部分会出问题。所以安装前先跑一下java -version确认输出里是 64-Bit。2.2 安装前检查JDK 版本、环境变量与系统兼容性在解压之前先把环境检查做了比装完再排查省时间。我一般按下面这个顺序来检查 Java 是否可用java -version。如果提示java is not recognized那就得先装 JDK或者把 JDK 的 bin 目录加进 PATH。确认JAVA_HOME是否设置echo %JAVA_HOME%。Liquibase 的批处理脚本会优先找JAVA_HOME找不到时也可能直接从 PATH 里找java。为了少踩坑我建议直接把JAVA_HOME配好指向 JDK 安装根目录不要带bin。检查计划解压的目录有没有写入权限。Liquibase 运行时会向当前工作目录或用户目录写内部临时文件如果你把它解压到了C:\Program Files下又没有以管理员身份运行后面很容易遇到权限不足。确认 Windows 的 PATH 里有没有跟liquibase同名或相似的可执行文件。搜索路径里如果存在其他工具的liquibase.exe你输入liquibase时执行的就不一定是这版工具。这些检查做完后再考虑系统兼容性。Windows 7 SP1 已经是很老的系统我不建议在它上面跑 4.31.0因为新版依赖的一些安全协议在旧系统上默认关闭Windows 10 1903 以上、Windows 11 以及 Windows Server 2019 都问题不大。真要在老系统上跑你大概率还要处理 TLS 和 JDK 版本的双重兼容问题性价比很低。2.3 跑通最小命令解压、配环境变量、查看版本环境检查过了接下来就是安装动作。假设我把压缩包解压到了D:\tools\liquibase-4.31.0那我会按下面的步骤操作。cd D:\tools\liquibase-4.31.0 set JAVA_HOMEC:\Program Files\Java\jdk-17 set PATH%JAVA_HOME%\bin;%PATH% .\liquibase.bat --version第一段先用cd切到解压目录第二段临时设置JAVA_HOME第三段把 JDK 的 bin 加到当前会话的 PATH最后执行liquibase.bat。这段逻辑里值得注意的有三点set在 CMD 里是临时环境变量只对当前窗口有效关掉就失效路径里如果含空格必须用双引号比如set JAVA_HOMEC:\Program Files\Java\jdk-17在某些写法下会把引号也存进变量所以我更推荐不带引号写在后面靠前面的cd和 PATH 来规避空格问题最后执行的.bat不能省略因为 Windows 不会默认把当前目录加入搜索路径。如果执行后能看到类似Liquibase Version: 4.31.0的输出说明工具本身没问题。有些人会尝试用 PowerShell 来跑那就写成.\liquibase.bat --version注意前面的.\不能少这是 PowerShell 调用当前目录下可执行文件的固定语法。如果站在 CMD 里直接输入liquibase --version还提示找不到命令说明你还没有把D:\tools\liquibase-4.31.0加到系统 PATH而不是 Liquibase 没装好。3. 用 properties 与 changelog 让第一次 update 在 Windows 上落地3.1 liquibase.properties 的 Windows 路径写法与关键项Liquibase 的配置方式有两种命令行参数或者liquibase.properties属性文件。我习惯先在项目根目录放一个属性文件因为它能让所有人都看到统一配置也方便维护。Windows 上最容易翻车的是路径写法因为属性文件的changeLogFile如果用反斜杠会被当作转义字符处理。driver: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/order_db?useUnicodetruecharacterEncodingutf8useSSLfalseallowPublicKeyRetrievaltrue username: root password: 123456 changeLogFile: db/changelog/db.changelog-master.xml searchPath: D:/workspace/order-service这里强调几个参数。url里的参数如果包含在 Windows 的 CMD 里不会有什么问题因为配置文件不是命令行但在 PowerShell 里如果你把整个 URL 写在命令行参数中会被当成语句分隔符所以我会尽量避免命令行传 URL全部放进 properties。searchPath用正斜杠这是 Windows 上最稳妥的写法反斜杠在 Java 属性文件里会被解析成转义字符像\u这类意外组合尤其危险。推荐把 changelog 根路径统一放到一个固定目录这样不管你从哪个工作目录启动Liquibase 都能找到文件。还有一个容易忽略的点属性文件编码默认是 ISO-8859-1如果你在里面写了中文注释保存时用的是 UTF-8加载后就是乱码甚至可能导致读取失败。我一般要么全部用英文注释要么在 Java 17 下用liquibase --defaults-filepath时先确认文件编码建议直接保存为 UTF-8 无 BOM 格式。3.2 第一个 XML changelog建表变更集的完整写法changelog 是 Liquibase 的核心它记录了对数据库做的每一次变更。第一次跑通不需要写复杂的逻辑一个建表变更集就够。?xml version1.0 encodingUTF-8? databaseChangeLog xmlnshttp://www.liquibase.org/xml/ns/dbchangelog xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsd changeSet id1 authordev createTable tableNameperson column nameid typeint autoIncrementtrue constraints primaryKeytrue nullablefalse/ /column column namename typevarchar(255) constraints nullablefalse/ /column column namecreated_at typedatetime/ /createTable /changeSet /databaseChangeLog这个文件里值得说明的是changeSet的id和author组合。Liquibase 会把这个组合作为一个唯一标识存入数据库的DATABASECHANGELOG表以后再执行时会根据这个组合判断是否已经运行过。id不一定非得是数字用功能模块加序号更好比如order-001。表字段里autoIncrement是数据库侧的自增语法不同数据库生成的 DDL 不一样比如 MySQL 是AUTO_INCREMENTPostgreSQL 是SERIAL。在 XML 中写typeint是通用的Liquibase 会负责翻译成目标数据库的类型。另一个容易踩的是created_at的默认值。如果你希望它自动取当前时间可以加defaultValueComputedCURRENT_TIMESTAMP。在编写时要小心 XML 里的特殊字符比如和它们必须转义成amp;和lt;。我见过有人在 default 值里写CURRENT_TIMESTAMP没问题但写func(NOW())时漏了转义导致整个 XML 解析失败。3.3 数据库连接驱动放在哪、URL 怎么写、端口怎么验在 Windows 上数据库连接不上是最高频的失败点而且很多情况下不是 Liquibase 的问题而是驱动和网络环境的问题。驱动 jar 一般放在两个地方Liquibase 安装目录下的lib文件夹或者通过--classpath参数指定。放lib是最省事的做法但升级 Liquibase 时容易把驱动丢在旧目录里。我更喜欢把驱动 jar 放进项目下的lib目录用--classpath指定。cd D:\workspace\order-service D:\tools\liquibase-4.31.0\liquibase.bat ^ --classpathD:\tools\mysql-connector-j-8.0.33.jar ^ --defaults-fileliquibase.properties ^ update这段命令里^是 CMD 的换行符PowerShell 里对应的是反引号。此处我先指定--classpath再指定--defaults-file。为什么不用把驱动放进lib的懒人方案因为项目成员各自机器上的 Liquibase 版本可能不同如果驱动版本跟随 Liquibase 目录走换版本时要重新放放到项目里并写进启动脚本至少保证同一个项目里大家用的是同一个驱动 jar。URL 写法也要认真检查。MySQL 5.7 和 MySQL 8 的驱动类名不一样旧的com.mysql.jdbc.Driver在 MySQL Connector/J 8.x 中已经废弃用com.mysql.cj.jdbc.Driver更稳。URL 里我加了useSSLfalse和allowPublicKeyRetrievaltrue这两个参数在本地开发环境很关键MySQL 8 默认需要公钥检索不加会报Public Key Retrieval is not allowed。characterEncodingutf8则保证中文写入不乱码。如果连接失败先不要急着调 Liquibase先用 Windows 自带的工具确认端口通不通netstat -ano | findstr :3306这个命令会列出监听 3306 端口的进程及其 PID。如果看不到输出说明 MySQL 没监听或者端口被别的东西占了。再用tasklist | findstr 3306能确认进程名。Windows 防火墙也会拦截本地回环地址但通常 localhost 不会被拦如果你用的是远程数据库服务器就要检查防火墙入站规则而不是反复重试。4. PowerShell 与 CMD 下的常用 Liquibase 命令状态、更新和回滚的运行姿势4.1 在 PowerShell 里加引号避开$和分号的坑团队里有人用 CMD有人用 PowerShell同一个命令在两个环境下的行为可能不一样。最经典的坑是 PowerShell 对$和;的解释。$在 PowerShell 里是变量引用符号如果你在命令行中直接写 changelog 参数值比如某个 include 路径里含$PowerShell 会把后面的内容当变量名替换掉。还有一个是 URL 中的在 CMD 里不会特殊处理在 PowerShell 里会被当作语句分隔符导致命令被截断。所以在 PowerShell 里执行 Liquibase 时我习惯把参数值用单引号包住。单引号在 PowerShell 里不做变量展开是最安全的转义方式。cd D:\workspace\order-service D:\tools\liquibase-4.31.0\liquibase.bat --defaults-fileliquibase.properties update是 PowerShell 的调用操作符后面跟路径字符串调用脚本。单引号包裹了批处理路径和参数值防止空格和特殊字符干扰。这个写法比直接输入.\liquibase.bat更通用因为你可能不在 Liquibase 所在目录下。要注意的是PowerShell 执行策略可能阻止.bat文件运行如果报错提示对脚本运行被禁用可以用Set-ExecutionPolicy -Scope Process Bypass临时解除但没必要改系统全局策略。另一个实际经验是不要把update塞在 PowerShell 脚本里直接跑。因为一旦中途失败PowerShell 默认不会保留完整的退出码后续脚本判断会失真。要用的话至少加上$LASTEXITCODE检查。4.2 用 update 把变更集落到 MySQL再用 status 确认第一次执行 update 之前最好先看一眼当前状态。Liquibase 有个status命令它不会修改数据库只是列出还有哪些变更集没有执行。如果你把--verbose加上还能看到具体文件的路径和变更集的 id。D:\tools\liquibase-4.31.0\liquibase.bat --defaults-fileliquibase.properties status --verbosestatus 命令适用于确认我们的预期它应该显示 changelog 中定义但尚未执行的changeSet。如果它显示全部已执行那你可能就是连到了已经被别人跑过一遍的数据库。这事我在项目里遇到过不止一次新同事连了同一个共享开发库执行 update 后以为自己的变更集生效了实际上里面的表早就存在且数据被改动闹出了不少误会。确认状态没问题后再执行 updateD:\tools\liquibase-4.31.0\liquibase.bat --defaults-fileliquibase.properties update执行完后我不建议只看命令提示的Successfully applied就收工。我会到 MySQL 客户端里查两张表DATABASECHANGELOG和业务表。前者记录执行历史后者验证业务结构是否生效。SELECT id, author, filename, orderexecuted, dateexecuted FROM DATABASECHANGELOG ORDER BY orderexecuted DESC LIMIT 5; SHOW CREATE TABLE person;第一段 SQL 看最近的执行记录重点看filename是不是你当前配置文件指定的 changelog 路径。如果filename是反斜杠路径说明 changelog 里 include 的路径写法和匹配方式有差异Liquibase 在 Windows 上会把路径规范化尽量让所有 changelog 都用正斜杠。第二段SHOW CREATE TABLE直接看建表语句确认类型、默认值、字符集都符合预期。这一步虽然多花两分钟但能避免“update 成功但表结构不对”的假象。4.3 rollback 回滚的正确姿势该在 changeSet 上补两个属性数据库迁移一定会有后悔的时候。Liquibase 的 rollback 不是简单地把变更集撤销而是执行你在 changelog 里定义的回滚逻辑。如果你没有定义回滚逻辑默认值行为是尝试自动推断比如建表会自动推断成删表加列会推断成删列。这种推断在简单场景下有效但在复杂的业务逻辑中经常出错比如你给一张表加了一列同时在数据里更新了历史值自动推断的回滚只会删列不会恢复被改的数据。所以在写 changeSet 时我会把回滚语句显式写出来。以刚才的createTable为例回滚就是删表changeSet id1 authordev createTable tableNameperson column nameid typeint autoIncrementtrue constraints primaryKeytrue nullablefalse/ /column column namename typevarchar(255) constraints nullablefalse/ /column /createTable rollback DROP TABLE person; /rollback /changeSetrollback里写的是普通的 SQL 语句不需要再嵌套任何 Liquibase tag。这段回滚语句会被记录到 DATABASECHANGELOG 中当执行 rollback 时Liquibase 会找到需要回滚的 changeSet先执行rollback块的内容再把这条记录从历史表中移除。这里有个关键点回滚时指定的是回滚到哪个 Tag或者回滚步数而不是直接指定某一个变更集。比如你想撤销最近一次变更集可以这样D:\tools\liquibase-4.31.0\liquibase.bat --defaults-fileliquibase.properties rollback-count 1rollback-count 1表示回滚最近 1 个变更集。它按照 DATABASECHANGELOG 表中记录的orderexecuted倒序找到最近一条然后执行对应的 rollback。如果你希望回滚到某个固定状态可以在执行 update 前先打一个 tag回滚时用rollback tag-name。在 Windows 上跑 rollback 还要注意一个文件锁定问题如果你在 Excel 或编辑器里打开了 changelog 文件然后执行 rollback虽然不会影响 SQL 执行但如果你在回滚过程中输出了日志文件而在资源管理器里占用着那个日志文件命令反而会失败。这个坑我后面单独说。5. Windows 上 Liquibase 的避坑清单5 个高发问题与排查路径5.1 命令行找不到 liquibasePATH、批处理策略与确认顺序现象在 CMD 或 PowerShell 中输入liquibase --version系统提示liquibase is not recognized as an internal or external command但进入解压目录后执行.\liquibase.bat --version却能正常工作。原因没有把 Liquibase 的安装目录加入系统 PATH或者加入后当前终端没有重新加载环境变量。Windows 的 PATH 修改后需要新开一个 CMD 窗口才生效如果你是在已经开着的 PowerShell 里改的需要关闭重开。还有一种少见的情况是Path被写成了PATHWindows 的注册表里对变量名不区分大小写但某些系统配置会出问题。解决确认目录正确后把D:\tools\liquibase-4.31.0加入系统 PATH然后新开终端。如果你不想改系统环境变量就在当前会话里临时追加set PATH%PATH%;D:\tools\liquibase-4.31.0。执行前先where liquibase看看命令被解析到了哪个路径如果输出里有其他项目的同名 exe说明 PATH 顺序有问题把 Liquibase 目录放到最前面即可。5.2 控制台和 changelog 中文乱码代码页、UTF-8 与 BOM 之争现象执行liquibase update时打印的日志里中文变成??或者各种乱码changelog 里写的中文注释在读取时也变成乱码甚至 XML 解析直接报错。原因Windows 控制台默认代码页通常是 936GBK或 437MS-DOS而 Liquibase 输出和 changelog 文件普遍是 UTF-8。当输出里的 Unicode 字符无法在当前代码页下表示时就会变成问号。另外changelog 文件如果是 UTF-8 带 BOM 格式有些版本会把 BOM 当作文件内容的一部分导致 XML 解析第一行报错。解决在执行 Liquibase 前先切代码页CMD 里执行chcp 65001PowerShell 里可以执行[Console]::OutputEncoding [System.Text.Encoding]::UTF8。changelog 文件一律保存为 UTF-8 无 BOM 格式如果你用 Windows 自带的记事本编辑另存为时选择“UTF-8”即可它默认不带 BOM。liquibase.properties 里如果有中文注释同样需要转成 UTF-8 无 BOM。如果实在无法统一编码可以把非必要的中文注释全部去掉减少干扰源。5.3 数据库连不上驱动缺失、端口占用与安全日志的误导现象执行 update 后报Connection could not be created或者Cannot load driver class: com.mysql.cj.jdbc.Driver。检查网络和防火墙后MySQL 服务明明是正常的但 Liquibase 就是连不上。原因最常见的是驱动 jar 没有被加载。Liquibase 自身不绑定任何数据库驱动需要你把对应的 JDBC jar 放到 classpath。Linux 上如果驱动版本过旧报错信息往往还会提示Public Key Retrieval is not allowed但 Windows 上容易把注意力引到防火墙。另一个原因是端口被占用比如你在 Windows 上同时装了多个 MySQL 实例3306 被旧实例占了新实例实际监听的是 3307。解决先用netstat -ano | findstr :3306确认监听端口再确认 URL 里的端口到底对不对。然后在命令行里显式加--classpath不要依赖环境变量里的 CLASSPATH因为 Windows 的全局 CLASSPATH 会引入很多无关 jar反而掩盖真正的问题。如果你用的是 MySQL 8驱动版本至少 8.0.33并在 URL 里带上allowPublicKeyRetrievaltrue。最后提醒一句数据库登录失败时不要直奔 Windows 安全日志查看那是操作系统层面的登录审计MySQL 的连接失败要去看 MySQL 自身的 error log一般位于 MySQL 数据目录下的.err文件。5.4 权限和文件占用不要轻易用管理员也别把工作目录选错现象以管理员身份运行 CMD执行liquibase update时提示Access is denied或者工具在运行到一半时突然报文件锁定错误。还有个经典现象右键“以管理员身份运行”后工作目录变成了C:\Windows\System32Liquibase 在默认路径下找不到 liquibase.properties于是报错。原因Liquibase 进程会向当前工作目录或用户主目录写入内部缓存、日志和临时文件。如果工作目录是System32普通用户没有写入权限如果你用管理员运行又会产生权限边界不一样的问题。另一种是你在编辑器中打开了 changelog 或日志文件文件被占用后 Liquibase 无法覆盖。解决不要在Program Files或System32下跑 Liquibase。我一般把 Liquibase 解压到D:\tools把项目也放在D:\workspace下始终用普通用户权限执行。如果工作目录里没有liquibase.properties用cd先切到项目根目录再用绝对路径调用批处理。文件占用的问题涉及到习惯写 changelog 时用 VS Code 可以但执行命令前把所有相关文件关闭。如果遇到文件锁可以用 PowerShell 的Get-Process | Where-Object {$_.Path -like *liquibase*}查看残留进程先杀掉再执行。5.5 路径分隔符、空格与换行符让 Windows 和 XML 和平相处现象changelog 里 include 了其他文件执行时报文件不存在或者把changeLogFile写成db\changelog\db.changelog-master.xml后Liquibase 在解析时把\c当作转义字符结果找不到路径。还有一种现象是从 Linux 仓库克隆下来的 changelog 在 Windows 上运行时报Unexpected token。原因都是文本和路径的兼容问题。Java 属性文件中\是转义字符所以db\changelog里的\c被吃掉了一部分。XML 文件头部的换行符如果从 LF 变成 CRLF本身没问题但使用某些文本编辑器时不注意编码会导致 BOM 混入 XML 声明解析器直接报错。解决所有 Liquibase 接触到的路径统一用正斜杠/包括 properties 里的changeLogFile、XML 里的include路径、命令行里的--classpath。换行符方面changelog 文件用 LF 还是 CRLF 都行但不要混用。如果真出了解析问题用 VS Code 打开文件查看右下角编码和行尾类型统一成 UTF-8 和 LF。这条经验不玄学属于遇到一次能记住很久的坑——我在某图像处理 Demo 项目里就因为一个 include 路径用了反斜杠排查了将近半天最后改成正斜杠一行解决。6. 发布前的最后一步用 dry-run 与 checks 在 Windows 上做可回滚验证6.1 先跑 update-sql再跑 status让变更集备份发送在正式对共享数据库执行 update 之前我习惯先跑update-sql把将要执行的 DDL/DML 完整输出到一个 SQL 文件。这个动作在 Windows 上尤其有用因为你可以提前检查生成的语句是否符合当前数据库版本而不需要真的去执行。D:\tools\liquibase-4.31.0\liquibase.bat --defaults-fileliquibase.properties update-sql update.sqlupdate-sql会连接数据库、读取 DATABASECHANGELOG 表、计算待执行的变更集但不会提交任何变更。它输出的是一个 SQL 脚本适合给 DBA 审查也适合在出问题时做人工干预。重定向到update.sql后我会用 VS Code 打开文件检查三件事第一语句结尾是否有分号第二表名有没有带上奇怪的数据库前缀第三中文默认值有没有乱码。确认无误后再执行liquibase update。最近我还会顺手执行status --verbose看一遍未应用变更集的完整清单这样能排除“以为自己 update 了其实还没有”的尴尬。如果发现 update 之后 DATABASECHANGELOG 记录和实际业务表对不上可以用clear-checksums重新生成校验值但那是另一套排错逻辑这里先记住顺序先update-sql再 review最后 update。6.2 checks 命令检查增量变更集的常规问题Liquibase 4.31.0 内置了checks命令可以扫描 changelog 中存在的常见问题。它有点像静态代码检查会检测你是否在变更集里做了临时表的修改、是否用了DDL却缺少回滚逻辑等。Windows 上跑 checks 有一个优势你不需要额外安装任何依赖直接用 bat 调用即可。D:\tools\liquibase-4.31.0\liquibase.bat --defaults-fileliquibase.properties checks --help这个命令会列出所有可用的 check 项名称比如checkChangeSetRequiresRollback、checkUnused等。实际跑的时候我一般只针对当前项目配置开启少量规则避免默认的几十个规则输出噪音过大。你可以先跑checks再根据提示调整配置。需要留意的是checks的规则是基于配置文件的如果项目里没有liquibase.checks-settings.conf它会用默认配置那结果不一定适合你的开发阶段。另一个推荐的静态校验方法是给update加--dry-run参数。update --dry-run不会真实变更数据库只打印执行计划在 CI 上跑它相当于给发布前加了一道安全门。Windows 上执行时可以把输出重定向到日志文件避免控制台乱码干扰。6.3 把日志写进文件避免控制台中文乱码影响排错最后这个技巧是我从一次线上事故中总结出来的。当时我在 Windows 服务机上跑 Liquibase控制台中文乱码排错时把日志复制到文本编辑器里又变成了更大的乱码最后只能靠英文关键词猜问题。从那之后我执行命令时都会把日志输出到文件D:\tools\liquibase-4.31.0\liquibase.bat --defaults-fileliquibase.properties update update-run.log 2121把标准错误也重定向到同一个日志文件这样无论界面怎么乱码文件里的内容都是原始的 UTF-8 字节流。之后用 VS Code 打开日志文件如果显示正常说明代码页没问题如果文件里本来就是乱码那问题出在 changelog 或 properties 的编码上而不是控制台。我个人的习惯是每次版本发布前在项目目录下建一个liquibase-release文件夹把update.sql、update-run.log、checks-result.txt放进去和这次发布绑在一起。万一线上要回滚直接参考当时的日志和 SQL 脚本比翻聊天记录靠谱得多。这套流程在 Windows 上跑顺了之后换到 Linux 上也就是把liquibase.bat换成liquibase而已数据库变更管理本身没有平台隔阂。希望这些经验能帮到你。本文还有配套的精品资源点击获取