事务报错没有显示回滚导致DDL阻塞引发的问题

在业务开发过程中,显示的开启事务并且在事务处理过程中对不同的情况进行显示的COMMIT或ROLLBACK,这是一个完整数据库事务处理的闭环过程。

在这里插入图片描述

这种在应用开发逻辑层面去handle的事务执行的结果,既确保了事务操作的数据完整性,又遵循了业务处理逻辑。所以显示的提交或回滚事务也是开发规范中的要求,但是也有一些存量的业务系统或开发人员并不能严格按照这一规范执行,进而在实际生产过程中引发故障。这里介绍一个因为开启事务后未显示的回滚导致DDL阻塞进而引发的问题。

应用系统使用的是MySQL生态的数据库,业务使用的是分区表,业务在处理时候因为当日的分区没有创建导致插入报错,应用逻辑上每日又有对表新增分区的操作,结果是事务没有显示回滚导致新增表分区的DDL阻塞,进而又引发后续的问题。

1、MySQL数据库故障模拟
1.1 创建分区表并插入数据

登录mysql数据库并创建分区表

CREATE TABLE tt1 (  
    id int NOT NULL, 
    sdate date NOT NULL,  
    c1 varchar(4) NOT NULL,  
    PRIMARY KEY (id, sdate)  
)  
PARTITION BY RANGE columns(sdate) (  
    PARTITION p20240524 VALUES LESS THAN ('2024-05-25'),  
    PARTITION p20240525 VALUES LESS THAN ('2024-05-26')
);
1.2 显示的开启事务并插入数据
mysql> begin;
mysql> select * from tango.tt1;
+----+------------+-----+
| id | sdate      | c1  |
+----+------------+-----+
|  1 | 2024-05-25 | aaa |
+----+------------+-----+
1 row in set (0.00 sec)

insert into tt1 values(1,'2024-05-25','aaa');
mysql> insert into tt1 values(3,'2024-05-27','ccc');
ERROR 1526 (HY000): Table has no partition for value from column_list

数据库执行报错提示插入的记录分区不存在。

1.3 查看数据库表中锁和事务的状态
mysql> select * from performance_schema.metadata_locks where object_name='tt1';
+-------------+---------------+-------------+-------------+-----------------------+--------------+---------------+-------------+-------------------+-----------------+----------------+
| OBJECT_TYPE | OBJECT_SCHEMA | OBJECT_NAME | COLUMN_NAME | OBJECT_INSTANCE_BEGIN | LOCK_TYPE    | LOCK_DURATION | LOCK_STATUS | SOURCE            | OWNER_THREAD_ID | OWNER_EVENT_ID |
+-------------+---------------+-------------+-------------+-----------------------+--------------+---------------+-------------+-------------------+-----------------+----------------+
| TABLE       | tango         | tt1         | NULL        |       140712994313232 | SHARED_READ  | TRANSACTION   | GRANTED     | sql_parse.cc:5768 |              85 |             24 |
| TABLE       | tango         | tt1         | NULL        |       140712994947616 | SHARED_WRITE | TRANSACTION   | GRANTED     | sql_parse.cc:5768 |              85 |             25 |
+-------------+---------------+-------------+-------------+-----------------------+--------------+---------------+-------------+-------------------+-----------------+----------------+
2 rows in set (0.00 sec)

可以看到表持有SHARED_READ和SHARED_WRITE锁,并不因为事务执行失败而释放,这也是mysql系数据库内核机制,事务报错后数据库层面并没有执行rollback操作,而是由应用自己决定是rol

<think>好的,我现在要解决用户提出的DM数据库在创建表空间时遇到的“事务未提交”报错问题。首先,我需要理解这个错误的原因。根据用户提供的引用内容,特别是引用[3]中提到,达梦数据库在创建表空间时,用户可创建的表空间ID有限,而且一旦删除表空间,ID也无法重复使用。但这里的问题是关于事务未提交导致的错误,所以可能需要考虑事务未提交对表空间操作的影响。 根据数据库的一般知识,创建表空间这样的DDL操作通常是自动提交的,也就是说执行后事务会自动提交。但如果数据库配置或某些特定情况导致事务未提交,可能会影响后续操作,比如创建表空间需要等待之前的事务完成。或者是用户可能在手动事务中执行了创建表空间但没有提交,导致后续操作被阻塞。 查看用户提供的引用[5],其中提到表空间损坏时可能需要删除并重新创建,但需要先删除相关对象。这可能和事务未提交有关吗?比如,如果之前有未提交的事务涉及该表空间,可能会导致锁的问题,从而无法创建新的表空间。 另外,引用[4]提到sp_who2可以查看会话和阻塞情况,这可能帮助识别是否有未提交的事务阻塞了表空间创建。因此,用户可能需要检查当前的活动会话,查看是否有挂起的事务。 解决方案可能包括以下几个步骤: 1. 检查当前未提交的事务,使用类似sp_who2的命令,找到阻塞的会话。 2. 提交或回滚这些未提交的事务,以释放锁。 3. 如果无法手动提交,可能需要终止阻塞的会话。 4. 确保在创建表空间之前,所有相关的事务都已经完成。 此外,还需要考虑达梦数据库的具体情况,比如是否支持隐式提交,或者在创建表空间时是否需要显式提交事务。可能需要查阅达梦的官方文档,确认创建表空间是否属于自动提交的操作。如果用户的报错提示事务未提交,可能是因为在显式事务中执行了创建表空间,但未提交,导致后续操作无法进行。这时需要用户检查是否有未提交的事务,并及时提交。 总结可能的步骤:检查会话和事务状态,提交或回滚未提交的事务,确保没有阻塞锁,然后重新尝试创建表空间。如果问题依旧,可能需要进一步分析日志或联系技术支持。</think>### DM数据库创建表空间时"事务未提交"报错解决方案 #### 问题原因分析 1. **隐式事务未生效**:DM数据库默认开启自动提交(AUTOCOMMIT=1),但若手动关闭自动提交后,执行DDL语句(如表空间创建)需要显式提交[^3][^5] 2. **会话残留事务**:存在未提交的DDL/DML操作占用系统资源,导致新表空间创建被阻塞[^4] 3. **表空间元数据锁定**:系统表空间(如MAIN、ROLL等)存在未释放的锁[^5] #### 逐步解决方案 **步骤1:检查事务状态** ```sql -- 查看当前会话事务状态 SELECT * FROM V$TRANSACTION; -- 显示未提交事务 SELECT * FROM V$LOCK; -- 显示当前锁信息 ``` **步骤2:终止阻塞进程** 若发现阻塞会话(通过`SP_WHO2`或`V$SESSIONS`): ```sql SP_CLOSE_SESSION(SESS_ID); -- 终止指定会话[^4] ``` **步骤3:强制提交事务** ```sql COMMIT; -- 显式提交当前会话事务 ALTER SYSTEM COMMIT; -- 强制提交所有事务(需DBA权限) ``` **步骤4:重建表空间** ```sql -- 确保使用自动提交模式 SET AUTOCOMMIT 1; CREATE TABLESPACE TS_001 DATAFILE 'TS_001.DBF' SIZE 128; ``` #### 预防措施 1. 重要操作前执行`COMMIT`释放事务 2. 保持`AUTOCOMMIT=1`默认配置 3. 定期监控`V$TRANSACTION`视图[^4]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值