Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

undo_log table check optimize #6030

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion changes/en-us/2.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ The version is updated as follows:
- [[#5951](https://github.com/seata/seata/pull/5951)] remove un support config in jdk17
- [[#5959](https://github.com/seata/seata/pull/5959)] modify code style and remove unused import
- [[#6002](https://github.com/seata/seata/pull/6002)] remove fst serialization

- [[#6030](https://github.com/seata/seata/pull/6030)] add a check for the existence of the undolog table

### security:
- [[#5642](https://github.com/seata/seata/pull/5642)] add Hessian Serializer WhiteDenyList
Expand Down
1 change: 1 addition & 0 deletions changes/zh-cn/2.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ Seata 是一款开源的分布式事务解决方案,提供高性能和简单
- [[#5951](https://github.com/seata/seata/pull/5951)] 删除在 jdk17 中不支持的配置项
- [[#5959](https://github.com/seata/seata/pull/5959)] 修正代码风格问题及去除无用的类引用
- [[#6002](https://github.com/seata/seata/pull/6002)] 移除fst序列化模块
- [[#6030](https://github.com/seata/seata/pull/6030)] 添加undo_log表的存在性校验


### security:
Expand Down
17 changes: 17 additions & 0 deletions core/src/main/java/io/seata/core/constants/DBType.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

import io.seata.common.util.StringUtils;

import java.util.Optional;

/**
* database type
*
Expand Down Expand Up @@ -209,4 +211,19 @@ public static DBType valueof(String dbType) {
throw new IllegalArgumentException("unknown dbtype:" + dbType);
}


/**
* optional of db type.
*
* @param dbType the db type
* @return optional of the db type
*/
public static Optional<DBType> optionalof(String dbType) {
for (DBType dt : values()) {
if (StringUtils.equalsIgnoreCase(dt.name(), dbType)) {
return Optional.of(dt);
}
}
return Optional.empty();
}
}
23 changes: 0 additions & 23 deletions rm-datasource/src/main/java/io/seata/rm/RMHandlerAT.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
import java.sql.SQLException;
import java.text.ParseException;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import io.seata.common.util.DateUtil;
import io.seata.core.model.BranchType;
Expand All @@ -44,8 +42,6 @@ public class RMHandlerAT extends AbstractRMHandler {

private static final int LIMIT_ROWS = 3000;

private final Map<String, Boolean> undoLogTableExistRecord = new ConcurrentHashMap<>();

@Override
public void handle(UndoLogDeleteRequest request) {
String resourceId = request.getResourceId();
Expand All @@ -56,12 +52,6 @@ public void handle(UndoLogDeleteRequest request) {
return;
}

boolean hasUndoLogTable = undoLogTableExistRecord.computeIfAbsent(resourceId, id -> checkUndoLogTableExist(dataSourceProxy));
if (!hasUndoLogTable) {
LOGGER.debug("resource({}) has no undo_log table, UndoLogDeleteRequest will be ignored", resourceId);
return;
}

Date division = getLogCreated(request.getSaveDays());

UndoLogManager manager = getUndoLogManager(dataSourceProxy);
Expand All @@ -80,19 +70,6 @@ public void handle(UndoLogDeleteRequest request) {
}
}

boolean checkUndoLogTableExist(DataSourceProxy dataSourceProxy) {
UndoLogManager manager = getUndoLogManager(dataSourceProxy);
try (Connection connection = getConnection(dataSourceProxy)) {
if (connection == null) {
return false;
}
return manager.hasUndoLogTable(connection);
} catch (Exception e) {
// should never happen, hasUndoLogTable method had catch all Exception
return false;
}
}

Connection getConnection(DataSourceProxy dataSourceProxy) {
try {
return dataSourceProxy.getPlainConnection();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,24 @@

import javax.sql.DataSource;

import io.seata.common.ConfigurationKeys;
import io.seata.common.Constants;
import io.seata.config.ConfigurationFactory;
import io.seata.core.constants.DBType;
import io.seata.core.context.RootContext;
import io.seata.core.model.BranchType;
import io.seata.core.model.Resource;
import io.seata.rm.DefaultResourceManager;
import io.seata.rm.datasource.sql.struct.TableMetaCacheFactory;
import io.seata.rm.datasource.undo.UndoLogManager;
import io.seata.rm.datasource.undo.UndoLogManagerFactory;
import io.seata.rm.datasource.util.JdbcUtils;
import io.seata.sqlparser.util.JdbcConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import static io.seata.common.DefaultValues.DEFAULT_TRANSACTION_UNDO_LOG_TABLE;

/**
* The type Data source proxy.
*
Expand Down Expand Up @@ -92,6 +99,9 @@ private void init(DataSource dataSource, String resourceGroupId) {
getMySQLAdaptiveType(connection);
}
version = selectDbVersion(connection);

checkUndoLogTableExist(connection);

} catch (SQLException e) {
throw new IllegalStateException("can not init dataSource", e);
}
Expand Down Expand Up @@ -120,6 +130,26 @@ private void getMySQLAdaptiveType(Connection connection) {
}
}

/**
* check existence of undolog table
*
* if the table not exist fast fail, or else keep silence
*
* @param conn db connection
*/
private void checkUndoLogTableExist(Connection conn) {
if (DBType.optionalof(dbType).isPresent()) {
UndoLogManager undoLogManager = UndoLogManagerFactory.getUndoLogManager(dbType);
boolean undoLogTableExist = undoLogManager.hasUndoLogTable(conn);
if (!undoLogTableExist) {
String undoLogTableName = ConfigurationFactory.getInstance()
.getConfig(ConfigurationKeys.TRANSACTION_UNDO_LOG_TABLE, DEFAULT_TRANSACTION_UNDO_LOG_TABLE);
String errMsg = String.format("in AT mode, %s table not exist", undoLogTableName);
throw new IllegalStateException(errMsg);
}
}
}

/**
* publish tableMeta refresh event
*/
Expand Down
13 changes: 0 additions & 13 deletions rm-datasource/src/test/java/io/seata/rm/RMHandlerATTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,22 +48,9 @@ void hasUndoLogTableTest() {
for (int i = 0; i < testTimes; i++) {
handler.handle(request);
}
verify(handler, times(1)).checkUndoLogTableExist(any());
verify(handler, times(testTimes)).deleteUndoLog(any(), any(), any());
}

@Test
void noUndoLogTableTest() {
RMHandlerAT handler = buildHandler(false);
UndoLogDeleteRequest request = buildRequest();
int testTimes = 5;
for (int i = 0; i < testTimes; i++) {
handler.handle(request);
}
verify(handler, times(1)).checkUndoLogTableExist(any());
verify(handler, never()).deleteUndoLog(any(), any(), any());
}

private RMHandlerAT buildHandler(boolean hasUndoLogTable) {
RMHandlerAT handler = spy(new RMHandlerAT());
DataSourceManager dataSourceManager = mock(DataSourceManager.class);
Expand Down
Loading