某些数据库维护任务(例如重新组织索引、移动文件、更改模式等)需要禁用任何使用该数据库的应用程序。
除了在您的网站上发布“我们将于美国东部时间午夜至凌晨 4 点暂停服务以进行服务器维护”之类的消息外,还有哪些好的策略可以解决此问题?
答案1
如果您有复制/高可用性解决方案,那么使用它来避免停机是显而易见的选择,在一台服务器正常工作时升级另一台服务器,然后切换并升级下一台服务器。
如果您没有这样的结构,您可以在同一台服务器上进行小型复制设置,其中每个数据库有两个副本,在其中一个正常运行时升级另一个,然后将旧副本同步回来。这仍然需要一些停机时间,但时间不会超过 4 小时。
避免使两个数据库保持同步的第三个选项是复制数据库,在维护一个数据库时,该副本和使用它的应用程序处于只读模式。完成后,您只需将应用程序切换到升级后的数据库并再次开始写入数据库。
当然,最后一个选项需要应用程序支持并且才有意义(有些应用程序的只读模式没有意义)。
答案2
如果您使用的是 SQL Server,那么从 SQL Server 2000 开始,您始终可以在线执行索引碎片删除。命令 DBCC INDEXDEFRAG 始终执行在线重组。我专门将其作为 DBCC DBREINDEX 的在线替代方案编写。
从 SQL Server 2005 开始,ALTER INDEX ... REORGANIZE 命令取代了 DBCC INDEXDEFRAG,并且始终处于在线状态。此外,从 2005 开始,使用企业版,您可以使用 ALTER INDEX ... REBUILD ... WITH (ONLINE=ON) 进行在线索引重建。在操作开始和结束时需要几个非常短期的表锁,因此它不像 REORGANIZE 那样在线(而且大多数情况下在线索引重建并不是一个好的营销术语 :-)。您甚至可以使用 CREATE INDEX ... WITH DROP_EXISTING 并指定 ONLINE=ON 将索引移动到新文件组。
谢谢
答案3
常规维护任务
大多数维护任务都可以完成没有如果有的话,请将网站或应用程序离线数据库复制。您将从副本集中删除一个数据库,应用所需的内容,然后将其重新连接到副本集。当它关闭时,其他数据库将保持解决方案运行。
更改数据库架构
当你需要更新你的数据库架构,你将被迫将解决方案关闭几分钟(或将其置于只读状态)如果更改会破坏旧版本。如果您的新架构只是创建表或字段,则不会影响旧版本1,因此这种架构更改可以在线完成2并使用蓝绿部署使您的应用程序实现高可用性。
如果您的新模式重命名了现有字段或将其删除,则为了实现 100% 的正常运行时间,您需要遵循以下步骤:
重命名字段
- 如果需要将 A 重命名为 B,请应用架构更改,添加新字段 B 并复制 A 内容。同时,保持 A 完好无损。
- 部署一个使用字段B的新应用程序,而不要使用字段A。
- 应用删除 A 的架构更改。
删除字段
- 不应用任何架构更改。
- 部署一个不使用将被删除的字段的新应用程序。
- 应用删除该字段的架构更改。
注 1:某些 ORM 工具(如 .NET Entity Framework)将每个架构更改与迁移 ID 关联。因此,当您部署新的架构版本时,旧应用程序将立即中断。这也是可以避免的如果你禁用此检查。
笔记2:如果您的新架构添加了唯一约束、检查或外键,那么如果您有数千行数据,则 alter table 命令可能需要相当长的时间。在 alter table 处理过程中,即使选择,表也会被锁定,这可能会导致一些查询超时,具体取决于您的数据量有多大。
答案4
可用的选项很大程度上取决于您使用的数据库引擎。您需要首先采取一切必要措施来启用数据库的在线备份,最好允许在备份过程中进行写入。这通常需要线性记录事务,这也应该使您能够通过向前滚动事务日志将数据库恢复到特定时间点。
表和索引重组可能有点棘手,但希望您的数据库引擎在重组对象时至少允许对对象进行只读访问。如果没有,您可能需要想出一种方法让您的应用程序暂时使用表的只读克隆。如果您的 DBMS 几乎不提供在线维护,您将不得不在应用程序层做出权衡,以便将其重定向到数据的部分或完整副本。
无论成本如何,数据库复制几乎总是一项难以管理的功能。更糟糕的是双向复制,理论上,即使主数据库因维护而停机,您的应用程序也可以更改辅助数据库上的数据。复制并非不可能,但确实需要大量规划和测试才能在生产中可靠地运行。