不会搞砸生产环境的数据库迁移
迁移在你的本地机器上运行得非常完美。因为看起来改动很小,你决定在周五下午 6 点进行部署。然后部署卡住了。或者更糟糕的是,一个拥有 800 万行数据的表锁定了 40 秒,导致你的网站崩溃。
迁移在生产环境中的表现与本地不同。本地数据库是空的,运行速度很快。而生产环境数据库拥有真实数据和活跃用户。
请遵循以下规则,以避免生产环境灾难。
始终编写可用的 down 方法 每个迁移都需要一个 up 和一个 down 函数。down 函数必须能够完全撤销 up 函数的操作。如果你无法编写回滚逻辑,说明你的迁移过于复杂了。在推送之前,先在本地使用 migrate 紧接着 migrate:rollback 进行测试。
永远不要修改旧的迁移文件 你可能想修改旧迁移文件中的列大小。千万不要这样做。Laravel 不会在服务器上再次运行该文件。相反,你应该创建一个新的迁移来更改结构。迁移是变更的历史记录。你应该添加新的章节,而不是重写旧的章节。
使用 nullable 或默认值 向一个已有数据的表中添加 NOT NULL 列会导致错误。数据库不知道该在旧行中填入什么内容。
请改用以下方法: • 将新列设为 nullable。 • 设置一个默认值。 • 如果该列必须是必填项,请分三步操作:先将其创建为 nullable,填入数据,然后将其更改为 NOT NULL。
数据丢失是永久性的 dropColumn 命令会永久删除数据。回滚可以重新创建列,但其中的数据已经丢失了。在删除列之前,请务必确认你的备份。更安全的方法是先在代码中停止使用该列,等待几周,然后再从数据库中将其移除。
将架构变更与数据更新分离 在迁移中运行 User::all() 可能会将数百万行数据加载到内存中,从而导致部署崩溃。如果必须在迁移期间更新数据,请使用 chunkById 分批处理记录。
在流水线中使用 --force 标志 如果 Laravel 请求确认,自动化部署流水线将会挂起。在你的部署脚本中使用此命令: php artisan migrate --force
注意表锁 在海量表上更改列或添加索引会锁定该表。这会导致停机。对于超大型表,请研究在线架构变更工具或在低流量时段进行变更。
推送前的检查清单: • down 方法是否有效? • 我在本地测试过回滚吗? • 我是在创建新的迁移,而不是修改旧的迁移吗? • 新列是 nullable 的,还是有默认值? • 在删除列之前,我是否有备份?
Source: https://dev.to/denisgusto1/migrations-que-nao-quebram-em-producao-o-guia-que-ninguem-te-deu-363o
