From fe4132a928583fd8e2c13fb51b89d2a02fa8a9fa Mon Sep 17 00:00:00 2001 From: moonsphere Date: Thu, 29 Oct 2020 20:24:30 +0800 Subject: [PATCH 1/3] fix transaction too large error when use TiDB as storage --- .../jdbc/hikaricp/JDBCHikariCPClient.java | 6 +- .../jdbc/h2/dao/H2HistoryDeleteDAO.java | 2 +- .../jdbc/mysql/TiDBHistoryDeleteDAO.java | 56 +++++++++++++++++++ .../jdbc/mysql/TiDBStorageProvider.java | 25 +++++++++ ...g.oap.server.library.module.ModuleProvider | 3 +- 5 files changed, 87 insertions(+), 5 deletions(-) create mode 100644 oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/TiDBHistoryDeleteDAO.java create mode 100644 oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/TiDBStorageProvider.java diff --git a/oap-server/server-library/library-client/src/main/java/org/apache/skywalking/oap/server/library/client/jdbc/hikaricp/JDBCHikariCPClient.java b/oap-server/server-library/library-client/src/main/java/org/apache/skywalking/oap/server/library/client/jdbc/hikaricp/JDBCHikariCPClient.java index 502eed3847cf..03bf6ac36e51 100644 --- a/oap-server/server-library/library-client/src/main/java/org/apache/skywalking/oap/server/library/client/jdbc/hikaricp/JDBCHikariCPClient.java +++ b/oap-server/server-library/library-client/src/main/java/org/apache/skywalking/oap/server/library/client/jdbc/hikaricp/JDBCHikariCPClient.java @@ -90,14 +90,14 @@ public void execute(Connection connection, String sql) throws JDBCClientExceptio } } - public boolean execute(Connection connection, String sql, Object... params) throws JDBCClientException { + public int executeUpdate(Connection connection, String sql, Object... params) throws JDBCClientException { LOGGER.debug("execute query with result: {}", sql); - boolean result; + int result; PreparedStatement statement = null; try { statement = connection.prepareStatement(sql); setStatementParam(statement, params); - result = statement.execute(); + result = statement.executeUpdate(); statement.closeOnCompletion(); healthChecker.health(); } catch (SQLException e) { diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2HistoryDeleteDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2HistoryDeleteDAO.java index 31ffe5032581..4c8510d6a4c8 100644 --- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2HistoryDeleteDAO.java +++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/h2/dao/H2HistoryDeleteDAO.java @@ -66,7 +66,7 @@ public void deleteHistory(Model model, String timeBucketColumnName, int ttl) thr return; } } - client.execute(connection, dataDeleteSQL.toString(), deadline, minTimeBucket); + client.executeUpdate(connection, dataDeleteSQL.toString(), deadline, minTimeBucket); } catch (JDBCClientException | SQLException e) { throw new IOException(e.getMessage(), e); } diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/TiDBHistoryDeleteDAO.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/TiDBHistoryDeleteDAO.java new file mode 100644 index 000000000000..eac392b9ef9b --- /dev/null +++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/TiDBHistoryDeleteDAO.java @@ -0,0 +1,56 @@ +package org.apache.skywalking.oap.server.storage.plugin.jdbc.mysql; + +import org.apache.skywalking.oap.server.core.storage.model.Model; +import org.apache.skywalking.oap.server.library.client.jdbc.JDBCClientException; +import org.apache.skywalking.oap.server.library.client.jdbc.hikaricp.JDBCHikariCPClient; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.SQLBuilder; +import org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.dao.H2HistoryDeleteDAO; +import org.joda.time.DateTime; + +import java.io.IOException; +import java.sql.Connection; +import java.sql.SQLException; + +public class TiDBHistoryDeleteDAO extends H2HistoryDeleteDAO { + + public TiDBHistoryDeleteDAO(JDBCHikariCPClient client) { + super(client); + } + + @Override + public void deleteHistory(Model model, String timeBucketColumnName, int ttl) throws IOException { + SQLBuilder dataDeleteSQL = new SQLBuilder("delete from " + model.getName() + " where ") + .append(timeBucketColumnName).append("<= ? and ") + .append(timeBucketColumnName).append(">= ?") + .append(" limit 10000"); + long minTimeBucket = 0; + DateTime minDate = new DateTime(1900, 1, 1, 0, 0); + + try (Connection connection = client.getConnection()) { + long deadline; + if (model.isRecord()) { + deadline = Long.valueOf(new DateTime().plusDays(0 - ttl).toString("yyyyMMddHHmmss")); + } else { + switch (model.getDownsampling()) { + case Minute: + deadline = Long.valueOf(new DateTime().plusDays(0 - ttl).toString("yyyyMMddHHmm")); + minTimeBucket = Long.valueOf(minDate.toString("yyyyMMddHHmm")); + break; + case Hour: + deadline = Long.valueOf(new DateTime().plusDays(0 - ttl).toString("yyyyMMddHH")); + minTimeBucket = Long.valueOf(minDate.toString("yyyyMMddHH")); + break; + case Day: + deadline = Long.valueOf(new DateTime().plusDays(0 - ttl).toString("yyyyMMdd")); + minTimeBucket = Long.valueOf(minDate.toString("yyyyMMdd")); + break; + default: + return; + } + } + while(client.executeUpdate(connection, dataDeleteSQL.toString(), deadline, minTimeBucket) > 0) {} + } catch (JDBCClientException | SQLException e) { + throw new IOException(e.getMessage(), e); + } + } +} diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/TiDBStorageProvider.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/TiDBStorageProvider.java new file mode 100644 index 000000000000..89eaa1738f56 --- /dev/null +++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/TiDBStorageProvider.java @@ -0,0 +1,25 @@ +package org.apache.skywalking.oap.server.storage.plugin.jdbc.mysql; + +import lombok.extern.slf4j.Slf4j; +import org.apache.skywalking.oap.server.core.storage.IHistoryDeleteDAO; +import org.apache.skywalking.oap.server.library.module.ServiceNotProvidedException; + +/** + * TiDB storage enhanced and came from MySQLStorageProvider to support TiDB. + * + * cause: need add "useAffectedRows=true" to jdbc url. + */ +@Slf4j +public class TiDBStorageProvider extends MySQLStorageProvider { + + @Override + public String name() { + return "tidb"; + } + + @Override + public void prepare() throws ServiceNotProvidedException { + super.prepare(); + this.registerServiceImplementation(IHistoryDeleteDAO.class, new TiDBHistoryDeleteDAO(this.mysqlClient)); + } +} diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider index c8fa0b9f81a8..d9b7df5f7276 100644 --- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider +++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/resources/META-INF/services/org.apache.skywalking.oap.server.library.module.ModuleProvider @@ -17,4 +17,5 @@ # org.apache.skywalking.oap.server.storage.plugin.jdbc.h2.H2StorageProvider -org.apache.skywalking.oap.server.storage.plugin.jdbc.mysql.MySQLStorageProvider \ No newline at end of file +org.apache.skywalking.oap.server.storage.plugin.jdbc.mysql.MySQLStorageProvider +org.apache.skywalking.oap.server.storage.plugin.jdbc.mysql.TiDBStorageProvider \ No newline at end of file From 2953a069a2d1409eff001eb8aef3d2f8ff092600 Mon Sep 17 00:00:00 2001 From: moonsphere Date: Thu, 29 Oct 2020 20:46:22 +0800 Subject: [PATCH 2/3] add CHANGES.md --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index e9a0e0addb21..8e5b58117408 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -13,6 +13,7 @@ Release Notes. #### OAP-Backend * Add the `@SuperDataset` annotation for BrowserErrorLog. * Improve Kubernetes service registry for ALS analysis. +* Fix "transaction too large error" when use TiDB as storage. #### UI From 4f3e3db27673b2add4c3c612892474f66a6e6e72 Mon Sep 17 00:00:00 2001 From: moonsphere Date: Thu, 29 Oct 2020 21:08:50 +0800 Subject: [PATCH 3/3] fix typo --- .../server/storage/plugin/jdbc/mysql/TiDBStorageProvider.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/TiDBStorageProvider.java b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/TiDBStorageProvider.java index 89eaa1738f56..2ac2dcef75d5 100644 --- a/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/TiDBStorageProvider.java +++ b/oap-server/server-storage-plugin/storage-jdbc-hikaricp-plugin/src/main/java/org/apache/skywalking/oap/server/storage/plugin/jdbc/mysql/TiDBStorageProvider.java @@ -7,7 +7,7 @@ /** * TiDB storage enhanced and came from MySQLStorageProvider to support TiDB. * - * cause: need add "useAffectedRows=true" to jdbc url. + * caution: need add "useAffectedRows=true" to jdbc url. */ @Slf4j public class TiDBStorageProvider extends MySQLStorageProvider {