我有点惊讶地发现,DDL语句(alter table,create index等)隐含在MySQL提交当前事务。来自 MS SQL Server,在本地事务(然后回滚)中进行数据库更改的能力是我工作流程的重要组成部分。对于持续集成,如果迁移因任何原因而中断,则使用回滚,这样至少我们不会让数据库处于半迁移状态。
人们在使用 MySQL 进行迁移和持续集成时如何解决这两个问题?
RDBMS 系统是否针对COMMIT操作进行了优化?ROLLBACK操作慢/快多少?为什么?
今天我发现存储我的数据库的硬盘已满。这种情况以前发生过,通常原因很明显。通常有一个错误的查询,这会导致对 tempdb 的大量溢出,它会一直增长到磁盘已满。这次发生的事情不太明显,因为 tempdb 不是驱动器满的原因,而是数据库本身。
事实:
我找到了可能的原因;有一个查询选择了太多的行(错误连接会导致选择 110 亿行,而预计会有几十万行)。这是一个SELECT INTO查询,这让我怀疑是否可能发生以下情况:
但是,在这种情况下,我不希望 由 创建的表SELECT INTO仍然存在,它应该被回滚删除。我测试了这个:
BEGIN TRANSACTION
SELECT T.x
INTO TMP.test
FROM (VALUES(1))T(x)
ROLLBACK
SELECT *
FROM TMP.test
Run Code Online (Sandbox Code Playgroud)
这导致:
(1 row affected)
Msg 208, Level 16, State 1, Line 8
Invalid object name 'TMP.test'.
Run Code Online (Sandbox Code Playgroud)
然而目标表确实存在。不过,实际查询并未在显式事务中执行,这能解释目标表的存在吗?
我在这里勾画的假设是否正确?这是可能发生的情况吗?
我有一些ALTER TABLE我正在运行的声明。并非所有这些都有效(它们是运行 SQL 数据比较的结果),我想将它们分组到一些事务中,并在出现问题时回滚语句。
这可能吗,还是只能回滚数据?
在 SQL Server 2008 R2 中,这两种回滚有何不同:
运行一条ALTER语句几分钟,然后点击“取消执行”。完全回滚需要几分钟时间。
运行相同的ALTER语句,但这要确保LDF文件不够大,无法成功完成。一旦达到LDF限制并且不允许“自动增长”,查询执行将立即停止(或发生回滚)并显示以下错误消息:
The statement has been terminated.
Msg 9002, Level 17, State 4, Line 1
The transaction log for database 'SampleDB' is full.
To find out why space in the log cannot be reused, see the
log_reuse_wait_desc column in sys.databases
Run Code Online (Sandbox Code Playgroud)
这两者在以下几点上有何不同?
为什么第二次“回滚”是瞬时的?我不完全确定它是否可以称为回滚。我的猜测是,事务日志是随着执行的进行而写入的,一旦它意识到没有足够的空间来完全完成任务,它就会停止并显示一些“结束”消息,而不提交。
当第一次回滚花费这么多时间(回滚单线程)时会发生什么?
2.1. SQL Server 会返回并撤消LDF文件中的条目吗?
2.2. 该LDF文件大小在回滚结束变得更小(从DBCC SQLPERF(LOGSPACE))
另一个问题:在第二种情况下,SQL Server 开始使用LDF文件的速度非常快。就我而言,它在前几分钟(< 4 分钟)内从 18% 的使用率增加到 90% …
sql-server sql-server-2008-r2 database-internals rollback transaction-log
这是SQL Server 的文档中讲的ROLLBACK语句。在该页面上,它声明其语法如下:
ROLLBACK { TRAN | TRANSACTION }
[ transaction_name | @tran_name_variable
| savepoint_name | @savepoint_variable ]
[ ; ]
Run Code Online (Sandbox Code Playgroud)
显然方括号内的内容是可选的,似乎您应该从TRAN或 中选择一个TRASACTION。但实际上,您可以完全省略两者,并且ROLLBACK是一个完全有效的语句。这是错误还是故意的?
我正在研究将 CSV 文件 ( customers.csv) 导入 MySQL 表 ( customers) 的PHP 脚本。
在将 CSV 文件的内容插入 mysql 表之前,我首先备份原始customers表。
我将整个导入过程(包括备份)包装在一个 mysql 事务中(以解决 CSV 在中间某处损坏的情况,并确保导入是原子的)。
问题是当我在INSERT INTO语句之后立即调用它时 ROLLBACK 似乎不起作用:通过 phpMyAdmin 检查数据库时,我可以看到新创建的表和 ROWS INSIDE IT 在 rollback 后仍然存在。
以下是操作日志:
[2015-01-19 14:08:11] DEBUG: "START TRANSACTION" [] []
[2015-01-19 14:08:11] DEBUG: SHOW TABLES LIKE :table_name; [] []
[2015-01-19 14:08:28] DEBUG: CREATE TABLE `customers__20150119_14_08_20` LIKE `customers` [] []
[2015-01-19 14:08:37] DEBUG: INSERT INTO `customers__20150119_14_08_20` SELECT * FROM `customers` [] …Run Code Online (Sandbox Code Playgroud) 在我们 mongodb 的最近自动更新期间PRIMARY,当它PRIMARY下台时,它永久进入了一种ROLLBACK状态。
ROLLBACK状态几小时后,mongodb数据库目录下.bson的rollback目录中仍然没有回滚文件。那,还有我们日志文件中的这一行:[rsSync] replSet syncThread: 13410 replSet too much data to roll back,似乎表明该ROLLBACK过程失败。
我需要一些帮助来分析到底出了什么问题。
rollback目录中没有出现任何内容?ROLLBACK?ROLLBACK状态”问题有没有通用的解决方案?我们最终不得不对整个数据库进行冲洗并从主数据库重新同步。相关的日志行是:
# Primary coming back after restart...
Tue May 15 19:01:01 [initandlisten] MongoDB starting : pid=3684 port=27017 dbpath=/var/lib/mongodb 64-bit host=magnesium
Tue May 15 19:01:01 [initandlisten] db version v2.0.5, pdfile version 4.5
# ... init stuff
Tue …Run Code Online (Sandbox Code Playgroud) 有没有办法在 MySQL 中删除具有待处理事务的 InnoDB 表或数据库(最好在文件系统级别)?
发生了什么:
我使用 MySQL 5.5.28 并运行LOAD DATA INFILE…将一个巨大的数据集(300M 行)导入到 InnoDB 表中。我以前没用过set autocommit = 0;。不幸的是,mysqld在导入过程中被停止了。
当我重新启动时mysql,它会尝试使用如下消息回滚填充系统日志的事务:
mysqld_safe[4433]:121212 16:58:52 InnoDB:等待 1 个活动事务完成
问题是回滚现在运行了超过 25 小时,在此期间 mysqld不接受任何套接字连接。
我不能只是删除/var/lib/mysql/*并从头开始,因为这台机器上还有一些其他 InnoDB 数据库/表。但是,有问题的表是单独数据库中的唯一表。删除整个表或整个数据库不是问题,因为我可以在之后重新导入所有数据。
rollback ×10
transaction ×6
sql-server ×4
mysql ×3
ddl ×2
innodb ×2
insert ×1
mongodb ×1
performance ×1
rdbms ×1
select-into ×1
t-sql ×1