Skip to content
Merged
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
6 changes: 5 additions & 1 deletion docs/src/main/sphinx/admin/event-listeners-mysql.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
:::
Original file line number Diff line number Diff line change
Expand Up @@ -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<Set<String>> clientTagsJsonCodec;
private final JsonCodec<Map<String, String>> sessionPropertiesJsonCodec;
Expand All @@ -59,13 +60,15 @@ public class MysqlEventListener

@Inject
public MysqlEventListener(
MysqlEventListenerConfig config,
QueryDao dao,
JsonCodec<Set<String>> clientTagsJsonCodec,
JsonCodec<Map<String, String>> sessionPropertiesJsonCodec,
JsonCodec<List<QueryInputMetadata>> inputsJsonCodec,
JsonCodec<QueryOutputMetadata> outputJsonCodec,
JsonCodec<List<TrinoWarning>> 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");
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -24,6 +25,7 @@
public class MysqlEventListenerConfig
{
private String url;
private boolean terminateOnInitializationFailure = true;

@NotNull
public String getUrl()
Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,20 @@ final class TestMysqlEventListenerConfig
void testDefaults()
{
assertRecordedDefaults(recordDefaults(MysqlEventListenerConfig.class)
.setUrl(null));
.setUrl(null)
.setTerminateOnInitializationFailure(true));
}

@Test
void testExplicitPropertyMappings()
{
Map<String, String> 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);
}
Expand Down