MySQL max_execution_time参数原理解析

本文深入解析MySQL的max_execution_time参数,用于控制SELECT语句的最长时间限制,单位为毫秒,支持session和global级别设置。文章通过示例和内部原理分析,包括计时器如何监控SQL执行并中断超时任务,以及线程_timer_notifier如何在Unix系统中实现提醒机制。

MySQL max_execution_time参数解析

一、参数解释说明

参数max_execution_time用来控制select语句的最大执行时间,单位是毫秒,可以动态修改,分为session和global两种级别,如果设置为0的话,则证明不设限制。

二、使用示例

mysql> set net_read_timeout=2;
Query OK, 0 rows affected (0.00 sec)

mysql> select count(*) from t10 a,t10 b where a.name != b.name;
ERROR 3024 (HY000): Query execution was interrupted, maximum statement execution time exceeded
mysql>
mysql>
mysql> set session max_execution_time=10000;
Query OK, 0 rows affected (0.00 sec)

mysql> select count(*) from t10 a,t10 b where a.name != b.name;
ERROR 3024 (HY000): Query execution was interrupted, maximum statement execution time exceeded
mysql>

</

<think>我们之前已经介绍过MVCC的基本概念,现在应要求更详细地介绍MySQL中的MVCC。我们将深入探讨MVCC的工作原理、数据结构、在事务隔离级别中的应用以及具体示例。同时,我们会提供一些伪代码或实际代码片段来说明其实现机制。</think>### MySQL MVCC(多版本并发控制)深度解析 MVCC(Multi-Version Concurrency Control)是MySQL InnoDB存储引擎实现高并发事务处理的核心技术,它通过创建数据的多个版本来实现**读操作不阻塞写操作,写操作不阻塞读操作**。 #### MVCC核心组件 | 组件 | 说明 | 存储位置 | |------|------|----------| | **DB_TRX_ID** | 6字节事务ID,记录最后修改该行的事务ID | 行记录隐藏列 | | **DB_ROLL_PTR** | 7字节回滚指针,指向Undo Log中的历史版本 | 行记录隐藏列 | | **DB_ROW_ID** | 6字节行ID(隐藏主键) | 行记录隐藏列 | | **Undo Log** | 存储数据的历史版本链 | 系统表空间 | | **Read View** | 事务开启时的系统快照 | 内存结构 | #### MVCC工作原理(RR隔离级别) ```mermaid graph LR A[事务启动] --> B[创建Read View] B --> C[记录活跃事务列表] C --> D[确定高低水位线] D --> E[查询数据] E --> F{检查行记录事务ID} F -->|小于低水位| G[可见] F -->|在高低水位之间| H{是否在活跃列表} H -->|是| I[不可见] H -->|否| J[可见] F -->|大于高水位| K[不可见] I & K --> L[通过回滚指针找旧版本] ``` #### MVCC可见性判断规则 1. **事务ID < Read View低水位线**:事务已提交,数据可见 2. **事务ID ≥ Read View高水位线**:事务在Read View之后启动,数据不可见 3. **低水位线 ≤ 事务ID < 高水位线**: - 事务ID在活跃事务列表中 → 不可见 - 事务ID不在活跃事务列表中 → 可见 #### MVCC实现代码解析 InnoDB通过以下数据结构实现MVCC: ```c // 行记录结构(简化) struct row_t { trx_id_t trx_id; // 最后修改的事务ID roll_ptr_t roll_ptr; // 指向undo log的回滚指针 // ... 数据列 }; // Read View结构 struct read_view_t { trx_id_t low_limit_no; // 低水位(小于此值的事务可见) trx_id_t up_limit_id; // 高水位(大于等于此值的事务不可见) ulint n_trx_ids; // 活跃事务数量 trx_id_t* trx_ids; // 活跃事务ID数组 trx_id_t creator_trx_id; // 创建该Read View的事务ID }; ``` #### MVCC在不同隔离级别的行为 | 隔离级别 | 创建Read View时机 | 是否解决幻读 | |----------|-------------------|--------------| | **读未提交** | 不使用MVCC | &times; | | **读已提交** | 每条SELECT语句创建新Read View | &times; | | **可重复读** | 第一条SELECT语句创建Read View | √ | | **串行化** | 不使用MVCC | √ | #### MVCC版本链示例 ```sql -- 初始数据 INSERT INTO account(id, balance) VALUES(1, 1000); -- trx_id=100 -- 事务A更新 UPDATE account SET balance=900 WHERE id=1; -- trx_id=200 -- 事务B更新 UPDATE account SET balance=800 WHERE id=1; -- trx_id=300 ``` 版本链结构: ``` 当前记录(trx_id=300) ↳ roll_ptr → undo log(trx_id=200) ↳ roll_ptr → undo log(trx_id=100) ``` #### MVCC清理机制 InnoDB通过Purge线程清理旧版本: ```sql -- 查看Purge配置 SHOW VARIABLES LIKE 'innodb_purge_threads'; SHOW VARIABLES LIKE 'innodb_max_purge_lag'; ``` 清理规则: 1. 删除标记删除的记录 2. 清理不再被任何Read View引用的Undo Log 3. 回收旧版本占用的空间 #### MVCC优缺点分析 **优点**: - 读操作完全无锁(快照读) - 大幅提升并发性能 - 避免不可重复读和幻读(RR级别) **缺点**: - 额外存储开销(Undo Log) - 长事务导致版本链过长 - 需要定期Purge旧版本 - 写操作仍需要加锁 #### MVCC优化实践 1. **避免长事务**: ```sql SET SESSION autocommit=1; -- 启用自动提交 SET SESSION max_execution_time=1000; -- 设置查询超时 ``` 2. **监控版本链长度**: ```sql -- 查看未清理的Undo Log SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TRX; ``` 3. **合理配置Purge线程**: ```ini # my.cnf配置 innodb_purge_threads=4 innodb_max_purge_lag=10000 ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值