digitalerase/deployer-extended-database

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

16.1.0.5 2023-04-12 05:58 UTC

README

https://scrutinizer-ci.com/g/sourcebroker/deployer-extended-database/badges/quality-score.png?b=master 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 [源实例]",允许您从远程实例拉取数据库到本地实例,
  2. 任务 "db:push [目标实例]",允许您从本地实例推送到远程实例,
  1. 任务 "db:copy [源实例] --options=target:[目标实例]",允许在远程实例之间复制数据库。

安装

  1. 使用 Composer 安装软件包

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

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

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

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

  2. 定义 "development" 服务器并为其设置 "db_databases"。使用以下代码

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

    该代码将从 .env 文件中读取数据库数据。

    host('development')
        ->set('deploy_path', getcwd())
        ->set('db_databases', [
            'database_default' => [
                (new \SourceBroker\DeployerExtendedDatabase\Driver\EnvDriver())->getDatabaseConfig()
            ]
        ])
    
  3. 为所有其他服务器添加 "db_databases" 变量。例如,对于生产服务器,它可以如下所示

    host('production')
        ->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 production 以测试是否一切正常。

选项

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

"db_databases" 选项

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

  • 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('production')
      ->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('development')
      ->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('production')
    ->setHostname('my-server.example.com')
    ->setRemoteUser('deploy')
    ->set('deploy_path', '/var/www/myapplication/');

host('development')
   ->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('production')
    ->setHostname('my-server.example.com')
    ->setRemoteUser('deploy')
    ->set('deploy_path', '/var/www/myapplication/');

host('development')
   ->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. array,

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

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

  4. class/method,它返回包含数据库选项的数组 (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('production')
    ->setHostname('my-server.example.com')
    ->setRemoteUser('deploy')
    ->set('deploy_path', '/var/www/myapplication/');

host('development')
   ->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/"。

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

示例

dep db:backup development
dep db:backup production
dep db:backup production --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 production --options=dumpcode:0772a8d396911951022db5ea385535f6

db:copy

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

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

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

dep db:copy production --options=target:staging

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

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

将实例复制到由 instance_live_name 定义的实例(默认为 production)是特殊情况。如果您复制到最高实例,则默认情况下您将两次被询问是否真的想要这样做。您可以通过将 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 production --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]。如果没有提供dumpcode,则将其创建并作为JSON结构返回。

示例

示例任务调用

dep db:export production

示例输出文件位于文件夹 {{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 production --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 staging --options=dumpcode:0772a8d396911951022db5ea385535f66

db:process

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

示例

dep db:process staging --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(默认值为 production)指定的实例拉取是特殊情况。如果您拉取到最高实例,则默认情况下您将两次被询问是否真的想这样做。您可以通过将 db_allow_pull_live_force 设置为 true 来禁用询问。您还可以通过将 db_allow_pull_live 设置为 false 来禁止拉取到生产实例。

示例

dep db:pull production

db:push

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

以下是您执行 "db:push" 时将完成的任务列表:

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

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

示例

dep db:push production

db:rmdump

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

示例

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

db:truncate

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

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

dep db:truncate

截断生产实例数据库表。

dep db:truncate production

db:upload

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

示例

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

变更日志

查看 https://github.com/digitalerase/deployer-extended-database/blob/master/CHANGELOG.rst