首页 > 解决方案 > 修改大型数据库的策略

问题描述

我正在为即将到来的重大变化测试不同的策略。问题是每个实验都会在 Azure 中产生一些成本。数据量很大,而且在我认识这家公司之前,由于多年的修复和交易,可能会有一些不一致的地方。

我需要更改具有数百万条记录和数十个索引的表中的列。这将有很大的停机时间。

ALTER TABLE X ALTER COLUMN A1 decimal(15, 4) --原始列是int

最初的想法之一(现在我知道这是不可能的是拥有一个辅助副本,在那里进行更改,并且当更改完成时,将主副本与辅助副本交换......零或几乎零停机时间。我指的是“实时”的冗余副本,而不仅仅是“副本”

编辑:提出新想法:

  1. 一个答案中提到的变化:创建一个表副本(不是整个数据库,只是表),应用 INSERT INTO... SELECT 并在过程结束时交换表。或者... 尽早进行交换,以最大限度地减少在添加源中的所有记录期间延迟的停机时间

我已经尝试过了,但需要 AGES 才能完成。此外,一些 null 和 FK 违规会在处理几个小时后导致进程失败。“恢复”可能是一个选项,但它会使每次执行的过程变慢。没有某种“简历”,每次失败都得从头开始重复

一个可接受的改进可能是忽略错误(当然是创建日志)并在迁移后应用修复。但是 afaik,AzureSql(也不是 SqlServer)不提供“忽略”选项

  1. 将所有索引、约束和依赖项删除到需要修改的列,修改列并再次应用所有索引、约束和依赖项。

也试过这个。一些索引需要 AGES 才能完成。但目前看来是最好的选择。在数据类型更改之前应用 ROW COMPRESSION 可能会产生变化,但我认为它不会改善实际情况:索引重新创建

  1. 使用目标数据类型创建一个新列,从源列复制数据,删除旧列并重命名新列。此策略还需要删除和重新生成索引,因此它不会提供关于#2 的大量收益(如果有的话)。

有朋友想到了一个变种,就是在线复制列拷贝所需的索引。同时,将源列上的所有更改触发到列副本。

对于任何提到的策略,可以通过增加处理能力来获得一些收益。但是,无论如何,我们考虑使用任何方法来增加功率,因此这对于所有解决方案都是常见的

标签: sql-serverazure-sql-databasedatabase-administration

解决方案


当您需要将 A LOT 的行更新为一次性事件时,使用以下迁移技术可能更有效:

  • 创建一个新的目标表
  • 使用INSERT INTO SELECT用正确/更新的值填充新表
  • 重命名 旧表和新表
  • 为新表创建索引

推荐阅读