dev3 ·
I need to add a NOT NULL column and an index to a table with 20 million rows on MySQL during business hours. php artisan migrate asks for confirmation in production. How do I do this safely?
0
DEV3 Developer Forum
Every post is reviewed first. Usually reviewed within 24 hours.
I need to add a NOT NULL column and an index to a table with 20 million rows on MySQL during business hours. php artisan migrate asks for confirmation in production. How do I do this safely?
Production migrations need planning, not just a command.
Running them
php artisan migrate --force # --force skips the prompt in production
php artisan migrate --pretend # print the SQL without running it
Take a backup first and run migrations in your deploy pipeline, before switching traffic to new code when the change is backwards compatible.
The expand and contract pattern (zero-downtime)
User::whereNull('region')->chunkById(1000, fn ($rows) => $rows->each->update(['region' => 'IN']));
Locking
ALTER TABLE operations online (ALGORITHM=INPLACE, LOCK=NONE), but adding some column types or changing a type can rebuild the table. In Laravel you can run raw statements for control: DB::statement('ALTER TABLE orders ADD INDEX idx_user (user_id), ALGORITHM=INPLACE, LOCK=NONE');.CREATE INDEX CONCURRENTLY (set public $withinTransaction = false; on the migration).Good habits
down() for reversible changes, or accept that production rollbacks are done by a new forward migration.DB::table().Schema::hasColumn guards help when a hotfix was applied by hand.