在即将到来的更新中,我需要将我们服务器中的多个表从 UTF-16 转换为 UTF-8。我预计这会花几个小时。
有没有一个好的方法可以关闭 INSERTS 和 UPDATES,但仍然允许数据库中的 SELECTS?
或者我是否需要在更新时阻止业务级别的更改/关闭数据库?
答案1
你可能有一个XY问题。有多种方法可以完成您尝试的操作,而无需在操作期间对正在操作的表进行更改。以下是我的做法(高层次):
- 添加具有所需定义(数据类型、排序规则等)的新列。
- 使用“插入后”触发器来确保来自应用程序的数据变异也会改变新列。
- 回填表中现有数据。
- 删除旧列,将新列重命名为旧列的名称。
答案2
如果对数据库架构、权限等没有进一步的了解,并且对应用程序的策略没有概念,那么制定规范将非常困难。至少,应用程序是否允许您在阻止表更新的情况下以只读模式进行操作?
从最基本的层面上讲,“是的”你可以这样做……
DENY INSERT, UPDATE, DELETE ON <table> TO <user>
但是无法预测你的应用程序会如何反应。根据我的经验,如果你这样做,大多数应用程序都会到处乱窜错误,甚至可能破坏数据(未经检查的错误、事务使用不当等)。我很少(可能从来没有)看到过一个应用程序在数据库访问不符合设计/预期时优雅地切换到只读模式。
所以要测试!在受控的非生产环境中测试、测试、再测试,直到您拥有支持变更的记录流程。
如果您的要求不允许长时间停机(或根本不停机),那么有更复杂的方法来处理这个问题。一个想法是添加插入后/更新后触发器,以便在您对较小批次进行维护时自动转换新字段中的新/更新记录。转换完所有数据后,将应用程序切换到新字段并删除旧字段。
答案3
除了 UTF-8 和 UTF-16 之外,我认为您问的更大问题是如何以最少的停机时间将更改部署到生产系统。我确信有几种不同的方法,但这就是我的方法。
- 创建数据库的副本。
- 在副本上运行架构更新。
- 使用 Redgate SQL Compare 等产品,或编写自己的脚本来同步数据。让它们尽可能接近
- 关闭应用程序,最终重新同步。
- 将数据库连接更改为新数据库(或重命名数据库)。
- 重新启动应用程序。
我知道这听起来过于简单而且由于各种原因可能并不可行,但值得研究。
我想这样做有几个原因。尽量减少中断和对用户的影响。安全的回滚选项。一个测试架构/数据更改影响的机会。
我知道如果有其他应用程序或与数据库的集成连接,这会变得更加复杂,但撤销失败的升级也不是一件有趣的事。