Search in sources :

Example 1 with JdbcConnection

use of io.debezium.jdbc.JdbcConnection in project eventuate-local by eventuate-local.

the class DebeziumCdcStartupValidator method validateDatasourceConnection.

private void validateDatasourceConnection() {
    logger.info("About to validate DataSource connection");
    Map<String, String> connectorConfig = new HashMap<>();
    connectorConfig.put(MySqlConnectorConfig.HOSTNAME.name(), jdbcUrl.getHost());
    connectorConfig.put(MySqlConnectorConfig.PORT.name(), String.valueOf(jdbcUrl.getPort()));
    connectorConfig.put(MySqlConnectorConfig.USER.name(), dbUser);
    connectorConfig.put(MySqlConnectorConfig.PASSWORD.name(), dbPassword);
    Configuration config = Configuration.from(connectorConfig);
    try (MySqlJdbcContext jdbcContext = new MySqlJdbcContext(config)) {
        jdbcContext.start();
        JdbcConnection mysql = jdbcContext.jdbc();
        int i = mySqlValidationMaxAttempts;
        SQLException lastException = null;
        while (i > 0) {
            try {
                mysql.execute("SELECT version()");
                logger.info("Successfully tested connection for {}:{} with user '{}'", jdbcContext.hostname(), jdbcContext.port(), mysql.username());
                return;
            } catch (SQLException e) {
                lastException = e;
                logger.info("Failed testing connection for {}:{} with user '{}'", jdbcContext.hostname(), jdbcContext.port(), mysql.username());
                i--;
                try {
                    Thread.sleep(mySqlValidationTimeoutMillis);
                } catch (InterruptedException ie) {
                    throw new RuntimeException("MySql validation had been interrupted!", ie);
                }
            }
        }
        jdbcContext.shutdown();
        throw new RuntimeException(lastException);
    }
}
Also used : Configuration(io.debezium.config.Configuration) HashMap(java.util.HashMap) MySqlJdbcContext(io.debezium.connector.mysql.MySqlJdbcContext) SQLException(java.sql.SQLException) JdbcConnection(io.debezium.jdbc.JdbcConnection)

Example 2 with JdbcConnection

use of io.debezium.jdbc.JdbcConnection in project debezium by debezium.

the class MySqlJdbcContext method readMySqlSystemVariables.

/**
 * Read the MySQL system variables.
 *
 * @param sql the reference that should be set to the SQL statement; may be null if not needed
 * @return the system variables that are related to server character sets; never null
 */
protected Map<String, String> readMySqlSystemVariables(AtomicReference<String> sql) {
    // Read the system variables from the MySQL instance and get the current database name ...
    Map<String, String> variables = new HashMap<>();
    try (JdbcConnection mysql = jdbc.connect()) {
        logger.debug("Reading MySQL system variables");
        String statement = "SHOW VARIABLES";
        if (sql != null)
            sql.set(statement);
        mysql.query(statement, rs -> {
            while (rs.next()) {
                String varName = rs.getString(1);
                String value = rs.getString(2);
                if (varName != null && value != null) {
                    variables.put(varName, value);
                    logger.debug("\t{} = {}", Strings.pad(varName, 45, ' '), Strings.pad(value, 45, ' '));
                }
            }
        });
    } catch (SQLException e) {
        throw new ConnectException("Error reading MySQL variables: " + e.getMessage(), e);
    }
    return variables;
}
Also used : HashMap(java.util.HashMap) SQLException(java.sql.SQLException) JdbcConnection(io.debezium.jdbc.JdbcConnection) ConnectException(org.apache.kafka.connect.errors.ConnectException)

Example 3 with JdbcConnection

use of io.debezium.jdbc.JdbcConnection in project debezium by debezium.

the class MySqlJdbcContext method readMySqlCharsetSystemVariables.

/**
 * Read the MySQL charset-related system variables.
 *
 * @param sql the reference that should be set to the SQL statement; may be null if not needed
 * @return the system variables that are related to server character sets; never null
 */
protected Map<String, String> readMySqlCharsetSystemVariables(AtomicReference<String> sql) {
    // Read the system variables from the MySQL instance and get the current database name ...
    Map<String, String> variables = new HashMap<>();
    try (JdbcConnection mysql = jdbc.connect()) {
        logger.debug("Reading MySQL charset-related system variables before parsing DDL history.");
        String statement = "SHOW VARIABLES WHERE Variable_name IN ('character_set_server','collation_server')";
        if (sql != null)
            sql.set(statement);
        mysql.query(statement, rs -> {
            while (rs.next()) {
                String varName = rs.getString(1);
                String value = rs.getString(2);
                if (varName != null && value != null) {
                    variables.put(varName, value);
                    logger.debug("\t{} = {}", Strings.pad(varName, 45, ' '), Strings.pad(value, 45, ' '));
                }
            }
        });
    } catch (SQLException e) {
        throw new ConnectException("Error reading MySQL variables: " + e.getMessage(), e);
    }
    return variables;
}
Also used : HashMap(java.util.HashMap) SQLException(java.sql.SQLException) JdbcConnection(io.debezium.jdbc.JdbcConnection) ConnectException(org.apache.kafka.connect.errors.ConnectException)

Example 4 with JdbcConnection

use of io.debezium.jdbc.JdbcConnection in project debezium by debezium.

the class BinlogReaderBufferIT method shouldProcessLargeTransaction.

@Test
public void shouldProcessLargeTransaction() throws SQLException, InterruptedException {
    String masterPort = System.getProperty("database.port", "3306");
    String replicaPort = System.getProperty("database.replica.port", "3306");
    boolean replicaIsMaster = masterPort.equals(replicaPort);
    if (!replicaIsMaster) {
        // Give time for the replica to catch up to the master ...
        Thread.sleep(5000L);
    }
    // Use the DB configuration to define the connector's configuration to use the "replica"
    // which may be the same as the "master" ...
    config = Configuration.create().with(MySqlConnectorConfig.HOSTNAME, System.getProperty("database.replica.hostname", "localhost")).with(MySqlConnectorConfig.PORT, System.getProperty("database.replica.port", "3306")).with(MySqlConnectorConfig.USER, "snapper").with(MySqlConnectorConfig.PASSWORD, "snapperpass").with(MySqlConnectorConfig.SERVER_ID, 18765).with(MySqlConnectorConfig.SERVER_NAME, DATABASE.getServerName()).with(MySqlConnectorConfig.SSL_MODE, SecureConnectionMode.DISABLED).with(MySqlConnectorConfig.POLL_INTERVAL_MS, 10).with(MySqlConnectorConfig.DATABASE_WHITELIST, DATABASE.getDatabaseName()).with(MySqlConnectorConfig.DATABASE_HISTORY, FileDatabaseHistory.class).with(MySqlConnectorConfig.INCLUDE_SCHEMA_CHANGES, true).with(MySqlConnectorConfig.BUFFER_SIZE_FOR_BINLOG_READER, 9).with(FileDatabaseHistory.FILE_PATH, DB_HISTORY_PATH).build();
    // Start the connector ...
    start(MySqlConnector.class, config);
    // 11 schema change records + 1 SET statement
    SourceRecords records = consumeRecordsByTopic(5 + 9 + 9 + 4 + 11 + 1);
    // ---------------------------------------------------------------------------------------------------------------
    try (MySQLConnection db = MySQLConnection.forTestDatabase(DATABASE.getDatabaseName())) {
        final int numRecords = 40;
        try (JdbcConnection connection = db.connect()) {
            final Connection jdbc = connection.connection();
            connection.setAutoCommit(false);
            final Statement statement = jdbc.createStatement();
            for (int i = 0; i < numRecords; i++) {
                statement.executeUpdate(String.format("INSERT INTO customers\n" + "VALUES (default,\"%s\",\"%s\",\"%s\")", i, i, i));
            }
            jdbc.commit();
            connection.query("SELECT * FROM customers", rs -> {
                if (Testing.Print.isEnabled())
                    connection.print(rs);
            });
            connection.setAutoCommit(true);
        }
        // All records should be present only once
        records = consumeRecordsByTopic(numRecords);
        int recordIndex = 0;
        for (SourceRecord r : records.allRecordsInOrder()) {
            Struct envelope = (Struct) r.value();
            assertThat(envelope.getString("op")).isEqualTo(("c"));
            assertThat(envelope.getStruct("after").getString("email")).isEqualTo(Integer.toString(recordIndex++));
        }
        assertThat(records.topics().size()).isEqualTo(1);
        Testing.print("*** Done with large TX");
    }
}
Also used : Statement(java.sql.Statement) Connection(java.sql.Connection) JdbcConnection(io.debezium.jdbc.JdbcConnection) JdbcConnection(io.debezium.jdbc.JdbcConnection) FileDatabaseHistory(io.debezium.relational.history.FileDatabaseHistory) SourceRecord(org.apache.kafka.connect.source.SourceRecord) Savepoint(java.sql.Savepoint) Struct(org.apache.kafka.connect.data.Struct) Test(org.junit.Test) AbstractConnectorTest(io.debezium.embedded.AbstractConnectorTest)

Example 5 with JdbcConnection

use of io.debezium.jdbc.JdbcConnection in project debezium by debezium.

the class BinlogReaderBufferIT method shouldProcessRolledBackSavepoint.

@FixFor("DBZ-411")
@Test
public void shouldProcessRolledBackSavepoint() throws SQLException, InterruptedException {
    String masterPort = System.getProperty("database.port", "3306");
    String replicaPort = System.getProperty("database.replica.port", "3306");
    boolean replicaIsMaster = masterPort.equals(replicaPort);
    if (!replicaIsMaster) {
        // Give time for the replica to catch up to the master ...
        Thread.sleep(5000L);
    }
    // Use the DB configuration to define the connector's configuration to use the "replica"
    // which may be the same as the "master" ...
    config = Configuration.create().with(MySqlConnectorConfig.HOSTNAME, System.getProperty("database.replica.hostname", "localhost")).with(MySqlConnectorConfig.PORT, System.getProperty("database.replica.port", "3306")).with(MySqlConnectorConfig.USER, "snapper").with(MySqlConnectorConfig.PASSWORD, "snapperpass").with(MySqlConnectorConfig.SERVER_ID, 18765).with(MySqlConnectorConfig.SERVER_NAME, DATABASE.getServerName()).with(MySqlConnectorConfig.SSL_MODE, SecureConnectionMode.DISABLED).with(MySqlConnectorConfig.POLL_INTERVAL_MS, 10).with(MySqlConnectorConfig.DATABASE_WHITELIST, DATABASE.getDatabaseName()).with(MySqlConnectorConfig.DATABASE_HISTORY, FileDatabaseHistory.class).with(MySqlConnectorConfig.INCLUDE_SCHEMA_CHANGES, true).with(FileDatabaseHistory.FILE_PATH, DB_HISTORY_PATH).build();
    // Start the connector ...
    start(MySqlConnector.class, config);
    // 11 schema change records + 1 SET statement
    SourceRecords records = consumeRecordsByTopic(5 + 9 + 9 + 4 + 11 + 1);
    // ---------------------------------------------------------------------------------------------------------------
    if (replicaIsMaster) {
        try (MySQLConnection db = MySQLConnection.forTestDatabase(DATABASE.getDatabaseName())) {
            try (JdbcConnection connection = db.connect()) {
                final Connection jdbc = connection.connection();
                connection.setAutoCommit(false);
                final Statement statement = jdbc.createStatement();
                statement.executeUpdate("CREATE TEMPORARY TABLE tmp_ids (a int)");
                statement.executeUpdate("INSERT INTO tmp_ids VALUES(5)");
                jdbc.commit();
                statement.executeUpdate("DROP TEMPORARY TABLE tmp_ids");
                statement.executeUpdate("INSERT INTO customers VALUES(default, 'first', 'first', 'first')");
                final Savepoint savepoint = jdbc.setSavepoint();
                statement.executeUpdate("INSERT INTO customers VALUES(default, 'second', 'second', 'second')");
                jdbc.rollback(savepoint);
                jdbc.commit();
                connection.query("SELECT * FROM customers", rs -> {
                    if (Testing.Print.isEnabled())
                        connection.print(rs);
                });
                connection.setAutoCommit(true);
            }
        }
        // Bug DBZ-533
        // INSERT + SAVEPOINT + INSERT + ROLLBACK
        records = consumeRecordsByTopic(1 + 1 + 1 + 1);
        assertThat(records.topics().size()).isEqualTo(1 + 1);
        assertThat(records.recordsForTopic(DATABASE.topicForTable("customers"))).hasSize(2);
        assertThat(records.allRecordsInOrder()).hasSize(4);
        Testing.print("*** Done with savepoint TX");
    }
}
Also used : Statement(java.sql.Statement) Connection(java.sql.Connection) JdbcConnection(io.debezium.jdbc.JdbcConnection) JdbcConnection(io.debezium.jdbc.JdbcConnection) Savepoint(java.sql.Savepoint) Test(org.junit.Test) AbstractConnectorTest(io.debezium.embedded.AbstractConnectorTest) FixFor(io.debezium.doc.FixFor)

Aggregations

JdbcConnection (io.debezium.jdbc.JdbcConnection)13 AbstractConnectorTest (io.debezium.embedded.AbstractConnectorTest)7 Test (org.junit.Test)7 Connection (java.sql.Connection)6 Statement (java.sql.Statement)6 SQLException (java.sql.SQLException)5 SourceRecord (org.apache.kafka.connect.source.SourceRecord)5 HashMap (java.util.HashMap)4 FixFor (io.debezium.doc.FixFor)3 Configuration (io.debezium.config.Configuration)2 FileDatabaseHistory (io.debezium.relational.history.FileDatabaseHistory)2 Savepoint (java.sql.Savepoint)2 ConnectException (org.apache.kafka.connect.errors.ConnectException)2 MySqlJdbcContext (io.debezium.connector.mysql.MySqlJdbcContext)1 RecordsForTable (io.debezium.connector.mysql.RecordMakers.RecordsForTable)1 CompletionResult (io.debezium.embedded.EmbeddedEngine.CompletionResult)1 BufferedBlockingConsumer (io.debezium.function.BufferedBlockingConsumer)1 Predicates (io.debezium.function.Predicates)1 StatementFactory (io.debezium.jdbc.JdbcConnection.StatementFactory)1 Column (io.debezium.relational.Column)1