mysql创建索引导致锁表阻塞查询

在Oracle至MySQL数据库迁移过程中,团队成员对同一表进行不同操作时可能遇到索引冲突,导致操作停滞。文章详细解析了MySQL的Waiting for table metadata lock现象,及其对业务的潜在影响,并提供了解决方案,包括如何通过kill慢SQL进程快速解决索引创建延迟。
部署运行你感兴趣的模型镜像

在数据库oracle迁移到mysql的过程中,因为团队每个人都负责了一些模块,难免会对表的操作有冲突,比如我正在给这张表创建索引,但是他却在进行查询,这样就会导致双方都失败。

正所谓MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景。而且,一旦alter table TableA的操作停滞在Waiting for table metadata lock的状态,后续对TableA的任何操作(包括读)都无法进行,因为他们也会在Opening tables的阶段进入到Waiting for table metadata lock的锁等待队列。如果是产品环境的核心表出现了这样的锁等待队列,就会造成灾难性的后果

解决方法通过命令查看慢查询:
select * from information_schema.processlist where command not in (‘Sleep’)
发现有慢SQL,针对该表。
解决方式:kill掉慢SQL进程,索引添加立刻完成

附上慢sql问题解析:

ALL, index, range, ref, eq_ref, const, system, NULL

ALL:Full Table Scan, MySQL将遍历全表以找到匹配的行
index:Full Index Scan,index与ALL区别为index类型只遍历索引树
range:索引范围扫描,对索引的扫描开始于某一点,返回匹配值域的行。显而易见的索引范围扫描是带有between或者where子句里带有<, >查询。当mysql使用索引去查找一系列值时,例如IN()和OR列表,也会显示range(范围扫描),当然性能上面是有差异的。
ref:使用非唯一索引扫描或者唯一索引的前缀扫描,返回匹配某个单独值的记录行
eq_ref:类似ref,区别就在使用的索引是唯一索引,对于每个索引键值,表中只有一条记录匹配,简单来说,就是多表连接中使用primary key或者 unique key作为关联条件。

您可能感兴趣的与本文相关的镜像

Langchain-Chatchat

Langchain-Chatchat

AI应用
Langchain

Langchain-Chatchat 是一个基于 ChatGLM 等大语言模型和 Langchain 应用框架实现的开源项目,旨在构建一个可以离线部署的本地知识库问答系统。它通过检索增强生成 (RAG) 的方法,让用户能够以自然语言与本地文件、数据库或搜索引擎进行交互,并支持多种大模型和向量数据库的集成,以及提供 WebUI 和 API 服务

### 添索引时避免的最佳实践 在 MySQL 中执行 `ADD INDEX` 操作通常会触发元数据定(metadata lock),这可能导致长时间的阻塞,尤其是在高并发环境中。然而,通过合理配置和优化操作方式,可以减少甚至完全避免这种的影响。 #### 使用在线 DDL 功能 自 MySQL 5.6 起引入了 Online DDL 支持,允许某些类型的 schema 修改在不中断正常查询的情况下完成。对于添索引的操作,可以通过指定合适的算法来实现无或低的效果: - **ALGORITHM=INPLACE**: 这种方法不会复制整个的数据,而是直接修改现有的结构[^3]。 - **LOCK=NONE**: 明确声明在执行期间不需要任何写入,从而允许读取和更新操作继续进行[^4]。 具体命令如下所示: ```sql ALTER TABLE your_table ADD INDEX idx_name(column_list), ALGORITHM=INPLACE, LOCK=NONE; ``` 需要注意的是,并非所有的存储引擎都支持这些选项;MyISAM 不支持真正的在线更改,而 InnoDB 则提供了较好的兼容性[^1]。 #### 配置延迟键写入参数 如果正在使用的确实是 MyISAM ,则应特别注意外部定机制以及 `delay_key_write` 的设置情况。当启用此功能时,在多进程环境下可能会引发索引损坏的风险,因此建议关闭该特性后再尝试增索引[^1]。 另外,考虑到性能因素,有时可能需要权衡是否真的有必要立即应用新的索引定义——特别是在非常繁忙的时间段内。一种替代方案是创建副本并迁移数据过去之后再做调整。 #### 分批处理大数据集上的变更请求 针对超大规模数据库实例而言,即使启用了 ONLINE 方式也可能因为日志文件增长过快等原因造成实际耗时较长的现象发生。此时可考虑采用分步策略逐步构建辅助列及其关联关系直至最终形成目标索引为止[^2]。 以下是基于 Python 实现的一个简单脚本片段用于演示如何拆解大型事务成多个小型子任务序列以便更好地控制进度条目数目的例子: ```python import mysql.connector def batch_add_index(db_config, table_name, chunk_size): conn = mysql.connector.connect(**db_config) cursor = conn.cursor() try: total_rows = get_total_row_count(cursor, table_name) for offset in range(0, total_rows, chunk_size): sql = f""" INSERT INTO temp_{table_name} SELECT * FROM {table_name} LIMIT %s OFFSET %s; """ cursor.execute(sql, (chunk_size, offset)) # Add index after each small insert operation. create_index_sql = f"CREATE INDEX IF NOT EXISTS my_idx ON temp_{table_name}(some_column);" cursor.execute(create_index_sql) merge_tables(cursor, table_name) # Merge back once all chunks processed. finally: cursor.close() conn.close() # Helper functions omitted here... ``` 以上代码仅为示意用途,请根据实际情况调整逻辑细节以满足特定需求。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值