mysql数据库压缩
文章目录
- 一、背景
- 二、说明
- 说明点1:问题1:他这个压缩最后产出的是啥,是个zip?tar?
- 说明点2:问题2:他这个压缩不是吧数据库备份生成sql文件压缩,而是直接把数据库进行压缩?
- 说明点3:问题3:如果是问题2那样的,那数据库压缩和数据库备份岂不是不相干,各干个的?
- 说明点4:问题4:InnoDB压缩和MyISAM压缩区别?
- 说明点5:有多种直观方法查看压缩是否成功
- 说明点6 数据库压缩执行就这3步
- 三、页面及代码
- DatabaseManageControl
- DatabaseManageUserControl
- application-cvt.properties
- ClientService
- ClientServiceI
- DataBaseServImpl
- SystemDao
- SystemDaoImpl
- 四、错误场景
- 错误场景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
- 本人其他相关文章链接
一、背景
节省磁盘空间
- 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:查看表状态信息(最直接)
-- 查看所有表的行格式和压缩状态
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:查看文件系统大小变化
# 进入MySQL数据目录
cd /var/lib/mysql/你的数据库名# 查看文件大小
ls -lh *.ibd # 查看InnoDB表文件大小
ls -lh *.MYD # 查看MyISAM数据文件大小# 或者查看总大小变化
du -sh . # 查看整个数据库目录大小
方法3:查看MySQL错误日志
-- 压缩过程中如有问题会在错误日志中显示
-- 查看日志位置
SHOW VARIABLES LIKE 'log_error';-- 或者查看最近的操作记录
SHOW ENGINE INNODB STATUS;
预期看到的成功迹象
:
- 文件大小明显减小(可能减少30%-70%)
- ROW_FORMAT显示为Compressed
- data_free碎片空间接近0
- 查询performance_schema可能显示压缩操作完成
最直观的方法就是对比压缩前后的文件大小和ROW_FORMAT字段的变化!
说明点6 数据库压缩执行就这3步
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 的页级压缩功能:
-- 作用:启用 InnoDB 表的透明压缩
ALTER TABLE table_name ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8;
工作原理
:
- 将数据分成 8KB 的块(KEY_BLOCK_SIZE=8)
- 每个块用 zlib 算法单独压缩
- 压缩后的数据存储在磁盘上
- 读取时自动解压缩到内存
效果
:
- 磁盘空间减少 30%-70%
- 内存中仍是未压缩格式,性能影响较小
- I/O 操作减少(因为读取的数据量变小)
第3步命令作用:这是通用的表维护命令:
-- 作用:重建表,整理碎片
OPTIMIZE TABLE table_name;
工作原理
:
- 重建表的物理存储
- 回收未使用的空间
- 整理数据碎片
- 更新索引统计信息
效果
:
- 减少存储空间
- 提高查询性能
- 对所有存储引擎都有效
为什么不同引擎要区别对待:
InnoDB 的处理:
// InnoDB:压缩 + 优化
ALTER TABLE table_name ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; // 🎯 启用压缩
OPTIMIZE TABLE table_name; // 🧹 整理碎片
原因
:
- InnoDB 支持透明的页级压缩
- 先启用压缩,再整理碎片获得最佳效果
MyISAM 和其他引擎的处理:
// MyISAM/其他:只优化
OPTIMIZE TABLE table_name; // 🧹 只整理碎片
原因
:
- MyISAM 不支持 ROW_FORMAT=COMPRESSED
- MyISAM 有自己的压缩工具 myisampack,但需要离线操作
- 其他引擎可能也不支持压缩
三、页面及代码
DatabaseManageControl
@Operation(summary = "数据库压缩")
@GetMapping(value = "/tarDatabase")
public ResponseModel tarDatabase() {return databaseManageUserControl.tarDatabase();
}
DatabaseManageUserControl
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
xnms.service.center.DSDatabaseName=cvt_db
ClientService
SingleResponse<Boolean> tarDatabase(String databaseName);
ClientServiceI
@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
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
void tarDatabase(String databaseName);
SystemDaoImpl
@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
完整错误
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 statementat 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 statementat 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 setsat 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
代码
@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()
解决方案
:
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
完整错误
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 statementat org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:259)
错误代码
@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中,表名、列名等数据库对象标识符不能使用参数化查询,只有值可以使用参数绑定。
解决方案:
@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.mysql数据库备份
2.mysql数据库压缩