diff --git a/docs/src/main/sphinx/admin/event-listeners-mysql.md b/docs/src/main/sphinx/admin/event-listeners-mysql.md index 4ea95eba095a..ec39fdb3491f 100644 --- a/docs/src/main/sphinx/admin/event-listeners-mysql.md +++ b/docs/src/main/sphinx/admin/event-listeners-mysql.md @@ -67,4 +67,8 @@ string, user, catalog, and others with information about the query processing. - Description * - `mysql-event-listener.db.url` - JDBC connection URL to the database including credentials -::: +* - `mysql-event-listener.terminate-on-initialization-failure` + - MySQL event listener initialization can fail if the database is unavailable. + This [boolean](prop-type-boolean) switch controls whether to throw an + exception in such cases. Defaults to `true`. + ::: diff --git a/plugin/trino-mysql-event-listener/src/main/java/io/trino/plugin/eventlistener/mysql/MysqlEventListener.java b/plugin/trino-mysql-event-listener/src/main/java/io/trino/plugin/eventlistener/mysql/MysqlEventListener.java index a59c209cb5eb..49981ae864ff 100644 --- a/plugin/trino-mysql-event-listener/src/main/java/io/trino/plugin/eventlistener/mysql/MysqlEventListener.java +++ b/plugin/trino-mysql-event-listener/src/main/java/io/trino/plugin/eventlistener/mysql/MysqlEventListener.java @@ -50,6 +50,7 @@ public class MysqlEventListener private static final long MAX_OPERATOR_SUMMARIES_JSON_LENGTH = 16 * 1024 * 1024; + private final boolean terminateOnInitializationFailure; private final QueryDao dao; private final JsonCodec> clientTagsJsonCodec; private final JsonCodec> sessionPropertiesJsonCodec; @@ -59,6 +60,7 @@ public class MysqlEventListener @Inject public MysqlEventListener( + MysqlEventListenerConfig config, QueryDao dao, JsonCodec> clientTagsJsonCodec, JsonCodec> sessionPropertiesJsonCodec, @@ -66,6 +68,7 @@ public MysqlEventListener( JsonCodec outputJsonCodec, JsonCodec> warningsJsonCodec) { + this.terminateOnInitializationFailure = config.getTerminateOnInitializationFailure(); this.dao = requireNonNull(dao, "dao is null"); this.clientTagsJsonCodec = requireNonNull(clientTagsJsonCodec, "clientTagsJsonCodec is null"); this.sessionPropertiesJsonCodec = requireNonNull(sessionPropertiesJsonCodec, "sessionPropertiesJsonCodec is null"); @@ -77,7 +80,16 @@ public MysqlEventListener( @PostConstruct public void createTable() { - dao.createTable(); + try { + dao.createTable(); + } + catch (Exception e) { + if (terminateOnInitializationFailure) { + throw e; + } + // Log the error but do not terminate, allowing the listener to continue functioning + log.warn(e, "Unexpected error while creating MySQL event listener schema at startup. Ignoring error."); + } } @Override diff --git a/plugin/trino-mysql-event-listener/src/main/java/io/trino/plugin/eventlistener/mysql/MysqlEventListenerConfig.java b/plugin/trino-mysql-event-listener/src/main/java/io/trino/plugin/eventlistener/mysql/MysqlEventListenerConfig.java index 7d9b08cd4365..6e887e71d52a 100644 --- a/plugin/trino-mysql-event-listener/src/main/java/io/trino/plugin/eventlistener/mysql/MysqlEventListenerConfig.java +++ b/plugin/trino-mysql-event-listener/src/main/java/io/trino/plugin/eventlistener/mysql/MysqlEventListenerConfig.java @@ -15,6 +15,7 @@ import com.mysql.cj.jdbc.Driver; import io.airlift.configuration.Config; +import io.airlift.configuration.ConfigDescription; import io.airlift.configuration.ConfigSecuritySensitive; import jakarta.validation.constraints.AssertTrue; import jakarta.validation.constraints.NotNull; @@ -24,6 +25,7 @@ public class MysqlEventListenerConfig { private String url; + private boolean terminateOnInitializationFailure = true; @NotNull public String getUrl() @@ -49,4 +51,17 @@ public boolean isValidUrl() throw new RuntimeException(e); } } + + public boolean getTerminateOnInitializationFailure() + { + return terminateOnInitializationFailure; + } + + @Config("mysql-event-listener.terminate-on-initialization-failure") + @ConfigDescription("The MySQL event listener initialization may fail if the database is unavailable. This flag determines whether an exception should be thrown in such cases.") + public MysqlEventListenerConfig setTerminateOnInitializationFailure(boolean terminateOnInitializationFailure) + { + this.terminateOnInitializationFailure = terminateOnInitializationFailure; + return this; + } } diff --git a/plugin/trino-mysql-event-listener/src/test/java/io/trino/plugin/eventlistener/mysql/TestMysqlEventListenerConfig.java b/plugin/trino-mysql-event-listener/src/test/java/io/trino/plugin/eventlistener/mysql/TestMysqlEventListenerConfig.java index 15b85e310568..22e9d8f1710c 100644 --- a/plugin/trino-mysql-event-listener/src/test/java/io/trino/plugin/eventlistener/mysql/TestMysqlEventListenerConfig.java +++ b/plugin/trino-mysql-event-listener/src/test/java/io/trino/plugin/eventlistener/mysql/TestMysqlEventListenerConfig.java @@ -28,17 +28,20 @@ final class TestMysqlEventListenerConfig void testDefaults() { assertRecordedDefaults(recordDefaults(MysqlEventListenerConfig.class) - .setUrl(null)); + .setUrl(null) + .setTerminateOnInitializationFailure(true)); } @Test void testExplicitPropertyMappings() { Map properties = Map.of( - "mysql-event-listener.db.url", "jdbc:mysql://example.net:3306"); + "mysql-event-listener.db.url", "jdbc:mysql://example.net:3306", + "mysql-event-listener.terminate-on-initialization-failure", "false"); MysqlEventListenerConfig expected = new MysqlEventListenerConfig() - .setUrl("jdbc:mysql://example.net:3306"); + .setUrl("jdbc:mysql://example.net:3306") + .setTerminateOnInitializationFailure(false); assertFullMapping(properties, expected); }