从云数据迁移服务看MySQL大表抽取模式

摘要:MySQL JDBC抽取到底应该采用什么样的方式,且听小编给你娓娓道来。

小编最近在云上的一个迁移项目中被MySQL抽取模式折磨的很惨。一开始爆内存被客户怼,再后来迁移效率低下再被怼。MySQL JDBC抽取到底应该采用什么样的方式,且听小编给你娓娓道来。

Java-JDBC通信原理

JDBC与数据库之间的通信是通过socket完,大致流程如下图所示。Mysql Server ->内核Socket Buffer -> 客户端Socket Buffer ->JDBC所在的JVM

从云数据迁移服务看MySQL大表抽取模式

JDBC读取数据的三种模式 方式1:使用JDBC默认参数读取数据

主要分为以下几步:

1)Mysql Server通过OuputStream 向 Socket Server 本地Kennel Buffer 写入数据,这里是一次内存拷贝。

2)当Socket Server 本地Kennel Buffer 有数据,就会通过TCP链路把数据传输到Socket Client 所在机器的Kennel Buffer。

3)JDBC 所在JVM利用InputSream读取本地Kennel Buffer 数据到JVM内存,没有数据时,则读取被阻塞。

接下来就是不断重复1,2,3的过程。问题是,Socket Client 端的JVM在默认模式下读取Kennel Buffer是没有考虑本机内存大小的,有多少读多少。如果数据太大,就会造成FULL GC,紧接着内存溢出。

参考 JDBC API docs,默认模式 Java demo 代码如下

public static Connection getConnection() throws SQLException { Properties connectionProps = new Properties(); connectionProps.put("user", this.userName); connectionProps.put("password", this.password); Connection conn = DriverManager.getConnection( "jdbc:" + this.dbms + "://" + "127.0.0.1:3306", connectionProps); return conn; } public static void viewTable(Connection con) throws SQLException { String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from COFFEES"; Connection conn = getConnection(); try (Statement stmt = conn.createStatement()) { ResultSet rs = stmt.executeQuery(query); while (rs.next()) { // ... } } catch (SQLException e) { JDBCTutorialUtilities.printSQLException(e); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyggzp.html