Browse Source

数据库快照功能BUG修复

yingp 7 years ago
parent
commit
b1dd3ef7f9
14 changed files with 157 additions and 26 deletions
  1. 9 3
      base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/mapper/CommonMapper.java
  2. 4 3
      base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/mapper/SchemaMapper.java
  3. 28 0
      base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/po/SchemaInfo.java
  4. 12 2
      base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/po/SnapshotData.java
  5. 7 0
      base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/service/SnapshotService.java
  6. 5 0
      base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/service/impl/SnapshotServiceImpl.java
  7. 6 0
      base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/snapshot/event/SnapshotLifecycle.java
  8. 6 1
      base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/snapshot/support/CompanyStrategy.java
  9. 15 8
      base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/snapshot/support/MysqlStrategy.java
  10. 7 1
      base-servers/datacenter/datacenter-server/src/main/resources/application.yml
  11. 2 2
      base-servers/datacenter/datacenter-server/src/main/resources/mapper/CommonMapper.xml
  12. 10 3
      base-servers/datacenter/datacenter-server/src/main/resources/mapper/SchemaMapper.xml
  13. 45 0
      base-servers/datacenter/datacenter-server/src/test/java/com/usoftchina/saas/dc/SnapshotServiceTest.java
  14. 1 3
      framework/core/src/main/java/com/usoftchina/saas/jdbc/DynamicDataSourceContextHolder.java

+ 9 - 3
base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/mapper/CommonMapper.java

@@ -1,5 +1,7 @@
 package com.usoftchina.saas.dc.mapper;
 
+import org.apache.ibatis.annotations.Param;
+
 import java.util.LinkedHashMap;
 import java.util.List;
 
@@ -9,10 +11,14 @@ import java.util.List;
  */
 public interface CommonMapper {
     /**
-     * 传入sql执行查询,取出结果
+     * 传入指定表、字段、值执行查询,取出结果
      *
-     * @param sql
+     * @param tableName
+     * @param columnName
+     * @param columnValue
      * @return
      */
-    List<LinkedHashMap<String, Object>> select(String sql);
+    List<LinkedHashMap<String, Object>> selectByTableAndColumnAndValue(
+            @Param("tableName") String tableName, @Param("columnName") String columnName,
+            @Param("columnValue") Object columnValue);
 }

+ 4 - 3
base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/mapper/SchemaMapper.java

@@ -1,5 +1,6 @@
 package com.usoftchina.saas.dc.mapper;
 
+import com.usoftchina.saas.dc.po.SchemaInfo;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
@@ -13,9 +14,9 @@ public interface SchemaMapper {
      * 按数据库、字段名查找表名
      *
      * @param schema
-     * @param columnName
+     * @param columnNames
      * @return
      */
-    List<String> selectTableNameBySchema(@Param("schema") String schema,
-                                         @Param("columnName") String columnName);
+    List<SchemaInfo> selectSchemaInfoByColumns(@Param("schema") String schema,
+                                             @Param("columnNames") List<String> columnNames);
 }

+ 28 - 0
base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/po/SchemaInfo.java

@@ -0,0 +1,28 @@
+package com.usoftchina.saas.dc.po;
+
+import java.io.Serializable;
+
+/**
+ * @author yingp
+ * @date 2019/1/22
+ */
+public class SchemaInfo implements Serializable{
+    private String tableName;
+    private String columnName;
+
+    public String getTableName() {
+        return tableName;
+    }
+
+    public void setTableName(String tableName) {
+        this.tableName = tableName;
+    }
+
+    public String getColumnName() {
+        return columnName;
+    }
+
+    public void setColumnName(String columnName) {
+        this.columnName = columnName;
+    }
+}

+ 12 - 2
base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/po/SnapshotData.java

@@ -19,16 +19,18 @@ public class SnapshotData {
     private String dcName;
     private String dbName;
     private String tableName;
+    private String columnName;
     private Object data;
 
     public SnapshotData() {
     }
 
-    public SnapshotData(Snapshot snapshot, DataSourceInfo info, String tableName, Object data) {
+    public SnapshotData(Snapshot snapshot, DataSourceInfo info, SchemaInfo schemaInfo, Object data) {
         this.snapshotId = snapshot.get_id();
         this.dcName = info.getDcName();
         this.dbName = info.getDbName();
-        this.tableName = tableName;
+        this.tableName = schemaInfo.getTableName();
+        this.columnName = schemaInfo.getColumnName();
         this.data = data;
     }
 
@@ -72,6 +74,14 @@ public class SnapshotData {
         this.tableName = tableName;
     }
 
+    public String getColumnName() {
+        return columnName;
+    }
+
+    public void setColumnName(String columnName) {
+        this.columnName = columnName;
+    }
+
     public Object getData() {
         return data;
     }

+ 7 - 0
base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/service/SnapshotService.java

@@ -15,6 +15,13 @@ public interface SnapshotService {
      */
     Snapshot save();
 
+    /**
+     * 查找
+     * @param id
+     * @return
+     */
+    Snapshot selectByPrimaryKey(String id);
+
     /**
      * 查找
      * @param page

+ 5 - 0
base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/service/impl/SnapshotServiceImpl.java

@@ -33,6 +33,11 @@ public class SnapshotServiceImpl implements SnapshotService {
         return snapshot;
     }
 
+    @Override
+    public Snapshot selectByPrimaryKey(String id) {
+        return snapshotRepository.findById(id).orElse(null);
+    }
+
     @Override
     public PageInfo<Snapshot> selectByCompany(PageRequest page) {
         Page<Snapshot> snapshots = snapshotRepository.findByCompanyIdOrderByCreateTimeDesc(

+ 6 - 0
base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/snapshot/event/SnapshotLifecycle.java

@@ -12,6 +12,8 @@ import com.usoftchina.saas.dc.service.DataSourceInfoService;
 import com.usoftchina.saas.dc.snapshot.support.MysqlStrategy;
 import com.usoftchina.saas.utils.CollectionUtils;
 import com.usoftchina.saas.utils.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.event.EventListener;
 import org.springframework.scheduling.annotation.Async;
@@ -26,6 +28,8 @@ import java.util.List;
 @Component
 public class SnapshotLifecycle {
 
+    private final Logger logger = LoggerFactory.getLogger(SnapshotLifecycle.class);
+
     @Autowired
     private SnapshotRepository snapshotRepository;
 
@@ -88,6 +92,8 @@ public class SnapshotLifecycle {
     @EventListener(CreateFailedEvent.class)
     public void onCreateFailedEvent(CreateFailedEvent event) {
         Snapshot snapshot = event.getSnapshot();
+        event.getException().printStackTrace();
+        logger.error("failed to create snapshot {}", event.getException(), snapshot.get_id());
         // 解锁
         CompanyLockCache.unlock(snapshot.getCompanyId());
         snapshot.setStatus(Snapshot.Status.FAILED);

+ 6 - 1
base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/snapshot/support/CompanyStrategy.java

@@ -1,9 +1,14 @@
 package com.usoftchina.saas.dc.snapshot.support;
 
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
 /**
  * @author yingp
  * @date 2019/1/21
  */
 public interface CompanyStrategy {
-    String COMPANY_ID_COLUMN = "company_id";
+    List<String> COMPANY_ID_COLUMNS = Collections.unmodifiableList(
+            Arrays.asList("company_id", "companyId"));
 }

+ 15 - 8
base-servers/datacenter/datacenter-server/src/main/java/com/usoftchina/saas/dc/snapshot/support/MysqlStrategy.java

@@ -3,6 +3,7 @@ package com.usoftchina.saas.dc.snapshot.support;
 import com.usoftchina.saas.dc.mapper.CommonMapper;
 import com.usoftchina.saas.dc.mapper.SchemaMapper;
 import com.usoftchina.saas.dc.po.DataSourceInfo;
+import com.usoftchina.saas.dc.po.SchemaInfo;
 import com.usoftchina.saas.dc.po.Snapshot;
 import com.usoftchina.saas.dc.po.SnapshotData;
 import com.usoftchina.saas.dc.repository.SnapshotDataRepository;
@@ -41,14 +42,20 @@ public class MysqlStrategy implements CompanyStrategy {
         DynamicDataSourceContextHolder.set(ds);
         try {
             // 查找所有与公司相关表
-            List<String> tables = schemaMapper.selectTableNameBySchema(ds.getDbRealName(), COMPANY_ID_COLUMN);
-            if (!CollectionUtils.isEmpty(tables)) {
-                tables.parallelStream().forEach(table -> {
-                    // 查找指定表的所有数据
-                    List<LinkedHashMap<String, Object>> data = commonMapper.select(String.format("select * from %s where %s=%s", table, COMPANY_ID_COLUMN, companyId));
-                    if (!CollectionUtils.isEmpty(data)) {
-                        SnapshotData snapshotData = new SnapshotData(snapshot, ds, table, data);
-                        snapshotDataRepository.save(snapshotData);
+            List<SchemaInfo> schemas = schemaMapper.selectSchemaInfoByColumns(ds.getDbRealName(), COMPANY_ID_COLUMNS);
+            if (!CollectionUtils.isEmpty(schemas)) {
+                schemas.parallelStream().forEach(schema -> {
+                    DynamicDataSourceContextHolder.set(ds);
+                    try {
+                        // 查找指定表的所有数据
+                        List<LinkedHashMap<String, Object>> data = commonMapper.selectByTableAndColumnAndValue(
+                                schema.getTableName(), schema.getColumnName(), companyId);
+                        if (!CollectionUtils.isEmpty(data)) {
+                            SnapshotData snapshotData = new SnapshotData(snapshot, ds, schema, data);
+                            snapshotDataRepository.save(snapshotData);
+                        }
+                    } finally {
+                        DynamicDataSourceContextHolder.clear();
                     }
                 });
             }

+ 7 - 1
base-servers/datacenter/datacenter-server/src/main/resources/application.yml

@@ -56,7 +56,7 @@ eureka:
   client:
     registryFetchIntervalSeconds: 5
     serviceUrl:
-      defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@10.1.81.61:8500/eureka/
+      defaultZone: http://${spring.security.user.name}:${spring.security.user.password}@10.1.81.61:8510/eureka/
 server:
   port: 8720
   tomcat:
@@ -84,5 +84,11 @@ mybatis:
   mapper-locations: classpath:mapper/*.xml
   configuration:
     call-setters-on-nulls: true
+feign:
+  hystrix:
+    enabled: true
+ribbon:
+  ReadTimeout: 6000
+  ConnectTimeout: 6000
 auth:
   public-key: auth/pub.key

+ 2 - 2
base-servers/datacenter/datacenter-server/src/main/resources/mapper/CommonMapper.xml

@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
 <mapper namespace="com.usoftchina.saas.dc.mapper.CommonMapper">
-    <select id="select" parameterType="java.lang.String" resultType="java.util.LinkedHashMap">
-        #{sql}
+    <select id="selectByTableAndColumnAndValue" resultType="java.util.LinkedHashMap" statementType="STATEMENT">
+        select * from ${tableName} where ${columnName}=${columnValue}
     </select>
 </mapper>

+ 10 - 3
base-servers/datacenter/datacenter-server/src/main/resources/mapper/SchemaMapper.xml

@@ -1,8 +1,15 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
 <mapper namespace="com.usoftchina.saas.dc.mapper.SchemaMapper">
-    <select id="selectTableNameBySchema">
-        select table_name information_schema.`COLUMNS` where table_schema=#{schema,jdbcType=VARCHAR}
-        and column_name=#{columnName,jdbcType=VARCHAR}
+    <resultMap id="BaseResultMap" type="com.usoftchina.saas.dc.po.SchemaInfo">
+        <result column="table_name" jdbcType="VARCHAR" property="tableName"/>
+        <result column="column_name" jdbcType="VARCHAR" property="columnName"/>
+    </resultMap>
+    <select id="selectSchemaInfoByColumns" resultMap="BaseResultMap">
+        select table_name,column_name from information_schema.`COLUMNS` where table_schema=#{schema,jdbcType=VARCHAR}
+        and column_name in
+        <foreach collection="columnNames" index="index" item="columnName" open="(" separator="," close=")">
+          #{columnName}
+        </foreach>
     </select>
 </mapper>

+ 45 - 0
base-servers/datacenter/datacenter-server/src/test/java/com/usoftchina/saas/dc/SnapshotServiceTest.java

@@ -0,0 +1,45 @@
+package com.usoftchina.saas.dc;
+
+import com.usoftchina.saas.context.BaseContextHolder;
+import com.usoftchina.saas.dc.po.Snapshot;
+import com.usoftchina.saas.dc.service.SnapshotService;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.MethodSorters;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.test.context.junit4.SpringRunner;
+
+/**
+ * @author yingp
+ * @date 2019/1/22
+ */
+@RunWith(SpringRunner.class)
+@SpringBootTest
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class SnapshotServiceTest {
+
+    @Autowired
+    private SnapshotService snapshotService;
+
+    @Test
+    public void testA_save() throws Exception {
+        BaseContextHolder.setCompanyId(134);
+        BaseContextHolder.setUserId(41);
+        Snapshot snapshot = snapshotService.save();
+        printStatus(snapshot);
+    }
+
+    private void printStatus(Snapshot snapshot) throws Exception {
+        while(true) {
+            snapshot = snapshotService.selectByPrimaryKey(snapshot.get_id());
+            System.out.println("Status: " + snapshot.getStatus());
+            if (snapshot.getStatus() == Snapshot.Status.SUCCESS ||
+                    snapshot.getStatus() == Snapshot.Status.FAILED) {
+                break;
+            }
+            Thread.sleep(1000);
+        }
+    }
+}

+ 1 - 3
framework/core/src/main/java/com/usoftchina/saas/jdbc/DynamicDataSourceContextHolder.java

@@ -1,13 +1,11 @@
 package com.usoftchina.saas.jdbc;
 
-import com.alibaba.ttl.TransmittableThreadLocal;
-
 /**
  * Created by Pro1 on 2017/7/27.
  */
 public class DynamicDataSourceContextHolder {
 
-    private static final ThreadLocal<String> contextHolder = new TransmittableThreadLocal<>();
+    private static final ThreadLocal<String> contextHolder = new InheritableThreadLocal<>();
 
     public static void set(String dataSource) {
         contextHolder.set(dataSource);