hibnate 创建表的时候type=innodb报错

本文介绍了在MySQL5.5及更高版本中如何正确配置InnoDB存储引擎。由于默认存储引擎已更改为InnoDB,因此需要更新配置以确保兼容性和性能。文章提供了具体的代码示例来展示如何定义自定义方言。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个原因是在MYSQL5.5及以后版本中type=InnoDB 由ENGINE=InnoDB  代替。

解决办法,自己定义一个方言:

package com.hotusm.dialect;



/**
 * 
 * @author Hotusm
 *
 *    在MYSQL5.5及以后版本中type=InnoDB 由ENGINE=InnoDB  代替。  
    由于5.5默认的存储引擎就是InnoDB,因此去掉这个属性不会有影响。 
    <code>
        <property name="dialect">com.hotusm.dialect.MYSQLInnoDBDialect</property>
    </code>
 */
public class MYSQLInnoDBDialect extends org.hibernate.dialect.MySQLInnoDBDialect{

    @Override
    public String getTableTypeString() {
        
        return "ENGINE=InnoDB";
    }

    @Override
    public boolean hasSelfReferentialForeignKeyBug() {
        return true;
    }
    
    

}

 

转载于:https://www.cnblogs.com/zr520/p/5420092.html

<think>嗯,用户遇到了MySQL在执行ALTER TABLE ENGINE=InnoDB时出现的锁等待超时问题(错误1205)。这个问题很典型,通常发生在对大进行DDL操作时,特别是在高并发环境中。用户可能正在尝试将MyISAM迁移到InnoDB,或者修复引擎不一致的问题。 从引用内容看,用户提供的参考信息主要集中在锁超时设置(innodb_lock_wait_timeout)和引擎检查上,但实际场景更复杂。这类问题需要系统性的解决思路,因为单纯增加超时阈值可能只是治标不治本——如果特别大或者有长时间事务阻塞,超时时间设得再高也可能失败。 用户的核心痛点是DDL操作被阻塞。这里需要分三层解决: 首先是应急处理,让当前操作能继续; 其次是根本解决,要找到阻塞源; 最后是预防措施,避免再次发生。 注意到引用[3]展示了具体的超时报错日志,说明用户已经观察到超过50秒(10:23:26到10:24:17)的等待。结合MySQL默认50秒的innodb_lock_wait_timeout,这个时间显然不够用于大改造。引用[1]提到的超时回滚机制正是错误1205的直接原因。 深层原因可能有: 长事务未提交(比如未关闭的读写事务) 未提交的显式事务(BEGIN后未COMMIT) 其他DDL/MDL锁冲突 甚至可能是外键约束检查 解决方案需要阶梯式推进: 第一步临时调高超时阈值是必要的,但如引用[1]所述,这需要全局设置(set global)。不过要注意,生产环境调高阈值需谨慎,可能掩盖其他问题。 第二步查杀阻塞事务是关键。引用[2]提到检查引擎的方法,但更重要的是用sys.innodb_lock_waits或information_schema.processlist定位阻塞源。这里有个细节:如果阻塞的是数据导入或报生成等后台任务,可能需要协调停用。 第三步的pt-online-schema-change方案其实最实用。用户可能担心工具复杂性,但实际它通过触发器实现无锁变更,对千万级大特别有效。不过要提醒用户注意外键约束限制,如引用[4]的重复键错误就可能与此相关。 最后补充的预防措施中,业务低峰期操作是常识,但用户容易忽略innodb_online_alter_log_max_size这个参数。当特别大时,默认128M的日志可能不够,会导致在线DDL回退到锁模式——这正是超时的根源之一。 用户可能还会关心:如果超过100GB怎么办?是否需要停机?这就要推荐gh-ost了,它完全不需要触发器,通过binlog流实现变更,不过配置更复杂些。考虑到用户当前需求,先提供基础方案更稳妥。 生成的相关问题覆盖了操作细节(如具体命令)、替代方案(如其他工具)和后续优化(如碎片整理),应该能形成完整的问题解决链路。特别是"如何避免未来出现"这个问题,直指运维规范建设,对用户长期价值更大。</think>以下是针对 MySQL 执行 `ALTER TABLE ENGINE=InnoDB` 时报错 **1205 Lock wait timeout exceeded** 的完整解决方案,结合根本原因分析和操作步骤: --- ### **根本原因分析** 1. **长事务阻塞** 其他未提交的事务(如查询、更新)持有该的元数据锁(MDL)或行锁,导致 `ALTER TABLE` 被阻塞,超过 `innodb_lock_wait_timeout` 时间(默认 **50秒**)后报错[^1][^3]。 2. **大操作耗时** 若数据量庞大,引擎转换需重建,长时间占用锁资源,易被并发事务阻塞。 3. **隐式事务未提交** 应用连接未关闭或未提交事务(如代码中遗漏 `COMMIT`),导致锁持续持有[^2]。 --- ### **解决方案** #### **1. 应急处理:终止阻塞事务** ```sql -- 查看阻塞进程(关注 State='Waiting for table metadata lock' 的会话) SHOW PROCESSLIST; -- 强制终止阻塞事务(替换 <ID> 为阻塞进程的 ID) KILL <ID>; ``` 终止后重试 `ALTER TABLE` 操作[^3]。 #### **2. 临时调高锁等待超时时间** ```sql -- 会话级调整(仅当前会话有效) SET SESSION innodb_lock_wait_timeout = 300; -- 单位:秒 -- 全局调整(需 SUPER 权限,重启失效) SET GLOBAL innodb_lock_wait_timeout = 300; ``` 调整后执行 `ALTER TABLE` 语句: ```sql ALTER TABLE your_table ENGINE=InnoDB; ``` #### **3. 使用 Online DDL 工具(推荐)** 通过第三方工具避免锁,推荐 **Percona Toolkit**: ```bash # 安装 Percona Toolkit sudo apt-get install percona-toolkit # 执行无锁引擎转换 pt-online-schema-change \ --alter "ENGINE=InnoDB" \ D=database_name,t=your_table \ --execute ``` 原理:创建影子异步迁移数据,全程不阻塞读写[^1]。 #### **4. 预防性措施** - **确认引擎状态** ```sql SHOW TABLE STATUS LIKE 'your_table'; -- 检查 Engine 字段 ``` - **检查事务提交模式** ```sql SELECT @@autocommit; -- 确保 autocommit=1(自动提交) SET GLOBAL autocommit=1; -- 全局开启自动提交[^2] ``` - **业务低峰期操作** 避免在高峰时段执行 DDL,减少锁冲突概率。 - **监控长事务** 定期检查未提交事务: ```sql SELECT * FROM information_schema.innodb_trx WHERE TIME_TO_SEC(TIMEDIFF(NOW(), trx_started)) > 60; -- 查找运行超过60秒的事务 ``` --- ### **操作流程总结** ```mermaid graph TD A[遇到错误1205] --> B{检查阻塞进程} B -->|存在阻塞| C[KILL 对应会话] B -->|无阻塞| D[临时调高 innodb_lock_wait_timeout] C --> E[重试 ALTER TABLE] D --> E E -->|仍失败| F[使用 pt-online-schema-change] F --> G[操作成功] ``` --- ### **关键配置参数** | 参数名 | 默认值 | 建议调整值 | 作用 | |----------------------------|--------|------------|--------------------------| | `innodb_lock_wait_timeout` | 50秒 | 300秒 | 锁等待超时时间 | | `autocommit` | 1 | 1 | 确保语句自动提交 | | `innodb_online_alter_log_max_size` | 128M | 1G | Online DDL 日志缓冲区大小 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值