Преглед изворни кода

liquibase多数据源处理

yuhongqi пре 1 недеља
родитељ
комит
b8807d43f6

+ 38 - 0
fs-service/src/main/java/com/fs/framework/liquibase/DataSourceAvailabilityValidator.java

@@ -0,0 +1,38 @@
+package com.fs.framework.liquibase;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+/**
+ * 校验目标数据源是否可用。
+ */
+public class DataSourceAvailabilityValidator {
+
+    private static final Logger log = LoggerFactory.getLogger(DataSourceAvailabilityValidator.class);
+
+    public void assertAvailable(DataSource dataSource, String targetName, String beanName) {
+        if (dataSource == null) {
+            throw new IllegalStateException(buildErrorMessage(targetName, beanName));
+        }
+        try (Connection connection = dataSource.getConnection()) {
+            if (connection.isClosed()) {
+                throw new IllegalStateException(buildErrorMessage(targetName, beanName));
+            }
+            try (Statement statement = connection.createStatement()) {
+                statement.execute("SELECT 1");
+            }
+        } catch (SQLException ex) {
+            log.error("Liquibase 目标 [{}] 数据源 {} 连接失败", targetName, beanName, ex);
+            throw new IllegalStateException(buildErrorMessage(targetName, beanName), ex);
+        }
+    }
+
+    public static String buildErrorMessage(String targetName, String beanName) {
+        return "未检测到可用数据源: target=" + targetName + ", bean=" + beanName;
+    }
+}

+ 47 - 0
fs-service/src/main/resources/db/changelog/DATASOURCE-MARK.md

@@ -0,0 +1,47 @@
+# Changelog 数据源目录标记
+
+按**目录**标记 changelog 归属的数据源。启动时 `LiquibaseStartupGate` 会:
+
+1. 读取 `fs.liquibase.targets`
+2. 检查对应 DataSource Bean 是否存在且可连接
+3. 检查该目标的 master changelog 文件是否存在
+4. 在**该数据源**上 audit → update → 写入各自库的 `DATABASECHANGELOG` / `database_init_meta`
+
+## 目录约定
+
+| 路径 | 数据源 Bean | 说明 |
+|------|-------------|------|
+| `db/changelog/` 根下(除下方子目录) | `masterDataSource` | **主库**。现有 baseline/changes/table/dictData 均属主库,路径勿随意搬迁(已执行过的 changeset 文件路径不能改) |
+| `db/changelog/sop/` | `sopDataSource` | **SOP 库**。仅放 SOP 库 DDL/DML |
+| `db/changelog/<其他>/` | 对应 Bean(需在 yml targets 注册) | 扩展其他库时新建同名一级目录,并在 `fs.liquibase.targets` 增加一项 |
+
+## 文件归属速查
+
+### 主数据源(master)
+
+- `db/changelog/db.changelog-master.xml`
+- `db/changelog/baseline/**`
+- `db/changelog/changes/**`
+- `db/changelog/table/**`
+- `db/changelog/dictData/**`
+- `db/changelog/draft/**`(草稿,不执行)
+
+### SOP 数据源(sop)
+
+- `db/changelog/sop/db.changelog-master.xml`
+- `db/changelog/sop/baseline/**`
+- `db/changelog/sop/changes/**`
+- `db/changelog/sop/draft/**`(草稿,不执行)
+
+## 新增 SOP 变更步骤
+
+1. 在 `db/changelog/sop/changes/` 新建 `YYYYMMDD-模块-简述.sql`
+2. 在 `db/changelog/sop/db.changelog-master.xml` 末尾 `include`
+3. 确认启动模块存在 `sopDataSource` Bean
+4. 重启应用,在 **SOP 库** 查 `DATABASECHANGELOG`
+
+## 注意
+
+- 主库 MD5 扫描会自动排除 `sop` 等已注册的其他目标子目录,避免互相污染
+- 某模块没有装配 `sopDataSource` 时,SOP 目标 `required: false` 会跳过,不影响启动
+- ClickHouse 等非 MySQL 库暂不要挂到本门禁(SQL 方言与元数据表不同)

+ 6 - 0
fs-service/src/main/resources/db/changelog/sop/baseline/baseline.sql

@@ -0,0 +1,6 @@
+--liquibase formatted sql
+
+--changeset yhq:sop-baseline-v1.0.0
+--comment 标记 SOP 库 Liquibase 接入基线,不执行业务 DDL
+--tagDatabase sop-baseline-v1.0.0
+SELECT 1;

+ 15 - 0
fs-service/src/main/resources/db/changelog/sop/baseline/init-meta.sql

@@ -0,0 +1,15 @@
+--liquibase formatted sql
+
+--changeset yhq:sop-database-init-meta
+--preconditions onFail:MARK_RAN
+--precondition-sql-check expectedResult:0 SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'database_init_meta'
+CREATE TABLE database_init_meta (
+    id              BIGINT       NOT NULL AUTO_INCREMENT COMMENT '主键',
+    bundle_md5      VARCHAR(32)  NOT NULL COMMENT 'changelog bundle MD5(32位小写)',
+    bundle_version  VARCHAR(64)  NULL     COMMENT '可选:Git tag / 发布版本号',
+    file_count      INT          NOT NULL COMMENT '参与计算的 changelog 文件数',
+    last_module     VARCHAR(64)  NULL     COMMENT '最后一次成功校验的启动模块',
+    update_time     DATETIME     NOT NULL COMMENT 'MD5 更新时间',
+    remark          VARCHAR(255) NULL     COMMENT '备注',
+    PRIMARY KEY (id)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='Liquibase changelog bundle MD5 元数据';

+ 0 - 0
fs-service/src/main/resources/db/changelog/sop/changes/.gitkeep


+ 17 - 0
fs-service/src/main/resources/db/changelog/sop/db.changelog-master.xml

@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<databaseChangeLog
+        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:schemaLocation="
+          http://www.liquibase.org/xml/ns/dbchangelog
+          http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd">
+
+    <!-- SOP 数据源 changelog:仅在此目录下的文件会在 sopDataSource 执行 -->
+    <include file="baseline/init-meta.sql" relativeToChangelogFile="true"/>
+    <include file="baseline/baseline.sql" relativeToChangelogFile="true"/>
+
+    <!-- 新增 SOP 库变更示例:
+    <include file="changes/YYYYMMDD-模块-简述.sql" relativeToChangelogFile="true"/>
+    -->
+
+</databaseChangeLog>

+ 0 - 0
fs-service/src/main/resources/db/changelog/sop/draft/.gitkeep