1. 确保安装了 Percona Toolkit
1.在目标环境中,确保系统中已正确安装 Percona Toolkit,尤其是 pt-online-schema-change
工具。
-
数据库用户具备执行外部命令权限。
-
MySQL 配置启用:
log_bin
binlog_format=ROW
- 目标表有主键或唯一索引。
2. 编写 Liquibase 自定义 Change Type 或使用 SQL 执行命令
Liquibase 支持通过 <sql>
标签执行原生 SQL 命令。你可以在 changelog 文件中直接调用 shell 命令来运行 pt-online-schema-change
,例如:
xml
<changeSet id="run-pt-online-schema-change" author="your-name">
<sql>
<![CDATA[
SET @schema_change := CONCAT('pt-online-schema-change --alter "ADD COLUMN new_column INT" D=your_database,t=your_table --execute');
PREPARE stmt FROM @schema_change;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
]]>
</sql>
</changeSet>
注意:上面的示例假设你正在使用 MySQL,并且你的数据库支持执行动态 SQL 和存储过程。
3. 配置 Liquibase 与环境兼容性
由于 pt-online-schema-change
是一个外部工具,需要确保:
- 数据库用户有权限执行外部命令。
- MySQL 的配置允许运行此类操作(如启用
log_bin
、binlog_format=ROW
等)。 - 目标表存在合适的主键或唯一索引以支持该工具。
4. 测试和验证
建议在测试环境中先验证 pt-online-schema-change
的行为是否符合预期,并确保 Liquibase 能够成功调用并完成更改。
5. 可选:封装为自定义扩展
如果你希望更灵活地控制集成方式,可以考虑开发 Liquibase 的自定义扩展(Custom Change),将 pt-online-schema-change
封装成一个可复用的变更类型。
要在 Liquibase 中集成 pt-online-schema-change
(Percona 的在线表结构变更工具),并支持表结构的增删改和索引操作,可以通过以下方式实现。
🧩 使用 Liquibase 调用 pt-online-schema-change
Liquibase 支持通过 <sql>
标签直接执行原生 SQL 或 Shell 命令。以下是一些常见操作示例:
1. 新增列
xml
<changeSet id="add-column" author="example">
<sql>
<![CDATA[
SELECT sys_exec('pt-online-schema-change --alter "ADD COLUMN new_column VARCHAR(255)" D=my_database,t=my_table --execute') INTO @out;
]]>
</sql>
</changeSet>
2. 删除列
xml
<changeSet id="drop-column" author="example">
<sql>
<![CDATA[
SELECT sys_exec('pt-online-schema-change --alter "DROP COLUMN old_column" D=my_database,t=my_table --execute') INTO @out;
]]>
</sql>
</changeSet>
3. 修改列定义
xml
<changeSet id="modify-column" author="example">
<sql>
<![CDATA[
SELECT sys_exec('pt-online-schema-change --alter "MODIFY COLUMN column_name VARCHAR(500)" D=my_database,t=my_table --execute') INTO @out;
]]>
</sql>
</changeSet>
4. 添加索引
xml
<changeSet id="add-index" author="example">
<sql>
<![CDATA[
SELECT sys_exec('pt-online-schema-change --alter "ADD INDEX idx_name (column_name)" D=my_database,t=my_table --execute') INTO @out;
]]>
</sql>
</changeSet>
5. 删除索引
xml
<changeSet id="drop-index" author="example">
<sql>
<![CDATA[
SELECT sys_exec('pt-online-schema-change --alter "DROP INDEX idx_name ON my_table" D=my_database,t=my_table --execute') INTO @out;
]]>
</sql>
</changeSet>
🔌 注意事项
- sys_exec 函数 :MySQL 默认不提供
sys_exec
,你需要安装 MariaDB 的 lib_mysqludf_sys 插件或使用其他方式调用 shell。 - 安全性:确保只在受控环境中运行此类命令,避免安全风险。
- 日志与回滚:建议将执行日志记录下来,并在失败时手动介入处理。
📦 可选:封装为自定义扩展
如果希望更规范地集成,可以开发一个 Liquibase 自定义 Change 类型,例如:
java
public class PtOnlineSchemaChangeChange extends AbstractChange {
private String databaseName;
private String tableName;
private String alterStatement;
// getters/setters
public SqlStatement[] generateStatements(Database database) {
return new SqlStatement[]{
new RawSqlStatement(String.format(
"SELECT sys_exec('pt-online-schema-change --alter \"%s\" D=%s,t=%s --execute') INTO @out;",
alterStatement, databaseName, tableName))
};
}
}
然后在 changelog 中使用:
xml
<changeSet id="custom-pt-change" author="example">
<customChange class="com.example.PtOnlineSchemaChangeChange">
<param name="databaseName" value="my_database"/>
<param name="tableName" value="my_table"/>
<param name="alterStatement" value="ADD COLUMN new_col INT"/>
</customChange>
</changeSet>
✅ 总结
操作类型 | 示例 |
---|---|
新增列 | ADD COLUMN new_column VARCHAR(255) |
删除列 | DROP COLUMN old_column |
修改列 | MODIFY COLUMN column_name VARCHAR(500) |
添加索引 | ADD INDEX idx_name (column_name) |
删除索引 | DROP INDEX idx_name ON my_table |
通过上述方式,你可以灵活地在 Liquibase 中集成 pt-online-schema-change
来实现零停机时间的表结构变更。