解決DataX支持Mysql 8的讀寫


  前言:如果是第一次安裝使用datax,或您服務器Mysql版本是 <= 5.7的,請先參考我之前的隨筆:https://www.cnblogs.com/zifan/p/9194793.html

  背景:Mysql從5.6升級到8.0.19之后,發現原先正常跑的datax出錯了。

  先來看下我的報錯信息:(看不清請放大網頁)

 1 2020-03-18 10:00:10.038 [0-0-0-writer] ERROR StdoutPluginCollector - 
 2 java.sql.SQLException: Could not retrieve transation read-only status server
 3 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:996) ~[mysql-connector-java-5.1.34.jar:5.1.34]
 4 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:935) ~[mysql-connector-java-5.1.34.jar:5.1.34]
 5 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:924) ~[mysql-connector-java-5.1.34.jar:5.1.34]
 6 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:870) ~[mysql-connector-java-5.1.34.jar:5.1.34]
 7 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:902) ~[mysql-connector-java-5.1.34.jar:5.1.34]
 8 at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:892) ~[mysql-connector-java-5.1.34.jar:5.1.34]
 9 at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3607) ~[mysql-connector-java-5.1.34.jar:5.1.34]
10 at com.mysql.jdbc.ConnectionImpl.isReadOnly(ConnectionImpl.java:3576) ~[mysql-connector-java-5.1.34.jar:5.1.34]
11 at com.mysql.jdbc.PreparedStatement.checkReadOnlySafeStatement(PreparedStatement.java:1114) ~[mysql-connector-java-5.1.34.jar:5.1.34]
12 at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1134) ~[mysql-connector-java-5.1.34.jar:5.1.34]
13 at com.alibaba.datax.plugin.rdbms.writer.CommonRdbmsWriter$Task.doOneInsert(CommonRdbmsWriter.java:382) [plugin-rdbms-util-0.0.1-SNAPSHOT.jar:na]
14 at com.alibaba.datax.plugin.rdbms.writer.CommonRdbmsWriter$Task.doBatchInsert(CommonRdbmsWriter.java:362) [plugin-rdbms-util-0.0.1-SNAPSHOT.jar:na]
15 at com.alibaba.datax.plugin.rdbms.writer.CommonRdbmsWriter$Task.startWriteWithConnection(CommonRdbmsWriter.java:297) [plugin-rdbms-util-0.0.1-SNAPSHOT.jar:na]
16 at com.alibaba.datax.plugin.rdbms.writer.CommonRdbmsWriter$Task.startWrite(CommonRdbmsWriter.java:319) [plugin-rdbms-util-0.0.1-SNAPSHOT.jar:na]
17 at com.alibaba.datax.plugin.writer.mysqlwriter.MysqlWriter$Task.startWrite(MysqlWriter.java:78) [mysqlwriter-0.0.1-SNAPSHOT.jar:na]
18 at com.alibaba.datax.core.taskgroup.runner.WriterRunner.run(WriterRunner.java:56) [datax-core-0.0.1-SNAPSHOT.jar:na]
19 at java.lang.Thread.run(Thread.java:748) [na:1.8.0_241]
20 Caused by: java.sql.SQLException: Unknown system variable 'tx_read_only'
View Code

  只需關注第一行和最后一行。第一行你去百度,部分資料會告訴你讓你設置下數據庫“事務隔離級別”,參考:https://www.cnblogs.com/jeffen/p/6005410.html

SET GLOBAL transaction_isolation='READ-COMMITTED';

  本人也嘗試過,對Mysql8而言報錯依舊,不過其它mysql版本可以嘗試該解決方案。參考:https://www.cnblogs.com/lewic/p/10685004.html,發現最終原因應該還是驅動版本不問題。

  再來關注最后一行:java.sql.SQLException: Unknown system variable 'tx_read_only',大部分的資料表明是驅動版本不一致的問題。總結以上,致命原因只有一個,就是“mysql的驅動版本不對”,所以解決方案自然就是升級驅動了。

  首先查看下原來的驅動:

ll {%Datax_Path}/plugin/writer/mysqlwriter/libs/ | grep mysql-con

  截至2020/03/23,GitHub上下載的最新datax tar包 所包含的mysql驅動是mysql-connector-java-5.1.34.jar。的確不匹配啊,此時有人會第一時間想到從網上直接下載8的驅動丟進去或替換就好了,

  參考:https://blog.csdn.net/jason_9527/article/details/100995505

  思路沒問題,不過不能徹底解決問題,而且會有一些error、warning出來。比如:

1、ERROR: zeroDateTimeBehavior=convertToNull要改為CONVERT_TO_NULL

2、WARN: Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary. 3、WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.

  所以我們要采用“修改源碼,自行編譯”的方式來徹底解決所有問題。參考:http://www.manongjc.com/detail/14-iexdburliccybhe.html

  第一步下載源碼:

  git clone方式或直接https://github.com/alibaba/DataX/archive/master.zip下載。

  第二步修改mysql-connector-java驅動的版本號:

  找到位於 {DataX_source_code_home}/mysqlreader/ 和 {DataX_source_code_home}/mysqlwriter/ 下的pom.xml文件,將version的值改為8.0.X(可以直接搜索‘mysql-connector-java’快速定位,X寫你自己想要的版本號)

 如果你只用到了mysql的寫,可以只修改mysqlwriter目錄下的xml文件。

  第三步修改zeroDateTimeBehavior的值convertToNull 為 CONVERT_TO_NULL:

  編輯{DataX_source_code_home}/plugin-rdbms-util/src/main/java/com/alibaba/datax/plugin/rdbms/util/DataBaseType.java

  全文替換 convertToNull 為 CONVERT_TO_NULL

# 自行檢索 {DataX_source_code_home}/文件夾下所有包含convertToNull字符串的文件,定位到文件再替換
vim {DataX_source_code_home}/plugin-rdbms-util/src/main/java/com/alibaba/datax/plugin/rdbms/util/DataBaseType.java # 然后命令模式下全文替換 :%s/convertToNull/CONVERT_TO_NULL/

  到此,如果跳過第四、五步直接打包datax,程序已經能正確運行,如果想完美解決其他警告,請按步驟繼續。

  第四步修改jdbc驅動的名稱com.mysql.jdbc.Driver 為 com.mysql.cj.jdbc.Driver

vi {DataX_source_code_home}/plugin-rdbms-util/src/main/java/com/alibaba/datax/plugin/rdbms/util/DataBaseType.java
vi {DataX_source_code_home}/adswriter/src/main/java/com/alibaba/datax/plugin/writer/adswriter/load/AdsHelper.java

  全文替換 com.mysql.jdbc.Driver 為 com.mysql.cj.jdbc.Driver。

  第五步jdbc鏈接追加useSSL=false設置

  比如:python datax.py file.json , 則file.json的配置項:"jdbcUrl":"jdbc:mysql://${writer_gateway}/oms?useUnicode=true&characterEncoding=UTF-8&useSSL=false",

  第六步通過maven打包:(本人是參考Git上開發者提供的操作步驟來的)

cd {DataX_source_code_home}
mvn -U clean package assembly:assembly -Dmaven.test.skip=true

  打包成功,日志顯示如下:

[INFO] BUILD SUCCESS
[INFO] -----------------------------------------------------------------
[INFO] Total time: 08:12 min
[INFO] Finished at: 2015-12-13T16:26:48+08:00
[INFO] Final Memory: 133M/960M
[INFO] -----------------------------------------------------------------

  打包成功后的DataX包位於 {DataX_source_code_home}/target/datax/datax/ ,查看datax/plugin/writer/mysqlwriter/libs/目錄,已經包含新版的驅動jar包

  最后一步:

  就是把datax移動到你希望的位置,然后執行:python datax.py ./file.json,至此,OVER

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM