mysql update commit吗_MySQL需要commit么

本文详细介绍了MySQL中不同存储引擎对事务的支持情况,特别是InnoDB引擎如何通过自动提交、显式提交和隐式提交来管理数据变更。

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

mysql在进行如插入(insert)操作的时候需不需要commit,这得看你的存储引擎,如果是不支持事务的引擎,如myisam,则是否commit都没有效的。

推荐课程:MySQL教程。

如果是支持事务的引擎,如innodb,则得知道你事物支持是否自动提交事务(即commit)

看自己的数据库是否是自动commit,可以使用mysql> show variables like '%autocommit%';来进行查看,如果是OFF即不自动commit,需要手动commit操作(命令行可以直接“commit;“命令),否则是自动commit。

5cd00265bccd4766.jpg

提交数据有三种类型:显式提交、隐式提交及自动提交。

下面分 别说明这三种类型。

显式提交

用 COMMIT 命令直接完成的提交为显式提交。

隐式提交

用 SQL 命令间接完成的提交为隐式提交。这些命令是:

ALTER , AUDIT , COMMENT , CONNECT , CREATE , DISCONNECT , DROP , EXIT , GRANT , NOAUDIT , QUIT, REVOKE , RENAME 。

自动提交

若把 AUTOCOMMIT 设置为 ON ,则在插入、修改、删除语句执行后,

系统将自动进行提交,这就是自动提交。其格式为: SQL>SET AUTOCOMMIT ON ;

COMMIT / ROLLBACK这两个命令用的时候要小心。 COMMIT / ROLLBACK 都是用在执行 DML语句(INSERT / DELETE / UPDATE / SELECT )之后的。DML 语句,执行完之后,处理的数据,都会放在回滚段中(除了 SELECT 语句),等待用户进行提交(COMMIT)或者回滚 (ROLLBACK),当用户执行 COMMIT / ROLLBACK后,放在回滚段中的数据就会被删除。(SELECT 语句执行后,数据都存在共享池。提供给其他人查询相同的数据时,直接在共享池中提取,不用再去数据库中提取,提高了数据查询的速度。)

所有的 DML 语句都是要显式提交的,也就是说要在执行完DML语句之后,执行 COMMIT 。而其他的诸如 DDL 语句的,都是隐式提交的。也就是说,在运行那些非 DML 语句后,数据库已经进行了隐式提交,例如 CREATE TABLE,在运行脚本后,表已经建好了,并不在需要你再进行显式提交。

<think>我们正在讨论MySQL中行更新操作的核心机制,特别是`upd_graph`(更新图)在InnoDB存储引擎中的角色。根据引用[2]和[3],InnoDB的行更新涉及多个关键组件:undolog、redo log、数据页修改以及二级索引更新。`upd_graph`是InnoDB内部用于管理行更新过程中索引修改的数据结构。###核心概念:`upd_graph`(更新图) 在InnoDB中,`upd_node_t`结构体(定义于`storage/innobase/include/row0upd.h`)用于管理行更新操作。其中`upd_graph`字段(实际为`upd_node->index`和`upd_node->update`的组合)负责: 1. **定位待更新行**:通过聚集索引(主键)定位数据页中的记录2. **构建更新向量**:`upd_node->update`存储更新前后的列值(引用[3])3.**二级索引更新决策**:根据更新向量判断哪些二级索引需要更新(引用[3]中的`UPD_NODE_NO_ORD_CHANGE`标志) ###行更新流程源码解析结合引用[2]的Update操作源码流程:```mermaidgraphTDA[开始更新] -->B[生成undolog]B--> C[更新聚集索引记录]C -->D{检查二级索引影响}D --需要修改--> E[更新二级索引]D --无需修改 -->F[跳过二级索引更新]E -->G[生成redo log]F -->GG--> H[事务提交]``` ####关键步骤详解1. **生成undolog**(`trx_undo_report_row_operation`):-在修改数据前记录旧值,用于回滚和MVCC-存储于回滚段(rollback segment)中2. **更新聚集索引记录**(`row_upd_clust_step`):-在缓冲池(buffer pool)中修改数据页-设置`DB_TRX_ID`和`DB_ROLL_PTR`字段(事务ID和回滚指针) 3. **二级索引更新决策**(`row_upd_sec_index_step`):-检查更新向量(`upd_node->update`):-若更新的列**不涉及**任何二级索引,设置`UPD_NODE_NO_ORD_CHANGE`标志(引用[3])-否则标记需要更新二级索引- **优化点**:避免不必要的二级索引更新可提升性能4. **生成redo log**(`mlog_write_ulint`等):-记录物理修改到重做日志缓冲区-通过`log_sys->mutex`保护并发写入###性能优化策略1. **减少二级索引更新**:-设计表时,将频繁更新的列放在聚集索引中-避免在二级索引中包含易变更的列2. **控制事务大小**:-大批量更新时,分批提交事务(如每1000行提交一次)-减少长事务对undo log的占用3. **利用ChangeBuffer**:-对于非唯一二级索引,延迟写入更新(仅当页被读取时合并) ###示例:更新操作的影响分析假设表结构:```sqlCREATETABLE user(id INTPRIMARY KEY,--聚集索引name VARCHAR(50),--无索引emailVARCHAR(50)UNIQUE,--唯一二级索引ageINT--二级索引(非唯一)); ```执行不同更新语句时: -**场景1**:更新`name`(无二级索引包含此列)```sqlUPDATEuser SETname ='new' WHEREid =1;```触发`UPD_NODE_NO_ORD_CHANGE`,**无需更新二级索引**- **场景2**:更新`email````sqlUPDATEuser SETemail ='new@mail.com'WHERE id=1;```需更新唯一二级索引,可能触发唯一性检查###监控工具通过PerformanceSchema观察更新操作: ```sql--查看索引更新统计SELECT* FROMperformance_schema.table_io_waits_summary_by_index_usage; ```---§§相关问题§§1.InnoDB中如何实现二级索引的延迟更新? 2.如何通过EXPLAIN分析UPDATE语句的执行计划?3.MySQL的ChangeBuffer机制如何提升写性能?</think>### MySQL行更新操作解析:`upd_graph`机制详解 在InnoDB存储引擎中,行更新操作的核心逻辑通过`upd_node_t`结构体(包含更新图逻辑)实现。以下是基于源码级别的完整流程解析: --- #### 一、更新操作核心流程 ```mermaid graph TD A[开始更新] --> B[生成undo log] B --> C[更新聚集索引记录] C --> D{检查二级索引影响} D -- 需要修改 --> E[更新二级索引] D -- 无需修改 --> F[跳过二级索引更新] E --> G[生成redo log] F --> G G --> H[事务提交] ``` --- #### 二、关键机制解析 1. **`upd_node_t`结构体作用** 管理更新过程中的所有状态,包含: - 待更新的行记录(`row`) - 更新向量(`update`,存储新旧值) - 索引更新标记(`index`,决定哪些索引需要更新) 2. **二级索引更新决策(核心优化点)** 通过`UPD_NODE_NO_ORD_CHANGE`标志判断是否需要更新二级索引[^3]: ```c // 伪代码逻辑(storage/innobase/row/row0upd.cc) if (更新列不涉及任何二级索引字段) { node->state = UPD_NODE_NO_ORD_CHANGE; // 跳过二级索引更新 } else { 构建二级索引更新图(upd_graph); } ``` **优化意义**:避免不必要的索引更新,提升性能。 3. **数据格式转换** 更新时会自动将MySQL格式数据转换为InnoDB行格式: ```c row_mysql_store_col_in_innobase_format(...); // 格式转换函数[^3] ``` 4. **日志生成顺序** 严格遵循WAL(Write-Ahead Logging)原则: 1. 先写undo log(用于回滚和MVCC) 2. 修改内存数据页 3. 写redo log(保证持久性)[^2] --- #### 三、性能优化策略 1. **减少二级索引更新** - 避免更新频繁变更的列上建立二级索引 - 使用覆盖索引减少回表操作 2. **利用Change Buffer** 对非唯一二级索引的更新,可通过Change Buffer延迟写入: ```sql SHOW ENGINE INNODB STATUS; -- 观察INSERT BUFFER AND ADAPTIVE HASH INDEX段 ``` 3. **事务拆分** 大批量更新时拆分事务,避免长事务导致的undo log膨胀: ```sql SET autocommit=0; UPDATE ... LIMIT 1000; COMMIT; UPDATE ... LIMIT 1000; COMMIT; -- 分批提交 ``` --- #### 四、监控与诊断 1. **查看更新影响** ```sql SELECT rows_affected FROM information_schema.innodb_metrics WHERE name = 'trx_rw_commits'; ``` 2. **检测索引更新跳过** 在慢查询日志中观察: ```log # Updated_rows: 100 Skipped_secondary_indexes: 1 ``` 3. **InnoDB状态分析** ```sql SHOW ENGINE INNODB STATUS\G -- 关注 TRANSACTION 和 UNDO LOG 段 ``` --- #### 五、设计建议 1. **表结构设计** - 将频繁更新的列放在聚集索引中 - 静态数据使用二级索引 2. **更新模式优化** ```sql -- 低效方式(逐行更新) UPDATE table SET col = col + 1 WHERE id BETWEEN 1 AND 1000; -- 高效方式(批量更新) UPDATE table SET col = col + 1 WHERE id BETWEEN 1 AND 1000; ``` > **关键结论**:MySQL通过`upd_graph`机制智能跳过不必要的二级索引更新,这是InnoDB在高并发写入场景仍能保持性能的关键设计[^1][^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值