sourcebroker/deployer-extended-database

Deployer任务,用于管理应用程序实例之间的数据库同步。

17.0.0 2023-04-16 16:06 UTC

README

https://poser.pugx.org/sourcebroker/deployer-extended-database/v/stable https://img.shields.io/badge/license-MIT-blue.svg?style=flat

它做了什么?

该软件包为Deployer (deployer.org)提供了额外的任务,用于在实例之间同步数据库。最有用的是以下两个任务

  1. 任务 "db:pull [source-instance]" 允许您从远程实例拉取数据库到本地实例,
  2. 任务 "db:push [target-instance]" 允许您将数据库从本地实例推送到远程实例,
  1. 任务 "db:copy [source-instance] --options=target:[target-instance]" 允许在远程实例之间复制数据库。

安装

  1. 使用composer安装包

    composer require sourcebroker/deployer-extended-database
    
  2. 将以下行放入您的deploy.php中

    require_once(__DIR__ . '/vendor/sourcebroker/deployer-loader/autoload.php');
    new \SourceBroker\DeployerLoader\Load([
        ['path' => 'vendor/sourcebroker/deployer-instance/deployer'],
        ['path' => 'vendor/sourcebroker/deployer-extended-database/deployer'],
    ]);
    
    重要提示!不要在deploy.php中放置 require('/vendor/autoload.php') 因为您可能会遇到依赖问题。请使用 require_once(__DIR__ . '/vendor/sourcebroker/deployer-loader/autoload.php'); 代替,如建议。
  1. 在项目根目录(存储deploy.php文件的位置)创建".env"文件。.env文件应从git中排除,因为您需要在此存储实例名称的信息。此外,请在此处放置您想要同步的数据库信息。您可以将数据库数据信息移动到其他文件中,但为了测试,最好将其放在.env文件中。请记住,如果根目录可以从WWW服务器级别读取,则保护.env文件免受https请求的下载。

    INSTANCE="local"
    
    DATABASE_HOST="127.0.0.1"
    DATABASE_NAME="database_name"
    DATABASE_USER="database_user"
    DATABASE_PASSWORD="password"
    

    INSTANCE必须与host()名称相对应。您需要在每个实例上放置包含正确INSTANCE名称和数据库访问数据的.env文件。

  2. 为"local"主机定义"host"并设置其"db_databases"。使用以下代码

    (new \SourceBroker\DeployerExtendedDatabase\Driver\EnvDriver())->getDatabaseConfig()
    

    这将从.env文件中读取数据库数据。

    host('local')
        ->set('deploy_path', getcwd())
        ->set('db_databases', [
            'database_default' => [
                (new \SourceBroker\DeployerExtendedDatabase\Driver\EnvDriver())->getDatabaseConfig()
            ]
        ])
    
  3. 为所有其他主机添加"db_databases"变量。例如,对于生产主机,可以是

    host('live')
        ->setHostname('my-server.example.com')
        ->setRemoteUser('deploy')
        ->set('deploy_path', '/var/www/myapplication/')
        ->set('db_databases', [
            'database_default' => [
                (new \SourceBroker\DeployerExtendedDatabase\Driver\EnvDriver())->getDatabaseConfig()
            ]
        ])
    
  4. 确保所有实例都拥有相同的/vendors文件夹中的deployer-extended-database和相同的deploy.php文件。大多数问题都是由于实例之间deploy.php文件的不同而引起的。

  5. 运行dep db:pull live以测试是否一切正常。

选项

  • db_databases 默认值: null
    要同步的数据库。您可以定义多个要同步的数据库。有关db_databases内部可用选项,请参阅db_databases。请参阅示例以更好地理解结构。
  • db_storage_path_relative 默认值: .dep/database/dumps
    相对于"deploy_path"的路径,您希望在其中存储在数据库同步命令期间产生的数据库转储。

"db_databases"的选项

"db_databases" 是一个 "数据库配置" 数组,而 "数据库配置" 是配置部分的数组。配置部分可以是数组或字符串。如果是字符串,则被视为指向文件的绝对路径,该路径应返回配置数组。每个或数组配置部分都会合并。请参考 示例 以更好地理解。

  • host 默认值: null
    数据库主机。
  • user 默认值: null
    数据库用户。
  • password 默认值: null
    数据库用户密码。
  • dbname 默认值: null
    数据库名称。
  • truncate_tables 默认值: null
    将使用任务 db:truncate 截断的表名数组。通常应是一些缓存表,在部署时会进行截断。值应放在 ^ 和 $ 之间,并作为 preg_match 处理。例如,您可以写入 "cf_.*" 以截断所有以 "cf_" 开头的表。最终 preg_match 检查为 /^cf_.*$/i
  • ignore_tables_out 默认值: null
    在任务 db:pull 从目标实例拉取数据库时将被忽略的表名数组。值应放在 ^ 和 $ 之间,并作为 preg_match 处理。例如,您可以写入 "cf_.*" 以截断所有以 "cf_" 开头的表。最终 preg_match 检查为 /^cf_.*$/i
  • post_sql_in 默认值: null
    在本地实例导入数据库后执行的 SQL。
  • post_sql_in_markers 默认值: null
    在本地实例导入数据库后执行的 SQL。与 "post_sql_in" 的区别在于您可以使用一些预定义的标记。目前只有一个标记是 {{domainsSeparatedByComma}},它包含在 ->set('public_urls', ['https://live.example.com']); 中定义的所有域名,并以逗号分隔。使用这样的标记可以在导入后更改数据库中的活动域名到其他实例,因为一些框架将域名保存在数据库中。

示例

以下示例应说明您应该如何构建您的数据库配置。

配置一个数据库,数据库数据从.env文件读取

deploy.php 文件

set('db_default', [
   'ignore_tables_out' => [
       'caching_.*'
   ]
]);

host('live')
      ->setHostname('my-server.example.com')
      ->setRemoteUser('deploy')
      ->set('deploy_path', '/var/www/myapplication')
      ->set('db_databases',
         [
           'database_foo' => [
               get('db_default'),
               (new \SourceBroker\DeployerExtendedDatabase\Driver\EnvDriver())->getDatabaseConfig()
            ],
         ]
      );

host('local')
      ->set('deploy_path', getcwd())
      ->set('db_databases',
         [
           'database_foo' => [
               get('db_default'),
               (new \SourceBroker\DeployerExtendedDatabase\Driver\EnvDriver())->getDatabaseConfig()
            ],
         ]
      );

请注意,因为所有主机的 db_* 设置都将相同,所以您可以将 'db_databases' 设置全局,并将其放在主机配置之外。请参考下面的示例,其中我们简化了配置。

deploy.php 文件

set('db_databases',
    [
        'database_foo' => [
            'ignore_tables_out' => [
               'caching_.*'
            ]
            (new \SourceBroker\DeployerExtendedDatabase\Driver\EnvDriver())->getDatabaseConfig()
         ],
    ]
);

host('live')
    ->setHostname('my-server.example.com')
    ->setRemoteUser('deploy')
    ->set('deploy_path', '/var/www/myapplication/');

host('local')
   ->set('deploy_path', getcwd());

然后 .env 文件应如下所示

INSTANCE="[instance name]"

DATABASE_HOST="127.0.0.1"
DATABASE_NAME="database_name"
DATABASE_USER="database_user"
DATABASE_PASSWORD="password"

配置两个数据库,数据库数据从.env文件读取

deploy.php 文件

set('db_databases',
    [
         'database_application1' => [
            'ignore_tables_out' => [
               'caching_.*'
            ]
         (new \SourceBroker\DeployerExtendedDatabase\Driver\EnvDriver())->getDatabaseConfig('APP1_')
      ],
         'database_application2' => [
            'ignore_tables_out' => [
               'cf_.*'
             ]
         (new \SourceBroker\DeployerExtendedDatabase\Driver\EnvDriver())->getDatabaseConfig('APP2_')
      ],
    ]
);

host('live')
    ->setHostname('my-server.example.com')
    ->setRemoteUser('deploy')
    ->set('deploy_path', '/var/www/myapplication/');

host('local')
   ->set('deploy_path', getcwd());

然后 .env 文件应如下所示

INSTANCE="[instance name]"

APP1_DATABASE_HOST="127.0.0.1"
APP1_DATABASE_NAME="database_name"
APP1_DATABASE_USER="database_user"
APP1_DATABASE_PASSWORD="password"

APP2_DATABASE_HOST="127.0.0.1"
APP2_DATABASE_NAME="database_name"
APP2_DATABASE_USER="database_user"
APP2_DATABASE_PASSWORD="password"

配置一个数据库,数据库配置从不同来源读取

在示例中,我们将使用

  1. 数组

    'ignore_tables_out' => [
                'caching_*'
             ]
    
  2. get() 返回包含数据库选项的数组,get('db_default')

  3. 直接文件包含返回包含数据库选项的数组 __DIR__ . '/.dep/database/config/additional_db_config.php'

  4. 类/方法返回包含数据库选项的数组 (new \YourVendor\YourPackage\Driver\MyDriver())->getDatabaseConfig()

  5. 闭包返回包含数据库选项的数组 function() { return (new \YourVendor\YourPackage\Driver\MyDriver())->getDatabaseConfig()}

这些数组中的每个都会合并,以构建用于数据库同步的最终配置。

deploy.php 文件

set('db_default', [
   'post_sql_in' => 'UPDATE sys_domains SET hidden=1;'
]);

set('db_databases',
    [
        'database_foo' => [
            [
                'ignore_tables_out' => [
                   'caching_.*'
                ]
            ],
            get('db_default'),
            __DIR__ . '/databases/config/additional_db_config.php',
            (new \YourVendor\YourPackage\Driver\MyDriver())->getDatabaseConfig(),
            function() {
               return (new \YourVendor\YourPackage\Driver\MyDriver())->getDatabaseConfig();
            }
         ],
    ]
);

host('live')
    ->setHostname('my-server.example.com')
    ->setRemoteUser('deploy')
    ->set('deploy_path', '/var/www/myapplication/');

host('local')
   ->set('deploy_path', getcwd());

配置一个数据库,数据库配置从"my framework"文件读取

建议您创建自己的特殊方法,该方法将返回您的框架数据库数据。在下面的示例中,它调用 \YourVendor\YourPackage\Driver\MyDriver()。这样,您就不需要在 .env 文件中重复数据库数据。在这种情况下,.env 文件应仅包含 INSTANCE。

set('db_databases',
       [
           'database_default' => [
               (new \YourVendor\YourPackage\Driver\MyDriver())->getDatabaseConfig()
           ],
       ]
   );

truncate_tables, ignore_tables_out, post_sql_in_markers的配置

真实世界示例:CMS TYPO3

set('db_default', [
    'truncate_tables' => [
        'cf_.*'
    ],
    'ignore_tables_out' => [
        'cf_.*',
        'cache_.*',
        'be_sessions',
        'fe_sessions',
        'sys_file_processedfile',
        'tx_devlog',
    ],
]);

任务

db:backup

备份数据库。在目标实例的背景中,执行两个任务 'db:export' 和 'db:compress'。结果存储在 "{{deploy_path}}/.dep/databases/dumps/"。

如果检测到发布文件夹,则将其添加到 dumpcode 名称中的信息关于发布,如下例所示: 2017-12-04_00:20:22#server=live#dbcode=database_default#dumpcode=backup_for_release_160_ec77cb6bc0e941b0ac92e2109ad7b04e#type=structure.sql.gz

示例

dep db:backup local
dep db:backup live
dep db:backup live --options=dumpcode:mycode

db:compress

在目标实例上,使用给定的dumpcode压缩存储在文件夹"{{deploy_path}}/.dep/databases/dumps/"中的转储。需要传递选项--options=dumpcode:[value]

查找配置变量'db_compress_suffix'、'db_compress_command'、'db_uncompress_command',以确定如何覆盖标准gzip压缩使用自己的方法。

示例

dep db:compress live --options=dumpcode:0772a8d396911951022db5ea385535f6

db:copy

此命令允许您在不同实例之间复制数据库。

dep db:copy [source-instance] --options=target:[target-instance]

在后台,它运行其他几个任务以完成此操作。假设我们想要从生产实例复制数据库到开发实例。您将在本地实例上运行以下命令

dep db:copy live --options=target:dev

以下是将在后台运行的任务

以下描述中
  • 源实例 = 生产
  • 目标实例 = 开发
  • 本地实例 = 本地
  1. 首先在源实例上运行dep db:export live --options=dumpcode:123456任务。导出任务的转储存储在目标实例的文件夹"{{deploy_path}}/.dep/databases/dumps/"中。
  2. 然后在本地实例上运行db:download live --options=dumpcode:123456以从生产实例的文件夹"{{deploy_path}}/.dep/databases/dumps/"下载转储文件到本地实例的文件夹"{{deploy_path}}/.dep/databases/dumps/"。
  3. 然后在本地实例上运行db:process local --options=dumpcode:123456对SQL转储文件进行一些直接操作。
  4. 然后在本地实例上运行db:upload dev --options=dumpcode:123456。此任务将具有代码:123456的转储文件发送到开发实例并存储在文件夹"{{deploy_path}}/.dep/databases/dumps/"中。
  5. 最后在目标实例上运行db:import dev --options=dumpcode:123456。此任务从开发实例的文件夹"{{deploy_path}}/.dep/databases/dumps/"读取具有代码:123456的转储并将其导入到数据库中。
  6. 最后,它使用命令db:rmdump dev --options=dumpcode:123456删除步骤5中刚刚导入的转储。

将实例复制到instance_live_name(默认为live)是特殊情况。如果您复制到最高实例,则默认情况下将两次询问您是否真的想要这样做。您可以通过将db_allow_copy_live_force设置为true来禁用询问。您还可以通过将db_allow_copy_live设置为false来禁止复制到生产实例。

db:decompress

在目标实例上解压缩存储在文件夹"{{deploy_path}}/.dep/databases/dumps/"中的给定dumpcode的转储。需要传递选项--options=dumpcode:[value]

查找配置变量'db_compress_suffix'、'db_compress_command'、'db_uncompress_command',以确定如何覆盖标准gzip压缩使用自己的方法。

示例

dep db:decompress live --options=dumpcode:0772a8d396911951022db5ea385535f6

db:download

从目标实例的文件夹"{{deploy_path}}/.dep/databases/dumps/"下载具有选定dumpcode的数据库转储并将其存储在本地实例的文件夹"{{deploy_path}}/.dep/databases/dumps/"中。需要传递选项--options=dumpcode:[value]

示例

dep db:download live --options=dumpcode:0772a8d396911951022db5ea385535f6

db:dumpclean

清理目标实例上的数据库转储存储。默认情况下,它删除所有转储,但除了最后五个,您可以设置自己的值,也可以根据实例更改这些值。

示例

set('db_dumpclean_keep', 10); // keep last 10 dumps for all instances

set('db_dumpclean_keep', [
   'live' => 10 // keep last 10 dumps for live instance dumps
   'dev' => 5   // keep last 5 dumps for dev instance dumps
   '*' => 2     // keep last 5 dumps for all other instances dumps
]);

dep db:dumpclean live

db:export

将数据库转储到本地实例上的文件夹,默认位置为"{{deploy_path}}/.dep/databases/dumps/"。转储将存储在两个单独的文件中。一个包含表结构,另一个仅包含数据。可以传递选项--options=dumpcode:[value]。如果没有提供转储代码,则将其创建并作为json结构返回。

示例

示例任务调用

dep db:export live

示例输出文件位于文件夹{{deploy_path}}/.dep/databases/dumps/

2017-02-26_14:56:08#server=live#dbcode=database_default#type=data#dumpcode=362d7ca0ff065f489c9b79d0a73720f5.sql
2017-02-26_14:56:08#server=live#dbcode=database_default#type=structure#dumpcode=362d7ca0ff065f489c9b79d0a73720f5.sql

具有自定义dumpcode=的示例任务调用

dep db:export live --options=dumpcode:mycode

示例输出文件

2017-02-26_14:56:08#server=live#dbcode=database_default#type=data#dumpcode=mycode.sql
2017-02-26_14:56:08#server=live#dbcode=database_default#type=structure#dumpcode=mycode.sql

db:import

从本地实例文件夹"{{deploy_path}}/.dep/databases/dumps/"导入数据库转储文件到本地数据库。需要传递选项--options=dumpcode:[value]

示例

dep db:import dev --options=dumpcode:0772a8d396911951022db5ea385535f66

db:process

此命令将在纯sql文件上运行一些定义的命令,因为有时在导入之前需要在sql文件上直接删除或替换一些字符串。需要传递选项--options=dumpcode:[value]

示例

dep db:process dev --options=dumpcode:0772a8d396911951022db5ea385535f66

db:pull

此命令允许您从目标实例拉取数据库到本地实例。在后台,它运行其他几个任务以完成此操作。

以下是执行"db:pull"时将执行的任务列表

  1. 首先在目标实例上运行db:export任务并获取"dumpcode",然后在后续命令中使用。
  2. 然后它在本地实例上运行 db:download(使用第一个任务中的“dumpcode”值)。
  3. 然后它在本地实例上运行 db:process(使用第一个任务中的“dumpcode”值)。
  4. 然后它在本地实例上运行 db:import(使用第一个任务中的“dumpcode”值)。

instance_live_name(默认为 live)定义的实例拉取是特殊情况。如果你拉取到最高实例,则默认情况下你将被问两次你是否真的想要这样做。你可以通过将 db_allow_pull_live_force 设置为 true 来禁用询问。你也可以通过将 db_allow_pull_live 设置为 false 来禁止拉取到生产实例。

示例

dep db:pull live

db:push

此命令允许您将本地实例的数据库推送到远程实例。在后台,它运行其他几个任务来完成此操作。

以下是执行“db:push”时将执行的任务列表

  1. 首先它在本地实例上运行 db:export 任务并获取“dumpcode”作为返回值以供后续命令使用。
  2. 然后它在本地实例上运行 db:upload(使用第一个任务中的“dumpcode”值)并将远程作为参数。
  3. 然后它在远程实例上运行 db:process(使用第一个任务中的“dumpcode”值)。
  4. 然后它在远程实例上运行 db:import(使用第一个任务中的“dumpcode”值)。

将实例定义在 instance_live_name(默认为 live)的情况是特殊的。如果你将实例推送到最高实例,则默认情况下你将被问两次你是否真的想要这样做。你可以通过将 db_allow_push_live_force 设置为 true 来禁用询问。你也可以通过将 db_allow_push_live 设置为 false 来禁止推送到生产实例。

示例

dep db:push live

db:rmdump

此命令将从给定的 dumpcode(压缩和非压缩)删除所有转储。需要传递所需选项 --options=dumpcode:[value]

示例

dep db:rmdump live --options=dumpcode:0772a8d396911951022db5ea385535f66

db:truncate

此命令允许您截断数据库配置变量 "truncate_tables" 中定义的数据库表。不需要 dumpcode,因为它直接操作数据库。

示例 截断本地实例数据库表。

dep db:truncate

截断生产实例数据库表。

dep db:truncate live

db:upload

将具有选定 dumpcode 的数据库转储从本地实例上的文件夹 "{{deploy_path}}/.dep/databases/dumps/" 上传到目标实例上的文件夹 "{{deploy_path}}/.dep/databases/dumps/"。需要传递所需选项 --options=dumpcode:[value]

示例

dep db:upload live --options=dumpcode:0772a8d396911951022db5ea385535f6

变更日志

请参阅 https://github.com/sourcebroker/deployer-extended-database/blob/master/CHANGELOG.rst