[转帖]max_allowed_packet 与 SQL 长度的关系
https://www.oceanbase.com/knowledge-base/oceanbase-database-1000000000210013
租户变量 max_allowed_packet 用于设置最大网络包大小,单位是 Byte。
| 属性 | 描述 |
|---|---|
| 参数类型 | int |
| 默认值 | 4194304 |
| 取值范围 | [1024,1073741824] |
| 生效范围 |
|
| 是否参与序列化 | 是 |
| 是否可修改 | 该变量可通过 SET GLOBAL 语句修改 Global 生效方式下的取值,不可通过 SET SESSION 语句修改 Session 生效方式下的取值。Session 值仅支持查看,且 Session 值只能与 Global 值相同。使用时,客户端与 Server 端一般均需要调整。 |
变量 max_allowed_packet 用于设置客户端与服务端(OBSERVER)传送网络包时允许的最大网络包大小。以 JDBC 为例,当应用使用 JDBC 与 OceanBase 租户建立连接后,JDBC 会向 OceanBase 主动查询该变量的值,从而控制可传输数据的最大长度。 例如,当 max_allowed_packet = 1024、应用端使用 OBClient 连接 OceanBase、使用 PrepareStatement 执行 SQL 时,由于 MySQL 协议规定在传输 PrepareStatement SQL 类型的报文时,需要向该 SQL 中添加 ? 字符,用于标识该 SQL 为 PrepareStatement 类型,因此该 SQL 可允许的最大长度为 max_allowed_packet - 1 = 1023,若超过该长度,则会直接由 JDBC 抛出错误。
query size(1024) >= max_allowed_packet(1024)。
需要注意以下:
- 租户变量
max_allowed_packet设置不合理将会导致各种隐形的问题。 - 设置最大网络包大小的变量
max_allowed_packet使用默认值 4194304 字节时, 若想使用REPEAT()、RPAD()等函数生成长度超过该变量值的目标字符串时,MySQL 模式下会返回 null,Oracle 模式下会返回 VARCHAR 类型的最大长度 32767,与这个参数关系不大。 - 对于 MySQL 模式来讲,若向 LONGTEXT 类型的列中插入超长的字符串时,在某些情况下会发生错误并禁止插入。
相关案例
length 函数与 max_allowed_packet
在使用字符串函数时(如 REPEAT()、RPAD() 等),若预计其生成的目标字符串长度 > max_allowed_packet 值,如果是 MySQL 模式则相关函数返回结果为 null;如果是 Oracle 模式,则与 max_allowed_packet 没有直接关系。
例如在 MySQL 模式下如下示例:当 max_allowed_packet = 2^22(默认值)时,执行以下 SQL 会返回 null:select length(repeat('z', pow(2, 23))) from dual。
<mysql:5.6.25:test>select length(repeat('z',pow(2,23))) from dual;
+-------------------------------+
| length(repeat('z',pow(2,23))) |
+-------------------------------+
| NULL |
+-------------------------------+
1 row in set, 1 warning (0.001 sec)
<mysql:5.6.25:test>show warnings;
+---------+------+-----------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------------------------------------------+
| Warning | 1301 | Result of repeat() was larger than max_allowed_packet (4194304) - truncated |
+---------+------+-----------------------------------------------------------------------------+
1 row in set (0.003 sec)
<mysql:5.6.25:test>select @@max_allowed_packet;
+----------------------+
| @@max_allowed_packet |
+----------------------+
| 4194304 |
+----------------------+
1 row in set (0.001 sec)
因此,若想使用字符串函数生成很长的字符串时,需要保证 max_allowed_packet 的值 >= 该目标字符串的长度。如下示例:设置max_allowed_packet值为pow(2,24),SQL 正常执行。
<mysql:5.6.25:test>select @@max_allowed_packet;
+----------------------+
| @@max_allowed_packet |
+----------------------+
| 16777216 |
+----------------------+
1 row in set (0.001 sec)
<mysql:5.6.25:test>select length(repeat('z',pow(2,23))) from dual;
+-------------------------------+
| length(repeat('z',pow(2,23))) |
+-------------------------------+
| 8388608 |
+-------------------------------+
1 row in set (0.127 sec)
LONGTEXT 字段与 max_allowed_packet
LONGTEXT 作为 OceanBase 数据库 MySQL 模式支持的大对象数据类型,其定义的最大有效长度为 50331648 或 48M 个字符,其可插入的最大有效长度同时也间接地受 max_allowed_packet 的约束。 在使用 SQL 向 LONGTEXT 类型列中插入目标字符串时,该 SQL 长度首先也需满足 max_allowed_packet 的约束,只有满足该约束的情况下,该 SQL 才能顺利传输至 OceanBase 数据库,之后再检查该 SQL 是否满足“插入 LONGTEXT 类型列的目标字符串长度 < 50331648 ”的约束。
例如,在默认启用严格 SQL 模式的 OceanBase 数据库 MySQL 模式中,插入 LONGTEXT 列的目标字符串由应用直接生成,其长度为 length,携带该目标字符串的 INSERT SQL 使用 OBClient 驱动、PrepareStatement 方式执行,该 SQL 的长度为 L。
- 若 L + 1 < max_allowed_packet:此时该 SQL 长度首先满足了
max_allowed_packet的约束。- 当 length < 50331648 时,满足了“插入 LONGTEXT 类型列的目标字符串长度 < 50331648 ”的约束,成功插入。
- 当 length >= 50331648 时,不满足“插入 LONGTEXT 类型列的目标字符串长度 < 50331648 ”的约束,故而报错
Data too long for column ...。
- 若 L + 1 >= max_allowed_packet:此时 SQL 长度首先不满足
max_allowed_packet的约束,直接抛出错误query size >= max_allowed_packet,插入失败。
如下示例:
<mysql:5.6.25:test>select @@max_allowed_packet;
+----------------------+
| @@max_allowed_packet |
+----------------------+
| 50331648 |
+----------------------+
1 row in set (0.001 sec)
<mysql:5.6.25:test>insert into t1 values (1,repeat('z',50331647));
Query OK, 1 row affected (2.157 sec)
<mysql:5.6.25:test>select length(r1) from t1;
+------------+
| length(r1) |
+------------+
| 50331647 |
+------------+
1 row in set (0.064 sec)
<mysql:5.6.25:test>insert into t1 values (2,repeat('z',50331649));
Query OK, 1 row affected, 1 warning (0.006 sec)
<mysql:5.6.25:test>show warnings;
+---------+------+------------------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+------------------------------------------------------------------------------+
| Warning | 1301 | Result of repeat() was larger than max_allowed_packet (50331648) - truncated |
+---------+------+------------------------------------------------------------------------------+
1 row in set (0.034 sec)
<mysql:5.6.25:test>select length(r1) from t1;
+------------+
| length(r1) |
+------------+
| 50331647 |
| NULL |
+------------+
2 rows in set (0.002 sec)
适用版本
OceanBase 数据库 V2.x 和 V3.x 版本。
[转帖]max_allowed_packet 与 SQL 长度的关系的更多相关文章
- mysql sql长度限制解决
mysql sql长度限制解决 今天发现了一个错误: Could not execute JDBC batch update 最后发现原因是SQL语句长度大于1M,而我机器上的mysql是 ...
- [转帖]EXPDP dumpfile和parallel的关系
http://blog.itpub.net/28602568/viewspace-2133375/ 转帖 EXPDP 里面 parallel 与 dumpfile 里面的文件数的关系. 但是我这里有一 ...
- (转帖)oracle sql 语句优化
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...
- [转帖]oracle改版sql server问题点汇总
https://www.cnblogs.com/zhangdk/p/oracle_sqlserver.html 只记得 最开始的时候看过 没有具体的了解里面的特点 原作者总结的很好 留下来 以后说不定 ...
- java.util.Date与java.sql.Date的关系和转换方法(转)
在ResultSet中我们经常使用的setDate或getDate的数据类型是java.sql.Date,而在平时java程序中我们一般习惯使用 java.util.Date. 因此在DAO层我们经常 ...
- 【转帖】关于sql server 2008 的mdf收缩问题
原帖地址:http://social.msdn.microsoft.com/forums/windowsazure/pt-br/388f92e1-9a1e-497d-bde1-6664561fd44e ...
- Hibernate 三种状态变化 与 sql 语句的关系
前言:在Hibernate中有三种状态,对它的深入理解,才能更好的理解hibernate的运行机理,刚开始不太注意这些概念,后来发现它是重要的.对于理解hibernate,JVM和sql的关系有更好的 ...
- (一)DB、DBMS、SQL之间的关系
一.概念 DB:数据库(database)相当于一个仓库,用于有组织的采存储数据. DBMS:数据库管理系统(database manage system)数据库是通过DBMS来创建和操作,种类很多( ...
- 知方可补不足~Sqlserver发布订阅与sql事务的关系
回到目录 前几讲说了一下通过sqlserver的发布与订阅来实现数据的同步,再通过EF这个ORM架构最终实现架构系统的读写分离,而在使用发布与订阅来实现数据同步时,需要我们注意几点,那就是当操作被使用 ...
- SQL笔记----在一个关系表中操作列
使用alter关键字,可以为一个表添加新的列. 比如: 给Persons的表中添加一列,名字为Birthday,类型是date. ALTER TABLE Persons ADD Birthday da ...
随机推荐
- STM32CubeMX教程1 工程建立
1.准备材料 开发板(STM32F407G-DISC1) ST-LINK/V2驱动 STM32CubeMX软件(Version 6.10.0) keil µVision5 IDE(MDK-Arm) 2 ...
- Windows Server 2016 Standard RemoteApp应用发布配置举例
RemoteApp 应用发布介绍 RemoteApp 是微软在Windows Server 2008 之后,在其系统中集成的一项服务功能,用户可以通过远程桌面访问远端服务器的桌面与程序,客户端本机在无 ...
- 在ubuntu下将virtualbox虚拟机的磁盘重设大小的方法
1.VBoxManage modifyhd /home/beyond/xxx.vdi --resize 20480 {20480(单位:M)是你要扩容之后的总大小,/home/beyond 是你存放 ...
- Spring Boot 整合 Log4j2 日志并压测性能
1/ Log4j2的性能测试 从图中不难看出,在线程数为 2~16 之间,混合使用同步和异步的logger来打印日志,性能是最好的. 2/ 目标 混合 sync/async 彩色日志 分类输出到不同文 ...
- 克服 ClickHouse 运维难题:ByteHouse 水平扩容功能上线
前言 对于分析型数据库产品,通过增加服务节点实现集群水平扩容,并提升集群性能和容量,是运维的必要手段. 但是对于熟悉 ClickHouse 的工程师而言,听到"扩容"二字一定会头疼 ...
- 火山引擎数智平台协助洞察美图类APP新增长,付费用户转化超过 124%
更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群 美图类 APP 的下一个增长点在哪里? 目前,国内市场上的美图类 APP 大多都遵循着基础功能免费使用.个性化热门 ...
- # github.com/coreos/etcd/clientv3/balancer/resolver/endpoint
linux使用go连接etcd集群时报错: # github.com/coreos/etcd/clientv3/balancer/resolver/endpoint /root/go/pkg/mod/ ...
- Grafana--变量(label_values)
grafana官方文档:https://grafana.com/docs/grafana/latest/ 版本:6.5.2 模板与变量(摘抄自官方文档): 变量是值的占位符.您可以在度量查询和面板标题 ...
- Java kafka 设置从指定时间戳开始消费
包含的功能: 1.Java kafka 设置从指定时间戳开始消费 2.JdbcTemplate操作MySql 3.Java多线程消费kafka 4.Java获取kafka所有topic pom.xml ...
- 题解| CF1561D2. Up the Strip(递推)
题目链接:Here 这个思路学习自 Harris-H ,考虑递推而不是DP 与 D1 不同,开始考虑 \(f_{i-1} \to f_i\) 显然操作 1 多了 \(f_{i-1}\) ,操作2 多了 ...