daursu / laravel-zero-downtime-migration
Laravel 和 percona 工具包的零停机迁移
Requires
- php: >=8.0
- illuminate/database: ^8.0|^9.0|^10.0|^11.0
- illuminate/support: ^8.0|^9.0|^10.0|^11.0
- symfony/console: ^5.0|^6.0|^7.0
- symfony/process: ^5.0|^6.0|^7.0
Requires (Dev)
- orchestra/testbench: 6.*|7.*|8.*|9.*
- phpunit/phpunit: ^8.4|^9.5|^10.0
- squizlabs/php_codesniffer: ^3.3
README
使用 Laravel 和 gh-ost
或 pt-online-schema-change
进行零停机迁移。
注意:仅适用于 MySQL 数据库,包括(Percona & MariaDB)。
安装
兼容 Laravel 8.0
、9.0
和 10.0
。对于旧版本支持,请使用 v1.0
。
先决条件
如果您使用 gh-ost
,请确保从他们的发布页面下载二进制文件
如果您使用 pt-online-schema-change
,请确保已安装 percona-toolkit
。
- 在 Mac 上,您可以使用 brew 安装它:
brew install percona-toolkit
。 - 在 Debian/Ubuntu 上:
apt-get install percona-toolkit
。
安装步骤
- 运行
composer require daursu/laravel-zero-downtime-migration
- (可选) 如果您不使用自动加载,请将服务提供程序添加到您的
config/app.php
文件中。
Daursu\ZeroDowntimeMigration\ServiceProvider::class,
- 更新您的
config/database.php
并添加新的连接
此包支持 pt-online-schema-change
和 gh-ost
。以下是每个包的配置
gh-ost
'connections' => [ 'zero-downtime' => [ 'driver' => 'gh-ost', // This is your master write access database connection details 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), // Additional options, depending on your setup // all options available here: https://github.com/github/gh-ost/blob/master/doc/cheatsheet.md 'params' => [ '--max-load=Threads_running=25', '--critical-load=Threads_running=1000', '--chunk-size=1000', '--throttle-control-replicas=myreplica.1.com,myreplica.2.com', '--max-lag-millis=1500', '--verbose', '--switch-to-rbr', '--exact-rowcount', '--concurrent-rowcount', '--default-retries=120', ], ], ],
pt-online-schema-change
'connections' => [ 'zero-downtime' => [ 'driver' => 'pt-online-schema-change', // This is your master write access database connection details 'host' => env('DB_HOST', '127.0.0.1'), 'port' => env('DB_PORT', '3306'), 'database' => env('DB_DATABASE', 'forge'), 'username' => env('DB_USERNAME', 'forge'), 'password' => env('DB_PASSWORD', ''), // Additional options, depending on your setup // all options available here: https://www.percona.com/doc/percona-toolkit/LATEST/pt-online-schema-change.html 'params' => [ '--nocheck-replication-filters', '--nocheck-unique-key-change', '--recursion-method=none', '--chunk-size=2000', ], ], ],
用法
当编写新迁移时,请使用辅助门面 ZeroDowntimeSchema
而不是 Laravel 的 Schema
,您的所有命令将通过 gh-ost
或 pt-online-schema-change
执行。
<?php use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; use Daursu\ZeroDowntimeMigration\ZeroDowntimeSchema; class AddPhoneNumberToUsersTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { ZeroDowntimeSchema::table('users', function (Blueprint $table) { $table->string('phone_number')->nullable(); }); } /** * Reverse the migrations. * * @return void */ public function down() { ZeroDowntimeSchema::table('users', function (Blueprint $table) { $table->dropColumn('phone-number'); }); } }
运行 php artisan:migrate
配置
所有配置都在 config/database.php
中完成,在连接本身上进行。您可以向下传递自定义标志到原始的 pt-online-schema-change
命令。只需在 params
数组中添加您想要的参数即可,如下所示
'params' => [ '--nocheck-replication-filters', '--nocheck-unique-key-change', '--recursion-method=none', '--chunk-size=2000', ]
您可以在这里找到所有可能的选项:https://www.percona.com/doc/percona-toolkit/LATEST/pt-online-schema-change.html
测试
ZeroDowntimeSchema
门面允许您在测试期间禁用运行 pt-online-schema-change
。为此,在您的基测试用例 TestCase.php
中的 setUp 方法中添加以下内容
public function setUp() { // ... existing code ZeroDowntimeSchema::disable(); }
这将禁用 pt-online-schema-change
,并且使用辅助门面运行的迁移将通过默认的 Laravel 迁移器执行。
自定义连接名称
默认情况下,ZeroDowntimeSchema
辅助使用的连接名称设置为 zero-downtime
,但是您可以在 config/database.php
中将其重写。
为此,在您的 AppServiceProvider.php
中 boot()
方法下添加以下内容
public function boot() { // ... existing code ZeroDowntimeSchema::$connection = 'your-custom-name'; }
复制
如果您的数据库在一个带有复制的集群中运行,那么您需要配置 pt-online-schema-changes
如何找到您的副本从服务器。以下是一个示例设置,但请根据您的需求进行自定义
'params' => [ '--nocheck-replication-filters', '--nocheck-unique-key-change', '--recursion-method=dsn=D=database_name,t=dsns', '--chunk-size=2000', ]
- 将
database_name
替换为您的数据库名称。 - 创建一个名为
dsns
的新表
CREATE TABLE `dsns` ( `id` int(11) NOT NULL AUTO_INCREMENT, `parent_id` int(11) DEFAULT NULL, `dsn` varchar(255) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB;
- 为每个副本添加一行,例如
INSERT INTO `dsns` (`id`, `parent_id`, `dsn`) VALUES (1, NULL, 'h=my-replica-1.example.org,P=3306');
升级到 v1
v1 引入了一个破坏性变更,需要修改 database.php
中的配置。传递给 pt-online-schema-change
或 gh-ost
的附加参数数组已从 options
更名为 params
。此更改是必要的,因为名称 options
与 Laravel 的数据库配置冲突,该配置会自动传递给 PDO。
// Before 'options' => [ '--nocheck-replication-filters', '--nocheck-unique-key-change', '--recursion-method=none', '--chunk-size=2000', ] // After 'params' => [ '--nocheck-replication-filters', '--nocheck-unique-key-change', '--recursion-method=none', '--chunk-size=2000', ]
注意事项
- 这仅适用于 MySQL、Percona 和 MariaDB
- 在需要更改表时使用此工具,而不是在创建或删除表时。