【问题标题】:How to alter a large Azure table without timeout如何在不超时的情况下更改大型 Azure 表
【发布时间】:2014-02-06 20:40:50
【问题描述】:

我正在尝试更改大型 Azure 表(20 Gb,500M+ 记录)中的字段定义

nvarchar(max)nvarchar(16) 使用

ALTER TABLE [dbo].[MyTable] ALTER COLUMN [MyField] [nvarchar](16)

但是我找不到在不超时的情况下执行此命令的方法。从 Visual Studio 和 SQL Server Management Studio 我得到一个

消息 10054,级别 20,状态 0,行 0 从服务器接收结果时发生传输级错误。 (提供者:TCP 提供者,错误:0 - 强制现有连接 被远程主机关闭。)

大约 30 分钟后。几分钟后,当我从 Azure 管理门户运行命令时,我得到:

消息 -2,级别 11,状态 0,行 0 超时已过。在操作完成之前超时时间已过或服务器没有响应。

如何在 SQL Azure 上执行如此长时间运行的查询?

【问题讨论】:

    标签: azure azure-sql-database


    【解决方案1】:

    为您的 alter 语句尝试 v12 "WITH (ONLINE = ON)" 选项。有关示例,请参见此处:

    http://sqlperformance.com/2015/02/sql-performance/more-online-operations

    【讨论】:

      【解决方案2】:

      你应该试试

      ALTER TABLE [dbo].[MyTable] ALTER COLUMN [MyField] nvarchar NULL

      注意 NULL 参数...

      【讨论】:

      • 如果您需要添加 NOT NULL 默认值.. 只需在 ALTER TABLE [dbo].[MyTable] ALTER COLUMN [MyField] [nvarchar](16) DEFAULT( '') 非空
      • 我不希望该字段允许为 NULL。 ALTER TABLE [dbo].[MyTable] ALTER COLUMN [MyField] [nvarchar](16) DEFAULT('') NOT NULL 给出语法错误。默认值应指定为约束。
      【解决方案3】:

      在 SQL Azure 中不只是更改大表上的列

      改为执行以下操作:

      1. 使用所需架构创建一个新表。
      2. 将数据从原表小批量复制到新表中,不会超时。
      3. 删除原始表格。
      4. 将新表重命名为原始表。

      【讨论】:

      • 在线情况如何?桌面上可以没有任何停机时间吗?说5分钟?还是 1 分钟?还有什么是表的性质。只有插入?更新删除等?
      • @Rene 忘记加你了,请看上面的评论,有办法以增量加载的方式完成我的解决方案,以最大限度地减少离线时间,但这取决于表的使用方式。
      • 主要是插入和读取。每分钟大约有 1000 个事务,表大约 100 Gb。我想知道是否有方法可以做到这一点,但问题是从一月份开始的,我们已经通过解决方法解决了最初的问题。
      • @Rene 据我所知,没有简单的方法可以做到这一点。如果您的表允许您可以逐步执行上述解决方案,然后最后创建一个带有 TABLOCKX,HOLDLOCK 的事务,该事务重命名表并移动剩余的新插入的行。但它需要没有执行更新或者你有一个rowversion/timestamp。该表只会在很短的时间内被 X 锁定,因为它会复制最后一批中最后剩余的行。
      • 您可以在新表上使用插入/更新/删除触发器,直到切换到新表,同时您可以多次扫描旧表(假设您有一个键列)
      【解决方案4】:

      实际上有一个选项 - 将您的数据库扩展到更高的性能层,完成繁重的工作,然后将其缩减。

      我有 S2 数据库,尝试更改大量表,30 分钟后超时。所以我把它放大到 P2,改变在 6 分钟内完成。缩减 - 您需要支付 1 小时的 P2 费用,目前为 1 欧元。就个人而言,我会随时给 1 欧元以避免脏东西,例如创建新表、移动数据以在实时系统上保持一致性、重命名表等......

      【讨论】:

        【解决方案5】:

        通常您会在 V11 中看到这一点,升级到 V12 应该不会出现会话限制问题。另一个想法是添加一个空列/默认值并增量填充该值并在需要时翻转位,直到那时您的应用程序应该忽略该列。

        【讨论】:

          【解决方案6】:

          能否不添加一个允许为空的新列,将旧列数据复制到其中,将可空性更改为不允许为空,删除原始列,然后将新列重命名为旧列?

          复制到新列可能需要一些时间,但它不应该使表脱机,我认为删除或重命名列不会花费太多时间。像这样的:

          ALTER TABLE dbo.Table_1 ADD col2 nvarchar(15) NULL

          更新 dbo.Table_1 SET col2 = col1
          ALTER TABLE dbo.Table_1 ALTER COLUMN col2 NVARCHAR(15) NOT NULL
          ALTER TABLE dbo.Table_1 DROP COLUMN col1
          EXEC sp_rename 'dbo.Table_1.col2', 'col1', 'COLUMN'

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-08-01
            • 2018-07-24
            • 1970-01-01
            • 1970-01-01
            • 2023-03-17
            • 2015-09-26
            • 1970-01-01
            • 2017-03-20
            相关资源
            最近更新 更多