Kafka Connect MySQL“无法识别服务器时区值‘EDT’”

Posted

技术标签:

【中文标题】Kafka Connect MySQL“无法识别服务器时区值‘EDT’”【英文标题】:Kafka Connect MySQL "server time zone value 'EDT' is unrecognized" 【发布时间】:2021-07-24 04:29:18 【问题描述】:

我是 Kafka 的新手,但 Debezium Connect/mysql 在 Docker 中启动并运行得很好。突然之间,所有 docker 容器都消失了,重新启动并尝试重新连接到 MySQL 时,JDBC 连接失败,并响应 Connect rest API:

Using ZOOKEEPER_CONNECT=0.0.0.0:2181
Using KAFKA_LISTENERS=PLAINTEXT://172.19.0.5:9092 and KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://172.19.0.5:9092
HTTP/1.1 400 Bad Request
Date: Fri, 30 Apr 2021 20:39:56 GMT
Content-Type: application/json
Content-Length: 
Server: Jetty(9.4.33.v20201020)
                    
"error_code":400,"message":"Connector configuration is invalid  
            and contains the following 1 error(s): \nUnable to connect: The server time  
            zone value 'EDT' is unrecognized or represents more than one time zone. You  
            must configure either the server or JDBC driver (via the 'serverTimezone'   
    configuration property) to use a more specifc time zone value if you want  
            to utilize time zone support.\nYou can also find the above list of errors  
            at the endpoint `/connector-plugins/connectorType/config/validate`"

响应运行:

docker run -it --rm --net mynet_default debezium/kafka \
curl -i -X POST -H "Accept:application/json" -H "Content-Type:application/json" \
mynet_connect_1:8083/connectors/ \
-d ' 
"name": "my-connector-001",
"config":  
"connector.class": "io.debezium.connector.mysql.MySqlConnector", 
"tasks.max": "1", 
"database.hostname": "my.domain.com", 
"database.port": "3306",
"database.user": "myuser",
"database.password": "mypassword", 
"database.server.id": "6400", 
"database.server.name": "dbserver001",
"database.include.list": "mydb", 
"database.history.kafka.bootstrap.servers": "kafka:9092", 
"database.history.kafka.topic": "dbhistory.metrics.connector004",
"table.include.list":"mydb.users,mydb.applications"

 '

这工作了几个小时。然后,当我主要直接从 Debezium 教程中观看更新时,所有的 kafka 容器都消失了,从那以后(使用完全相同的配置)将不再连接,引用时区的事情。我可以在 mysql 客户端(通过 docker 网络)中使用相同的凭据进行连接,并且 MySQL 权限和授权没有改变。去年 7 月有一个 Gitter 提到,这个错误本身就是其他连接失败的错误指示。并且有多个报告称它是 JDBC 中的一个错误。除了有人更改了我们数据库中的某些内容之外,还有其他可能性吗?

这是连接日志:

connect_1    | 2021-04-30 20:28:47,254 INFO   ||  [Worker clientId=connect-1, groupId=1] Session key updated   [org.apache.kafka.connect.runtime.distributed.DistributedHerder]
connect_1    | 2021-04-30 20:39:56,996 ERROR  ||  Failed testing connection for jdbc:mysql://my.domain.com:3306/?useInformationSchema=true&nullCatalogMeansCurrent=false&useSSL=false&useUnicode=true&characterEncoding=UTF-8&characterSetResults=UTF-8&zeroDateTimeBehavior=CONVERT_TO_NULL&connectTimeout=30000 with user 'myuser'   [io.debezium.connector.mysql.MySqlConnector]
connect_1    | java.sql.SQLException: The server time zone value 'EDT' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the 'serverTimezone' configuration property) to use a more specifc time zone value if you want to utilize time zone support.
connect_1    |  at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
connect_1    |  at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
connect_1    |  at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
connect_1    |  at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
connect_1    |  at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:73)
connect_1    |  at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:76)
connect_1    |  at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:836)
connect_1    |  at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456)
connect_1    |  at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246)
connect_1    |  at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:197)
connect_1    |  at io.debezium.jdbc.JdbcConnection.lambda$patternBasedFactory$1(JdbcConnection.java:231)
connect_1    |  at io.debezium.jdbc.JdbcConnection.connection(JdbcConnection.java:872)
connect_1    |  at io.debezium.connector.mysql.MySqlConnection.connection(MySqlConnection.java:79)
connect_1    |  at io.debezium.jdbc.JdbcConnection.connection(JdbcConnection.java:867)
connect_1    |  at io.debezium.jdbc.JdbcConnection.connect(JdbcConnection.java:413)
connect_1    |  at io.debezium.connector.mysql.MySqlConnector.validateConnection(MySqlConnector.java:98)
connect_1    |  at io.debezium.connector.common.RelationalBaseSourceConnector.validate(RelationalBaseSourceConnector.java:52)
connect_1    |  at org.apache.kafka.connect.runtime.AbstractHerder.validateConnectorConfig(AbstractHerder.java:375)
connect_1    |  at org.apache.kafka.connect.runtime.AbstractHerder.lambda$validateConnectorConfig$1(AbstractHerder.java:326)
connect_1    |  at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
connect_1    |  at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
connect_1    |  at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
connect_1    |  at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
connect_1    |  at java.base/java.lang.Thread.run(Thread.java:834)
connect_1    | Caused by: com.mysql.cj.exceptions.InvalidConnectionAttributeException: The server time zone value 'EDT' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the 'serverTimezone' configuration property) to use a more specifc time zone value if you want to utilize time zone support.
connect_1    |  at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
connect_1    |  at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
connect_1    |  at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
connect_1    |  at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
connect_1    |  at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:61)
connect_1    |  at com.mysql.cj.exceptions.ExceptionFactory.createException(ExceptionFactory.java:85)
connect_1    |  at com.mysql.cj.util.TimeUtil.getCanonicalTimezone(TimeUtil.java:132)
connect_1    |  at com.mysql.cj.protocol.a.NativeProtocol.configureTimezone(NativeProtocol.java:2120)
connect_1    |  at com.mysql.cj.protocol.a.NativeProtocol.initServerSession(NativeProtocol.java:2143)
connect_1    |  at com.mysql.cj.jdbc.ConnectionImpl.initializePropsFromServer(ConnectionImpl.java:1310)
connect_1    |  at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:967)
connect_1    |  at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:826)
connect_1    |  ... 17 more
connect_1    | 2021-04-30 20:39:56,998 INFO   ||  AbstractConfig values: 
connect_1    |    [org.apache.kafka.common.config.AbstractConfig]

我是否可以通过 Connect rest API 传入一个参数来指定 JDBC 字符串中的时区(显示在此日志顶部附近)?我正在使用 tutorial 的 Debezium (1.5) Docker 映像。

【问题讨论】:

似乎错误提示您修复服务器而不是仅修改驱动程序 是的,它确实说“或”。并且有很多文献说现在需要在 jdbc 字符串中指定时区。连接器没有。 【参考方案1】:

我认为 EDT 不在 mysql.time_zone_name 表中

SELECT * FROM mysql.time_zone_name;

添加配置“database.serverTimezone”解决了我这边的这个问题,例如

"config": 
    ...
    "database.serverTimezone": "America/Los_Angeles",
    ...

【讨论】:

Debezium 连接器通过以database. 开头的属性到 JDBC URL,所以这实际上是要走的路 - 在连接级别设置它。【参考方案2】:

在我的情况下,使用 kafka 连接,我必须修改连接器配置 - mysql 连接字符串(connection.url 属性) 像这样:

jdbc:mysql://<server ip or dns>:<port>?serverTimezone=GMT%2b8:00&<more parameters>

注意:%2b+ 字符。

【讨论】:

以上是关于Kafka Connect MySQL“无法识别服务器时区值‘EDT’”的主要内容,如果未能解决你的问题,请参考以下文章

Kafka Connect JDBC Source MySQL 全量同步

Kafka Connect MySQL“无法识别服务器时区值‘EDT’”

pyflink消费kafka-connect-jdbc消息(带schema)

Confluent Kafka Connect MySQL Sink Connector 的开源替代方案?

不使用 Kafka Connect 复制架构更改

如何使用debezium更改数据捕获在mysql中捕获数据并在kafka connect中使用jdbc sink?