Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【bug】批量insert丢数据问题汇总 #2589

Closed
funnyAnt opened this issue Sep 11, 2020 · 3 comments
Closed

【bug】批量insert丢数据问题汇总 #2589

funnyAnt opened this issue Sep 11, 2020 · 3 comments

Comments

@funnyAnt
Copy link
Collaborator

问题

交流群里面很多同学反馈批量Insert 丢数据,此单集中处理

问题可能原因

  • 1、应用用法错误,因为mycat 最新的1.6.7.4及之前的版本都不支持以逗号分隔的批量语句,形如insert aa...;insert bb...;insert cc....;
    此时,应用的SQL里面包含这种语句,或者连接mycat的驱动url里面带有allowMultiQueries=true参数,都会触发这种问题。
    请务必设置allowMultiQueries=false. 群里面反馈的用navicat导入insert 文件,mycat 日志里面出现but no handler大体都是属于这类问题。
  • 2、mycat自身问题
  • 2.1 后端连接连管理有问题,连接被共用。 目前review代码,没有发现这个问题。
  • 2.2 NIO buffer管理有问题,存在多次释放,导致共用,引起包错乱。AbstractConnection.cleanup()这个方法存在并发调用的问题,有这种风险。待加锁解决
  • 2.3 其他,问题待补充
解决方案
  • 1、allowMultiQueries=true问题,创建连接时候直接拦截报错。另外, SQL解析时候遇到多语句直接报错。
  • 2、AbstractConnection.cleanup() 加锁
@cy19900702
Copy link

现在使用的是Mycat-server-1.6.6.1-release-20190104121553.jar这个jar包,然后使用jdbc连接是8066/HAP_MYCAT?allowMultiQueries=true&zeroDateTimeBehavior=convertToNull这种,目前主要批量插入正常情况下没有问题,但是在压测的情况批量插入会出现批量插入超时的问题,导致应用层面出现The last packet successfully received from the server was 415,281 milliseconds ago. The last packet sent successfully to the server was 2 milliseconds ago.或者Caused by: java.net.SocketException: Connection reset或者Caused by: java.sql.SQLException: Could not retrieve transation read-only status server这样的错误。正常情况下没有问题。

@funnyAnt
Copy link
Collaborator Author

funnyAnt commented Oct 1, 2020

@cy19900702 先把allowMultiQueries=false再测试下。Mycat-server-1.6.6.1版本不支持allowMultiQueries=true

@funnyAnt
Copy link
Collaborator Author

funnyAnt commented Oct 1, 2020

901bc47 修复内容如下:

  • 1 连接参数里面出现allowMultiQueries=true,日志记录。PS:完全禁用影响navicat和mysql cmd方式登陆
  • 2 sql里面的带多语句,如“update customer set name=1;update customer set name=2”,在解析时候直接报错
  • 3 AbstractConnection.cleanup() 加锁,防止并发情况下buffer多次释放,导致buffer被多个connection共用,引发数据错乱

测试代码:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestClass1 {

	/**
	 * 使用jdbc 访问MYSQL数据库
	 */
	// 数据库用户名
	private static final String USER = "root";
	// 数据库代码
	private static final String PASSWORD = "123";
	// 数据库url
	private static final String MULTI_QUERIES_URL = "jdbc:mysql://localhost:8066/TESTDB?allowMultiQueries=true";
	private static final String URL = "jdbc:mysql://localhost:8066/TESTDB?allowMultiQueries=false";

	public static void main(String[] args) {
		Connection connection = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			connection = DriverManager.getConnection(MULTI_QUERIES_URL, USER, PASSWORD);
		} catch (Exception e) {
			e.printStackTrace();
	    }

		Statement statement = null;
		try {
			connection = DriverManager.getConnection(URL, USER, PASSWORD);
			statement = connection.createStatement();
			//SQL语句带多语句,会在mycat解析SQL的时候拦截报错
			String sql = "update customer set name=1;update customer set name=2";
			int row_count = statement.executeUpdate(sql);
			
		} catch (Exception e) {
			e.printStackTrace();
		}

	}
}

junwen12221 added a commit that referenced this issue Oct 8, 2020
#2589 批量Insert丢数据问题
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants