2

我有一个包含大约 150 万条记录的 SQL Server 2008 表,我想添加另一个字段并编辑另一个。当我保存更改时,它会出错:

'Member' table
- Unable to modify table.  
The transaction log for database 'storeboard' is full. To find out why space in the log cannot be reused, see the log_reuse_wait_desc column in sys.databases

即使我清空事务日志,它仍然会出现同样的错误。我怎样才能避免这个问题并对我的表进行必要的更改?

4

3 回答 3

1

试试这个:

USE master ;
ALTER DATABASE YourDBName SET RECOVERY SIMPLE ;
于 2012-12-18T17:40:41.157 回答
1

就像“Nikita”建议的那样,您可以将恢复模式更改为简单,这样就不会在事务日志中跟踪更改......但是,如果这是一个生产数据库,您可能正在播放日志传送,或者???,这需要使用事务日志将更改复制到另一台服务器...如果是这种情况,那么您需要了解导致事务日志填满的原因,以及如何在不禁用事务日志的情况下进行补救.

听起来您正在使用 SSMS 进行更改,而更改的性质要求 SSMS:

  1. 从更改的表中删除所有外键、索引等
  2. 将表中的所有数据复制到#temp 表中
  3. 使用建议的更改创建一个新表
  4. 将#temp表中的所有数据复制到新创建的表中
  5. 丢弃旧表
  6. 将新表重命名为旧表的名称
  7. 重新创建所有索引、外键等。

SSMS 脚本插入BEGIN TRANSACTIONCOMMIT TRANSACTION贯穿整个脚本,因此如果出现故障,希望您的表和数据不会被破坏。但是由于它还GO在整个脚本中插入,因此错误可能导致问题,特别是因为它所做的最后一件事是删除原始表,然后将新创建的表重命名为原始表名。

听起来事务日志在脚本完成运行之前已填满。如果您无法将生产数据库更改为简单的恢复模式(例如,因为它会中断日志传送等),那么您需要以一种不会填满事务日志的方式运行脚本。

我建议:

  1. 首先在没有 150 万行的开发/测试服务器上构建和测试脚本,以确保脚本完全按照您的意愿执行。
  2. 修改脚本并添加COMMIT关键位置,以便在脚本继续运行时可以回收事务日志中的空间。
  3. 一次将 100,000 条记录从 #temp 表复制回新创建的表,COMMIT每个块之间都有一个。
  4. 在生产环境运行之前,在开发/测试服务器上再次测试修改后的脚本。
  5. 在运行脚本之前备份您的生产数据库...
于 2012-12-18T18:05:53.230 回答
0

即使您对数据库使用简单的恢复模型,SQL Server 也会继续将所有内容写入事务日志。

假设您要添加datetime需要 8 个字节存储空间的列。假设您的表有 1.5 条 Mio 记录,SQL Server 将需要 8 * 1.5 字节(+开销)来完成事务。所有位都写入日志,没有办法阻止它们。

如果您的方案(和/或策略)不需要任何时间点恢复,那么 SIMPLE 恢复模式可能适合您。只需启用自动增长,为最大日志大小设置公平限制并切换auto-shrinktrue.

否则(即生产数据库、高度业务关键型应用程序等),您可能需要基于完整恢复模型和日志备份制定适当的维护计划。有很多关于这方面的白皮书和文章。

于 2015-06-21T13:13:30.097 回答