본문 바로가기

프로그래밍(TA, AA)/JVM 언어

[자바] Error: com.mysql.jdbc.PacketTooBigException: Packet for query is too large

max_allowed_packet이란?

네트워크 문제나 MySQL 서버 또는 클라이언트의 버그로 인해 잘못된 패킷이 MySQL 서버로 전달될 경우 MySQL 서버에 심각한 문제를 일으킬 수 있습니다. 이러한 문제점을 없애고자 MySQL 서버는 모든 클라이언트의 패킷이 max_allowed_packet 설정값에 지정된 크기 이하일 것이라고 간주하고 처리하게 됩니다. 만약 max_allowed_packet이 32MB로 설정된 서버에서 실행해야 할 쿼리 문장이 그 이상이 되는 경우에는 이 값을 더 큰 값으로 변경해야 합니다. 이러한 문제는 BLOB나 TEXT 타입의 칼럼에 상당히 큰 데이터를 저장해야 하는 경우에 주로 발생합니다.


MySQL 서버와 통신할 때 클라이언트가 MySQL 서버로 쿼리 요청을 보내는 경우에는 무조건 하나의 패킷만 사용할 수 있으며, 쿼리의 실행 결과는 여러 개의 패킷으로 나눠서 전달받게 됩니다. 그래서 이 설정값은 클라이언트가 서버로 요청하는 쿼리 문장의 길이보다 큰 값으로 설정하기만 하면 됩니다. 




에러 해결 방법

max_allowed_packet 설정 값보다 쿼리 패킷의 값이 더 클때 발생하는 에러입니다.

mysql 설정 파일에서 해당 변수값을 초과한 쿼리 패킷 용량보다 크게 설정하면 해결됩니다.


Caused by: com.mysql.jdbc.PacketTooBigException: Packet for query is too large (1547 > 1024). You can change this value on the server by setting the max_allowed_packet' variable.

        at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3291)

        at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1983)

        at com.mysql.jdbc.MysqlIO.sqlQueryDirect(MysqlIO.java:2163)

        at com.mysql.jdbc.ConnectionImpl.execSQL(ConnectionImpl.java:2624)

        at com.mysql.jdbc.PreparedStatement.executeInternal(PreparedStatement.java:2127)

        at com.mysql.jdbc.PreparedStatement.execute(PreparedStatement.java:1362)

        at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)

        at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)

        at sun.reflect.GeneratedMethodAccessor84.invoke(Unknown Source)

        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

        at java.lang.reflect.Method.invoke(Method.java:606)

        at org.apache.ibatis.logging.jdbc.PreparedStatementLogger.invoke(PreparedStatementLogger.java:58)

        at com.sun.proxy.$Proxy23.execute(Unknown Source)

        at org.apache.ibatis.executor.statement.PreparedStatementHandler.query(PreparedStatementHandler.java:56)

        at org.apache.ibatis.executor.statement.RoutingStatementHandler.query(RoutingStatementHandler.java:70)

        at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:57)

        at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:267)

        at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:141)

        at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:105)

        at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:81)

        at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:101)

        at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:95)

        at sun.reflect.GeneratedMethodAccessor93.invoke(Unknown Source)

        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)

        at java.lang.reflect.Method.invoke(Method.java:606)

        at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:355)



해결방법1) MySQL 커맨드 라인에서 update하여 값 변경

mysql> SET GLOBAL max_allowed_packet = 2048000000;

Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> FLUSH PRIVILEGES;

Query OK, 0 rows affected (0.00 sec)

mysql> show variables where Variable_name = 'max_allowed_packet';

+--------------------+---------+

| Variable_name      | Value   |

+--------------------+---------+

| max_allowed_packet | 2097152 |

+--------------------+---------+

1 row in set (0.00 sec)


해결방법2) /etc/my.cnf 설정파일내 값 변경

> vi /etc/my.cnf

set-variable = max_allowed_packet=2M


변경 확인 방법 입니다.

mysql> show variables where Variable_name = 'max_allowed_packet';

+--------------------+---------+

| Variable_name      | Value   |

+--------------------+---------+

| max_allowed_packet | 2097152 |

+--------------------+---------+

1 row in set (0.00 sec)