
文章目录
- 一、背景
- 二、说明
- 三、页面及代码
- 四、错误场景
-
- [错误场景1:org.springframework.orm.jpa.JpaSystemException: could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement](#错误场景1:org.springframework.orm.jpa.JpaSystemException: could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement)
- [错误场景2:ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''alarm_data' ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8' at line 1](#错误场景2:ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''alarm_data' ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8' at line 1)
- 本人其他相关文章链接
一、背景
节省磁盘空间
- InnoDB 表:可节省 30%-70% 磁盘空间
- MyISAM 表:通过优化可节省 5%-20% 空间
提高 I/O 性能
- 数据在磁盘上压缩存储
- 读取时解压到内存
- 减少磁盘 I/O 操作
二、说明
说明点1:问题1:他这个压缩最后产出的是啥,是个zip?tar?
答案
:不是zip或tar文件,没有产出任何压缩包文件!
这个方法只是在数据库内部对表的存储格式进行压缩,产出的是:
- 更紧凑的数据库表文件(对于InnoDB存储引擎生成.ibd文件;MyISAM存储引擎会生成3种文件,后缀名不同:表名.MYD - 数据文件(My Data)、表名.MYI - 索引文件(My Index) 、表名.frm - 表结构文件(格式定义))
- 更小的磁盘占用空间
- 优化后的表结构
说明点2:问题2:他这个压缩不是吧数据库备份生成sql文件压缩,而是直接把数据库进行压缩?
答案
:是的,是直接压缩数据库表本身,不是备份文件!
说明点3:问题3:如果是问题2那样的,那数据库压缩和数据库备份岂不是不相干,各干个的?
答案
:完全正确!这个方法与数据库备份毫不相干,各干各的!
说明点4:问题4:InnoDB压缩和MyISAM压缩区别?
答案
:
说明点5:有多种直观方法查看压缩是否成功
方法1:查看表状态信息(最直接)
java
-- 查看所有表的行格式和压缩状态
SELECT
TABLE_NAME,
ENGINE,
ROW_FORMAT,
TABLE_ROWS,
DATA_LENGTH as '数据大小(字节)',
INDEX_LENGTH as '索引大小(字节)',
round(((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024), 2) as '总大小(MB)'
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = '你的数据库名';
压缩成功的关键指标
:
ROW_FORMAT 显示为 Compressed
DATA_LENGTH 明显减小
方法2:查看文件系统大小变化
java
# 进入MySQL数据目录
cd /var/lib/mysql/你的数据库名
# 查看文件大小
ls -lh *.ibd # 查看InnoDB表文件大小
ls -lh *.MYD # 查看MyISAM数据文件大小
# 或者查看总大小变化
du -sh . # 查看整个数据库目录大小
方法3:查看MySQL错误日志
java
-- 压缩过程中如有问题会在错误日志中显示
-- 查看日志位置
SHOW VARIABLES LIKE 'log_error';
-- 或者查看最近的操作记录
SHOW ENGINE INNODB STATUS;
预期看到的成功迹象
:
- 文件大小明显减小(可能减少30%-70%)
- ROW_FORMAT显示为Compressed
- data_free碎片空间接近0
- 查询performance_schema可能显示压缩操作完成
最直观的方法就是对比压缩前后的文件大小和ROW_FORMAT字段的变化!
说明点6 数据库压缩执行就这3步
java
select ENGINE,TABLE_NAME from information_schema.TABLES WHERE TABLE_SCHEMA = '数据库名'
ALTER TABLE 表名 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8
OPTIMIZE TABLE 表名
第1步命令作用:查询数据库下所有表
第2步命令作用:这是 InnoDB 的页级压缩功能:
java
-- 作用:启用 InnoDB 表的透明压缩
ALTER TABLE table_name ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
工作原理
:
- 将数据分成 8KB 的块(KEY_BLOCK_SIZE=8)
- 每个块用 zlib 算法单独压缩
- 压缩后的数据存储在磁盘上
- 读取时自动解压缩到内存
效果
:
- 磁盘空间减少 30%-70%
- 内存中仍是未压缩格式,性能影响较小
- I/O 操作减少(因为读取的数据量变小)
第3步命令作用:这是通用的表维护命令:
java
-- 作用:重建表,整理碎片
OPTIMIZE TABLE table_name;
工作原理
:
- 重建表的物理存储
- 回收未使用的空间
- 整理数据碎片
- 更新索引统计信息
效果
:
- 减少存储空间
- 提高查询性能
- 对所有存储引擎都有效
为什么不同引擎要区别对待:
InnoDB 的处理:
java
// InnoDB:压缩 + 优化
ALTER TABLE table_name ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; // 🎯 启用压缩
OPTIMIZE TABLE table_name; // 🧹 整理碎片
原因
:
- InnoDB 支持透明的页级压缩
- 先启用压缩,再整理碎片获得最佳效果
MyISAM 和其他引擎的处理:
java
// MyISAM/其他:只优化
OPTIMIZE TABLE table_name; // 🧹 只整理碎片
原因
:
- MyISAM 不支持 ROW_FORMAT=COMPRESSED
- MyISAM 有自己的压缩工具 myisampack,但需要离线操作
- 其他引擎可能也不支持压缩

三、页面及代码

DatabaseManageControl
java
@Operation(summary = "数据库压缩")
@GetMapping(value = "/tarDatabase")
public ResponseModel tarDatabase() {
return databaseManageUserControl.tarDatabase();
}
DatabaseManageUserControl
java
public ResponseModel<String> tarDatabase() {
String databaseName = configValue.obtainConfigValue("xnms.service.center.DSDatabaseName");;
SingleResponse<Boolean> booleanSingleResponse = clientService.tarDatabase(databaseName);
Boolean isSuccess = booleanSingleResponse.getData();
if (!isSuccess) {
return ResponseModel.ofError(languageFind.findKey("TarFailed"));
}
Account account = (Account) SecurityUtils.getSubject().getPrincipal();
clientService.clientLog(account.getUserName(), ClientLogType.LogDataBaseManager, ClientSubLogType.LogDataBaseManager_CompressDB, "DatabaseCompressSuccess", account.getIp());
return ResponseModel.ofSuccess(languageFind.findKey("TarSuccess"));
}
application-cvt.properties
java
xnms.service.center.DSDatabaseName=cvt_db
ClientService
java
SingleResponse<Boolean> tarDatabase(String databaseName);
ClientServiceI
java
@Override
public SingleResponse<Boolean> tarDatabase(String databaseName) {
SingleResponse<Boolean> singleResponse = new SingleResponse<>();
try {
singleResponse.setData(dataBase.tarDatabase(databaseName));
singleResponse.setSuccess(true);
} catch (Exception ex) {
logger.error("[DataBaseI] TarDatabase error: " + ex.getMessage(), ex);
singleResponse.setSuccess(false);
singleResponse.setMsg(ex.getMessage());
}
return singleResponse;
}
DataBaseServImpl
java
public boolean tarDatabase(String databaseName) {
try {
systemDao.tarDatabase(databaseName);
return true;
} catch (Exception e) {
// Log the exception (optional)
logger.error("Error during database tar operation: " + e.getMessage(), e);
return false;
}
}
SystemDao
java
void tarDatabase(String databaseName);
SystemDaoImpl
java
@Transactional
@Override
public void tarDatabase(String databaseName) {
String selectSql = "SELECT ENGINE,TABLE_NAME FROM information_schema.tables WHERE TABLE_SCHEMA= :databaseName";
Query selectQuery = entityManager.createNativeQuery(selectSql, InformationSchemaEntity.class);
selectQuery.setParameter("databaseName", databaseName);
List<InformationSchemaEntity> list = selectQuery.getResultList();
for (InformationSchemaEntity item : list ) {
if (item.getEngine().equalsIgnoreCase("InnoDB")) {
String alterSql = "ALTER TABLE " + item.getTableName() + " ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8";
Query alterQuery = entityManager.createNativeQuery(alterSql);
alterQuery.executeUpdate();
}
String optimizeSql = "OPTIMIZE TABLE " + item.getTableName();
Query optimizeQuery = entityManager.createNativeQuery(optimizeSql);
optimizeQuery.getResultList();
}
}
四、错误场景
错误场景1:org.springframework.orm.jpa.JpaSystemException: could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement
完整错误
java
2025-10-10 11:20:59.298 [http-nio-61000-exec-8] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Can not issue executeUpdate() or executeLargeUpdate() with statements that produce result sets
2025-10-10 11:20:59.308 [http-nio-61000-exec-8] ERROR c.x.d.service.service.impl.client.DataBaseServImpl - Error during database tar operation: could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement
org.springframework.orm.jpa.JpaSystemException: could not execute statement; nested exception is org.hibernate.exception.GenericJDBCException: could not execute statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:331)
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:233)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:551)
at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:152)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:388)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:708)
at com.xnms.data.service.dao.mysql.impl.SystemDaoImpl$$EnhancerBySpringCGLIB$$b7963bdd.tarDatabase(<generated>)
at com.xnms.data.service.service.impl.client.DataBaseServImpl.tarDatabase(DataBaseServImpl.java:99)
at com.xnms.data.service.service.impl.client.DataBaseServImpl$$FastClassBySpringCGLIB$$bf1fe8d7.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy.invokeMethod(CglibAopProxy.java:386)
at org.springframework.aop.framework.CglibAopProxy.access$000(CglibAopProxy.java:85)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:704)
at com.xnms.data.service.service.impl.client.DataBaseServImpl$$EnhancerBySpringCGLIB$$24daa3c3.tarDatabase(<generated>)
at com.xnms.data.service.controller.client.ClientServiceI.tarDatabase(ClientServiceI.java:473)
at com.xnms.data.service.controller.client.ClientServiceI$$FastClassBySpringCGLIB$$a830f508.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy.invokeMethod(CglibAopProxy.java:386)
at org.springframework.aop.framework.CglibAopProxy.access$000(CglibAopProxy.java:85)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:704)
at com.xnms.data.service.controller.client.ClientServiceI$$EnhancerBySpringCGLIB$$9dda6ef6.tarDatabase(<generated>)
at com.xnms.client.service.view.system.mangment.DatabaseManageUserControl.tarDatabase(DatabaseManageUserControl.java:135)
at com.xnms.client.service.controller.system.management.DatabaseManageControl.tarDatabase(DatabaseManageControl.java:50)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1071)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:964)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:670)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:779)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:112)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:61)
at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
at org.apache.shiro.web.servlet.AdviceFilter.executeChain(AdviceFilter.java:108)
at org.apache.shiro.web.servlet.AdviceFilter.doFilterInternal(AdviceFilter.java:137)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.apache.shiro.web.servlet.ProxiedFilterChain.doFilter(ProxiedFilterChain.java:66)
at org.apache.shiro.web.servlet.AbstractShiroFilter.executeChain(AbstractShiroFilter.java:449)
at org.apache.shiro.web.servlet.AbstractShiroFilter$1.call(AbstractShiroFilter.java:365)
at org.apache.shiro.subject.support.SubjectCallable.doCall(SubjectCallable.java:90)
at org.apache.shiro.subject.support.SubjectCallable.call(SubjectCallable.java:83)
at org.apache.shiro.subject.support.DelegatingSubject.execute(DelegatingSubject.java:387)
at org.apache.shiro.web.servlet.AbstractShiroFilter.doFilterInternal(AbstractShiroFilter.java:362)
at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:125)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:177)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:541)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:360)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:891)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1784)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: org.hibernate.exception.GenericJDBCException: could not execute statement
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113)
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:200)
at org.hibernate.engine.query.spi.NativeSQLQueryPlan.performExecuteUpdate(NativeSQLQueryPlan.java:107)
at org.hibernate.internal.SessionImpl.executeNativeUpdate(SessionImpl.java:1554)
at org.hibernate.query.internal.NativeQueryImpl.doExecuteUpdate(NativeQueryImpl.java:299)
at org.hibernate.query.internal.AbstractProducedQuery.executeUpdate(AbstractProducedQuery.java:1696)
at com.xnms.data.service.dao.mysql.impl.SystemDaoImpl.tarDatabase(SystemDaoImpl.java:240)
at com.xnms.data.service.dao.mysql.impl.SystemDaoImpl$$FastClassBySpringCGLIB$$42f84ff5.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:793)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:763)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:137)
... 96 common frames omitted
Caused by: java.sql.SQLException: Can not issue executeUpdate() or executeLargeUpdate() with statements that produce result sets
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1038)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1009)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1320)
at com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:994)
at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61)
at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java)
at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:197)
... 107 common frames omitted
代码
java
@Transactional
@Override
public void tarDatabase(String databaseName) {
String selectSql = "SELECT `TABLE_NAME` FROM information_schema.tables WHERE TABLE_SCHEMA= :databaseName";
Query selectQuery = entityManager.createNativeQuery(selectSql);
selectQuery.setParameter("databaseName", databaseName);
List<String> tableNames = selectQuery.getResultList();
for (String tableName : tableNames ) {
String alterSql = "ALTER TABLE " + tableName + " ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8";
Query alterQuery = entityManager.createNativeQuery(alterSql);
alterQuery.executeUpdate();
String optimizeSql = "OPTIMIZE TABLE " + tableName;
Query optimizeQuery = entityManager.createNativeQuery(optimizeSql);
optimizeQuery.executeUpdate();
}
}
原因
:这个错误是因为 OPTIMIZE TABLE 语句会返回结果集,但你在使用 executeUpdate() 方法,这个方法只能用于不返回结果集的语句。
问题分析
:
ALTER TABLE → 不返回结果集 → 可以用 executeUpdate()
OPTIMIZE TABLE → 返回优化结果信息 → 不能用 executeUpdate()
解决方案
:
java
String optimizeSql = "OPTIMIZE TABLE " + item.getTableName();
Query optimizeQuery = entityManager.createNativeQuery(optimizeSql);
optimizeQuery.getResultList();
错误场景2:ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''alarm_data' ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8' at line 1
完整错误
java
2025-10-10 11:02:16.697 [http-nio-61000-exec-3] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''alarm_data' ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8' at line 1
2025-10-10 11:02:16.717 [http-nio-61000-exec-3] ERROR c.x.d.service.service.impl.client.DataBaseServImpl - Error during database tar operation: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement
org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute statement; SQL [n/a]; nested exception is org.hibernate.exception.SQLGrammarException: could not execute statement
at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:259)
错误代码
java
@Override
public void tarDatabase(String databaseName) {
String selectSql = "SELECT `TABLE_NAME` FROM information_schema.tables WHERE TABLE_SCHEMA= :databaseName";
Query selectQuery = entityManager.createNativeQuery(selectSql, String.class);
selectQuery.setParameter("databaseName", databaseName);
List<String> tableNames = selectQuery.getResultList();
for (String tableName : tableNames ) {
String alterSql = "ALTER TABLE :tableName ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8";
Query alterQuery = entityManager.createNativeQuery(alterSql);
alterQuery.setParameter("tableName", tableName);
alterQuery.executeUpdate();
String optimizeSql = "OPTIMIZE TABLE :tableName";
Query optimizeQuery = entityManager.createNativeQuery(optimizeSql);
optimizeQuery.setParameter("tableName", tableName);
optimizeQuery.executeUpdate();
}
}
原因
:问题在于:表名不能使用参数绑定!
问题分析
:在SQL中,表名、列名等数据库对象标识符不能使用参数化查询,只有值可以使用参数绑定。
解决方案:
java
@Transactional
@Override
public void tarDatabase(String databaseName) {
String selectSql = "SELECT ENGINE,TABLE_NAME FROM information_schema.tables WHERE TABLE_SCHEMA= :databaseName";
Query selectQuery = entityManager.createNativeQuery(selectSql, InformationSchemaEntity.class);
selectQuery.setParameter("databaseName", databaseName);
List<InformationSchemaEntity> list = selectQuery.getResultList();
for (InformationSchemaEntity item : list ) {
if (item.getEngine().equalsIgnoreCase("InnoDB")) {
String alterSql = "ALTER TABLE " + item.getTableName() + " ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8";
Query alterQuery = entityManager.createNativeQuery(alterSql);
alterQuery.executeUpdate();
}
String optimizeSql = "OPTIMIZE TABLE " + item.getTableName();
Query optimizeQuery = entityManager.createNativeQuery(optimizeSql);
optimizeQuery.getResultList();
}
}