Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 使用ansible应用数据库迁移_Linux_Postgresql_Bash_Ansible - Fatal编程技术网

Linux 使用ansible应用数据库迁移

Linux 使用ansible应用数据库迁移,linux,postgresql,bash,ansible,Linux,Postgresql,Bash,Ansible,我确实希望在使用ansible获取构建工件时应用迁移 一些事实: 迁移是纯sql的 Postresql处于群集模式(无分片) 有2台主机(api1和api2) 不需要“向下机械装置” 可能的问题: 如何选择运行迁移的主机(第一个就绪主机还是始终主主机) 如何跟踪已应用的脚本并避免重复应用 我对如何解决这个问题的想法是: 使用fs层: 每个构建工件都将包含sql迁移 部署后,主主机应将现有迁移文件与新文件区分开来,并应用新文件,通过用新文件替换旧文件来保存状态 使用community.p

我确实希望在使用ansible获取构建工件时应用迁移

一些事实:

  • 迁移是纯sql的
  • Postresql处于群集模式(无分片)
  • 有2台主机(api1和api2)
  • 不需要“向下机械装置”
可能的问题:

  • 如何选择运行迁移的主机(第一个就绪主机还是始终主主机)
  • 如何跟踪已应用的脚本并避免重复应用
我对如何解决这个问题的想法是:

使用fs层:

  • 每个构建工件都将包含sql迁移
  • 部署后,主主机应将现有迁移文件与新文件区分开来,并应用新文件,通过用新文件替换旧文件来保存状态
  • 使用
    community.postgresql.postgresql\u查询执行迁移
这种方式看起来很奇怪-在我看来,fs不可靠,主主机可以更改(被销毁等)

使用数据库:

  • 每个构建工件都将包含sql迁移
  • 部署后,第一个就绪的主机应该查询一些表以获取应用的迁移,并应用新的迁移,通过插入新的迁移名称保存状态
    community.postgresql.postgresql\u query
这种方式看起来更好-db仍然可靠,但是否可以使用ansible

我不熟悉python,所以我不能接受像“编写自己的插件”这样的解决方案——将来我将无法支持它。任何NPM软件包都不是首选,我仅限于编译解决方案和内置linux工具,如
python
bash
,等等

顺便说一句,剧本看起来像:

---
- hosts: api
  vars:
    api_apps:
      - name: "Api"
        description: "API service"
        exec: "/usr/local/bin/handler"
        identifier: "handler"
        env:
          - name: PORT
            value: "3000"
          - name: DB_TYPE
            value: 'postgres'
          - name: DB_PATH
            value: "postgres://{{hostvars['db01'].postgresql_users[0].name}}:{{hostvars['db01'].postgresql_users[0].pass}}@{{hostvars['db01'].private_ip}}:{{hostvars['db01'].postgresql_port}}/{{hostvars['db01'].postgresql_databases[0].name}}"
          - name: ACCESS_CONTROL_ALLOW_ORIGIN
            value: "\"*""
          - name: ACCESS_CONTROL_MAX_AGE
            value: 9600
  tasks:
    - block: # Pull and extract artifacts
      - name: "[ api ] Pull release info"
        uri:
          url: "https://api.github.com/repos/<my_profile>/{{ item }}/releases/latest"
          headers:
            Authorization: "Bearer {{ github_token }}"
          return_content: true
        register: release_response
        no_log: True
        with_items:
          - "<my_private_repo>"

      - name: "[ api ] Pull latest artifact"
        get_url:
          url: "{{ item.json.assets[0].url }}"
          headers:
            Accept: "application\/octet-stream"
            Authorization: "Bearer {{ github_token }}"
          force: true
          dest: "/tmp/{{ item.item }}.zip"
        no_log: True
        register: pulled_items
        with_items: "{{ release_response.results }}"

      - name: Extract archives
        unarchive:
          src: "/tmp/{{ item.item.item }}.zip"
          dest: "/usr/local/bin"
          remote_src: yes
        no_log: True
        with_items: "{{ pulled_items.results }}"

      - name: create service templates
        template:
          src: "files/api/service.j2"
          dest: "/etc/systemd/system/{{item.identifier}}.service"
        with_items: "{{ api_apps }}"
        no_log: False

      - name: Start services
        systemd:
          state: restarted
          daemon_reload: yes
          name: "{{item.identifier}}"
        with_items: "{{api_apps}}"
---
-主机:api
变量:
api_应用程序:
-名称:“Api”
说明:“API服务”
exec:“/usr/local/bin/handler”
标识符:“处理程序”
环境:
-名称:港口
价值:“3000”
-名称:DB_类型
价值:“博士后”
-名称:DB_路径
值:“postgres://{{hostvars['db01'].postgresql_用户[0].name}:{{hostvars['db01'].postgresql_用户[0].pass}@{{hostvars['db01'].private_ip}:{{hostvars['db01'].postgresql_端口}/{hostvars['db01'].postgresql_数据库[0].name}”
-名称:访问\控制\允许\原点
值:“\”*“”
-名称:访问控制最大年龄
价值:9600
任务:
-块:#拉取和提取工件
-名称:“[api]拉取发布信息”
uri:
url:“https://api.github.com/repos//{{item}}/releases/latest“
标题:
授权:“承载{{github_token}}”
返回内容:true
寄存器:释放响应
没有日志:正确
有以下项目:
- ""
-名称:“[api]拉取最新工件”
获取url:
url:“{item.json.assets[0].url}”
标题:
接受:“应用程序\/octet流”
授权:“承载{{github_token}}”
原力:对
dest:“/tmp/{{item.item}}.zip”
没有日志:正确
登记:已删除的项目
带_项:“{release_response.results}”
-名称:提取档案
无归档:
src:“/tmp/{{item.item.item}}.zip”
目的地:“/usr/local/bin”
遥控器:是的
没有日志:正确
带_项:“{{pull_items.results}”
-名称:创建服务模板
模板:
src:“文件/api/service.j2”
dest:“/etc/systemd/system/{{item.identifier}}.service”
带_项:“{api_apps}”
无日志:False
-名称:启动服务
系统D:
状态:重新启动
daemon_重新加载:是
名称:“{item.identifier}”
带_项:“{api_apps}”
如何跟踪已应用的脚本并避免重复应用

在数据库世界中,有两种主要的数据库自动迁移方法

  • 基于州的迁移
    • 源代码管理处于一致状态的所有数据库对象
    • 部署工具将存储库状态与live DB进行比较,并生成差异脚本
    • 脚本是对象定义,如:创建表
    • 例如:
  • 基于迁移的方法
    • 源代码管理:不断发展的对象和更改
    • 部署脚本
    • 脚本主要类似于:ALTER/CREATE或REPLACE
    • 例如:
    每种方法都有其优缺点。我不知道有任何现有工具支持PosrgreSQL的状态迁移


    为了避免重复使用相同的脚本:

    理想情况下,每个SQL脚本都应该是独立的和正交的

    例如,如果需要添加新列:

    ALTER TABLE tab ADD COLUMN new_col INT;
    
    此脚本不是幂等的,因为第二次运行将失败。因此,我们可以将其保护为:

    ALTER TABLE tab ADD COLUMN IF NOT EXISTS new_col INT; 
    
    另一个常见示例是添加字典数据:

    -- instead of 
    INSERT INTO tab(col, ...) VALUES (...);
    
    -- use upsert to handle existing data
    INSERT INTO tab(col, ...)
    VALUES(....) 
    ON CONFLICT (...) 
    DO 
    
    另一个问题是正确的脚本顺序。例如,在创建使用新列的视图时,必须首先使用ALTERTABLE

    正如我们所看到的,原本微不足道的事情变得越来越棘手

    幸运的是我们有工具。其主要思想是一个迁移跟踪表,其中包含已运行脚本的完整历史记录。通过订购SQL脚本,我们可以完全控制部署的内容


    相关:

    我怀疑你是否能得到答案,因为这更像是一个支持问题。您正在尝试使用气动锤来推动销。也许它最终会以价值而告终。@sorin,也许你是对的Symfony/Doctrine使用这种行为。基本上,它所做的是有一个
    迁移
    表,记录已经运行的迁移文件的名称。然后,每次您要求进行完全迁移时,它都会将文件与表的记录区分开来,并且仅