Erda MySQL Migration

Erda MySQL 数据库迁移工具

功能

该 Action 用于将代码仓库中的 SQLs 脚本更新到数据库中。 用户需要将用于 migration 的 SQLs 脚本提交到某个目录,并按模块进行分门别类。 如指定 .erda/migrations 目录为存放脚本的目录,那么目录结构为

  1. repo-root:.
  2. ├── .erda
  3. └── migrations
  4. ├── config.yml
  5. ├── module_1
  6. ├── 210101_base.sql
  7. ├── 210101_feature_1.sql
  8. └── 210201_feature_2.sql
  9. └── module_2
  10. ├── 210101_base.sql
  11. └── 210201_some_feature.sql
  12. ├── other_directories
  13. └── dice.yml

其中 module_1 和 module_2 是用户定义的业务模块名,可以自定义。 module 目录下存放 SQLs 脚本。

Erda MySQL Migration Action 会读取所有脚本,将安装到数据库中。

参数说明

  • workdir: 工作目录, 对应仓库根目录, 默认为 ${git-checkout}
  • migrationdir: SQLs 脚本存放目录, 如上文提到的 .erda/migrations
  • database: 库名, 即 MySQL schema 名称
  • mysqllint: 是否要对即将安装的脚本进行规约检查
  • lint_config: 进行规约检查时的规约配置文件, 如果不填则使用默认配置
  • modules: 要执行 migrate 的模块列表, 如果不填则执行 migrationdir 目录下的所有模块

注意事项

  • 该 Action 连接的是 MySQL Addon, 如果 runtime 下没有 MySQL Addon, 会执行失败。
  • 如果第一次使用该 Action 之前, 数据库中已经存在业务表了, 要将这部分业务表结构和初始化数据整理成基线 SQL 脚本并在脚本首行标记# MIGRATION_BASE
  • 指定的 database 如果不存在,该 Action 会自动创建。
  • Action 执行模块内的 SQLs 脚本时,首先执行所有的标记了# MIGRATION_BASE的基线脚本,基线脚本有多个时,按字符序执行;然后执行其他脚本,其他脚本也是按字符序执行。所以为脚本命名时,务必注意按一定的字符序。建议命名方式为日期+数字序号+feature描述。脚本文件名后缀应当为.sql
  • Action 对脚本是增量执行的:每次执行前,都会比对执行记录,只执行上次执行后增量的脚本。执行过的脚本不应当修改内容或重命名,不然 Action 就比对不出哪些被执行过了。Action 的比对方式是在数据库中新增一个执行记录表schema_migration_history,将执行过的文件都记录下来,请不要删除改表。
  • 该 Action 只允许执行 DDL(数据定义语言) 和 DML(数据操作语言),不支持 TCL(事务控制语言) 和 DCL(数据控制语言),所以该 Action 不允许脚本中存在事务控制、授权等操作。

示例配置文件

  1. allowed_ddl: # allowed_ddl 表示是否允许在 migration 中执行该类型的 DDL
  2. create_database_stmt: false
  3. alter_database_stmt: false
  4. drop_database_stmt: false
  5. create_table_stmt: true
  6. drop_table_stmt: false
  7. drop_sequence_stmt: false
  8. rename_table_stmt: false
  9. create_view_stmt: false
  10. create_sequence_stmt: false
  11. create_index_stmt: true
  12. drop_index_stmt: true
  13. lock_tables_stmt: false
  14. unlock_tables_stmt: false
  15. cleanup_table_lock_stmt: false
  16. repair_table_stmt: false
  17. truncate_table_stmt: false
  18. recover_table_stmt: false
  19. flash_back_table_stmt: false
  20. alter_table_option: true
  21. alter_table_add_columns: true
  22. alter_table_add_constraint: true
  23. alter_table_drop_column: false
  24. alter_table_drop_primary_key: false
  25. alter_table_drop_index: true
  26. alter_table_drop_foreign_key: false
  27. alter_table_modify_column: true
  28. alter_table_change_column: true
  29. alter_table_rename_column: false
  30. alter_table_rename_table: false
  31. alter_table_alter_column: true
  32. alter_table_lock: false
  33. alter_table_algorithm: false
  34. alter_table_rename_index: true
  35. alter_table_force: false
  36. alter_table_add_partitions: false
  37. alter_table_coalesce_partitions: false
  38. alter_table_drop_partition: false
  39. alter_table_truncate_partition: false
  40. alter_table_partition: false
  41. alter_table_enable_keys: false
  42. alter_table_disable_keys: false
  43. alter_table_remove_partitioning: false
  44. alter_table_with_validation: false
  45. alter_table_without_validation: false
  46. alter_table_secondary_load: false
  47. alter_table_secondary_unload: false
  48. alter_table_rebuild_partition: false
  49. alter_table_reorganize_partition: false
  50. alter_table_check_partitions: false
  51. alter_table_exchange_partition: false
  52. alter_table_optimize_partition: false
  53. alter_table_repair_partition: false
  54. alter_table_import_partition_tablespace: false
  55. alter_table_discard_partition_tablespace: false
  56. alter_table_alter_check: false
  57. alter_table_drop_check: false
  58. alter_table_import_tablespace: false
  59. alter_table_discard_tablespace: false
  60. alter_table_index_invisible: false
  61. alter_table_order_by_columns: false
  62. alter_table_set_ti_flash_replica: false
  63. allowed_dml: # allowed_dml 表示是否允许在 migration 中执行该类型的 DML
  64. select_stmt: true
  65. union_stmt: true
  66. load_data_stmt: false
  67. insert_stmt: true
  68. delete_stmt: false
  69. update_stmt: true
  70. show_stmt: true
  71. split_region_stmt: false
  72. boolean_field_linter: true # 以系动词开头的字段应当为 boolean(tinyint(1)) 类型, boolean 类型字段命名应当以系动词开头
  73. charset_linter: true # 建表语句应当显示注明 charset 为 utf8mb4
  74. column_comment_linter: true # 列定义应当有 comment
  75. column_name_linter: true # 列命名应当只包含字母数字下划线, 不以数字开头, 两个下划线中不能只有数字, 字母都应当小写
  76. created_at_default_value_linter: true # created_at 默认值应当跟踪当前时间
  77. created_at_exists_linter: true # 表定义时应当有 created_at 列
  78. created_at_type_linter: true # created_at 类型应当为 datetime
  79. destruct_linter: true # 破坏性检查: 如不允许删库、删表、删字段等
  80. float_double_linter: true # 小数不能用 float 或 double 表示,应当用 decimal
  81. foreign_key_linter: true # 不允许使用外键
  82. id_exists_linter: true # 表定义时必须有 id 字段
  83. id_is_primary_linter: true # id 字段必须是主键
  84. id_type_linter: true # id 必须是 bigint 类型
  85. index_length_linter: true # 索引长度检查,单列索引长度不能超过 767 bytes,联合索引长度不能超过 3072 bytes
  86. index_name_linter: true # 唯一索引名以 uk_ 开头 , 普通索引名以 idx_ 开头
  87. keywords_linter: true # 关键字检查,不能使用 MySQL 保留字或关键字作为表名列名
  88. not_null_linter: true # 表定义时所有字段都应当是 not null 的
  89. table_comment_linter: true # 表定义时应当有表 comment
  90. table_name_linter: true # 表名检查,与列名检查规则基本相同
  91. updated_at_exists_linter: true # 表定义时应当有 updated_at 字段
  92. updated_at_type_linter: true # updated_at 字段的类型应当为 datetime
  93. updated_at_default_value_linter: true # updated_at 字段默认值应当跟踪创建时间
  94. updated_at_on_update_linter: true # updated_at 字段应当跟踪更新时间
  95. varchar_length_linter: true # varchar 类型长度不应当超过 5000
  96. complete_insert_linter: true # INSERT 或 REPLACE 语句应当写清列名
  97. manual_time_setter_linter: true # 不允许在 migration 中修改行数据时手动 created_at 或 updated_at 时间