简体   繁体   English

Ansible 幂等 MySQL 安装 Playbook

[英]Ansible idempotent MySQL installation Playbook

I want to setup a MySQL server on AWS, using Ansible for the configuration management.我想在 AWS 上设置一个 MySQL 服务器,使用 Ansible 进行配置管理。 I am using the default AMI from Amazon ( ami-3275ee5b ), which uses yum for package management.我正在使用 Amazon ( ami-3275ee5b ) 的默认 AMI,它使用yum进行包管理。

When the Playbook below is executed, all goes well.当执行下面的 Playbook 时,一切顺利。 But when I run it for a second time, the task Configure the root credentials fails, because the old password of MySQL doesn't match anymore, since it has been updated the last time I ran this Playbook.但是当我第二次运行它时, Configure the root credentials的任务失败了,因为 MySQL 的旧密码不再匹配,因为它已在我上次运行此 Playbook 时更新。

This makes the Playbook non-idempotent, which I don't like.这使得 Playbook 非幂等,我不喜欢。 I want to be able to run the Playbook as many times as I want.我希望能够根据需要多次运行 Playbook。

- hosts: staging_mysql
  user: ec2-user
  sudo: yes

  tasks:
    - name: Install MySQL
      action: yum name=$item
      with_items:
        - MySQL-python
        - mysql
        - mysql-server

    - name: Start the MySQL service
      action: service name=mysqld state=started

    - name: Configure the root credentials
      action: command mysqladmin -u root -p $mysql_root_password

What would be the best way to solve this, which means make the Playbook idempotent?解决这个问题的最佳方法是什么,这意味着使 Playbook 幂等? Thanks in advance!提前致谢!

I posted about this on coderwall , but I'll reproduce dennisjac's improvement in the comments of my original post.我在coderwall上发布了这个,但我会在我原来的帖子的评论中重现 dennisjac 的改进。

The trick to doing it idempotently is knowing that the mysql_user module will load a ~/.my.cnf file if it finds one.以幂等方式执行此操作的技巧是知道 mysql_user 模块如果找到一个 ~/.my.cnf 文件将加载一个。

I first change the password, then copy a .my.cnf file with the password credentials.我首先更改密码,然后使用密码凭据复制一个 .my.cnf 文件。 When you try to run it a second time, the myqsl_user ansible module will find the .my.cnf and use the new password.当您尝试第二次运行它时,myqsl_user ansible 模块将找到 .my.cnf 并使用新密码。

- hosts: staging_mysql
  user: ec2-user
  sudo: yes

  tasks:
    - name: Install MySQL
      action: yum name={{ item }}
      with_items:
        - MySQL-python
        - mysql
        - mysql-server

    - name: Start the MySQL service
      action: service name=mysqld state=started

    # 'localhost' needs to be the last item for idempotency, see
    # http://ansible.cc/docs/modules.html#mysql-user
    - name: update mysql root password for all root accounts
      mysql_user: name=root host={{ item }} password={{ mysql_root_password }} priv=*.*:ALL,GRANT
      with_items:
        - "{{ ansible_hostname }}"
        - 127.0.0.1
        - ::1
        - localhost

    - name: copy .my.cnf file with root password credentials
      template: src=templates/root/.my.cnf dest=/root/.my.cnf owner=root mode=0600

The .my.cnf template looks like this: .my.cnf 模板如下所示:

[client]
user=root
password={{ mysql_root_password }}

Edit: Added privileges as recommended by Dhananjay Nene in the comments, and changed variable interpolation to use braces instead of dollar sign .编辑:添加了 Dhananjay Nene 在评论中推荐的权限,并将变量插值更改为使用大括号而不是美元符号

Ansible version for a secure MySQL installation.用于安全 MySQL 安装的 Ansible 版本。

mysql_secure_installation.yml mysql_secure_installation.yml

- hosts: staging_mysql
  user: ec2-user
  sudo: yes

  tasks:
    - name: Install MySQL
      action: yum name={{ item }}
      with_items:
        - MySQL-python
        - mysql
        - mysql-server

    - name: Start the MySQL service
      action: service name=mysqld state=started

    # 'localhost' needs to be the last item for idempotency, see
    # http://ansible.cc/docs/modules.html#mysql-user
    - name: update mysql root password for all root accounts
      mysql_user: name=root host={{ item }} password={{ mysql_root_password }}
      with_items:
        - "{{ ansible_hostname }}"
        - 127.0.0.1
        - ::1
        - localhost

    - name: copy .my.cnf file with root password credentials
      template: src=templates/root/my.cnf.j2 dest=/root/.my.cnf owner=root mode=0600

    - name: delete anonymous MySQL server user for $server_hostname
      action: mysql_user user="" host="{{ server_hostname }}" state="absent"

    - name: delete anonymous MySQL server user for localhost
      action: mysql_user user="" state="absent"

    - name: remove the MySQL test database
      action: mysql_db db=test state=absent

templates/root/my.cnf.j2模板/根/my.cnf.j2

[client]
user=root
password={{ mysql_root_password }}

References参考

This is an alternative solution to the one proposed by @LorinHochStein这是@LorinHochStein 提出的解决方案的替代解决方案

One of my constraints was to ensure that no passwords are stored in plain text files anywhere on the server.我的限制之一是确保没有密码存储在服务器上的任何地方的纯文本文件中。 Thus .my.cnf was not a practical proposition因此 .my.cnf 不是一个实用的提议

Solution :解决方案 :

- name: update mysql root password for all root accounts from local servers
  mysql_user: login_user=root 
              login_password={{ current_password }} 
              name=root 
              host=$item 
              password={{ new_password }} 
              priv=*.*:ALL,GRANT
  with_items:
      - $ansible_hostname
      - 127.0.0.1
      - ::1
      - localhost

And in the vars file在 vars 文件中

current_password: foobar
new_password: "{{ current_password }}"

When not changing the mysql password run ansible playbook on command line as usual.当不更改 mysql 密码时,像往常一样在命令行上运行 ansible playbook。

When changing the mysql password, add the following to the command line.更改mysql密码时,在命令行中添加以下内容。 Specifying it on the commandline allows the parameter set on the command line to take precedence over the one defaulted to in the vars file.在命令行上指定它允许在命令行上设置的参数优先于 vars 文件中默认设置的参数。

$ ansible-playbook ........ --extra-vars "new_password=buzzz"

After running the command change the vars file as follows运行命令后更改vars文件如下

current_password=buzzz
new_password={{ current_password }}

Adding to the previous answers, I didn't want a manual step before running the command, ie I want to spin up a new server and just run the playbook without having to manually change the root password first time.添加到前面的答案中,我不想在运行命令之前手动执行步骤,即我想启动一个新服务器并只运行 playbook,而不必第一次手动更改 root 密码。 I don't believe {{ mysql_password }} will work the first time, when root password is null, because mysql_password still has to be defined somewhere (unless you want to override it with -e).我不相信 {{ mysql_password }} 会第一次工作,当 root 密码为空时,因为 mysql_password 仍然必须在某处定义(除非你想用 -e 覆盖它)。

So I added a rule to do that, which is ignored if it fails.所以我添加了一个规则来做到这一点,如果失败,则忽略该规则。 This is in addition to, and appears before, any of the other commands here.这是此处任何其他命令的补充,并且出现在此之前。

- name: Change root user password on first run
  mysql_user: login_user=root
              login_password=''
              name=root
              password={{ mysql_root_password }}
              priv=*.*:ALL,GRANT
              host={{ item }}
      with_items:
        - $ansible_hostname
        - 127.0.0.1
        - ::1
        - localhost
      ignore_errors: true

For ansible 1.3+ :对于 ansible 1.3+ :

- name: ensure mysql local root password is zwx123
  mysql_user: check_implicit_admin=True login_user=root login_password="zwx123" name=root password="zwx123" state=present

Well, this came a bit complicated.嗯,这有点复杂。 I've spent a whole day on this and came up with the solution listed below.我花了一整天的时间来解决这个问题,并提出了下面列出的解决方案。 The key point is how Ansible installs MySQL server.关键是 Ansible 如何安装 MySQL 服务器。 From the docs of mysql_user module (last note on page):来自mysql_user模块的文档(页面上的最后一个注释):

MySQL server installs with default login_user of ‘root’ and no password. To secure this user as part of an idempotent playbook, you must create at least two tasks: the first must change the root user’s password, without providing any login_user/login_password details. The second must drop a ~/.my.cnf file containing the new root credentials. Subsequent runs of the playbook will then succeed by reading the new credentials from the file.

That issue with blank or null password was a big surprise.空白或空密码的问题是一个很大的惊喜。

Role :角色

---

- name: Install MySQL packages
  sudo: yes
  yum: name={{ item }} state=present
  with_items:
    - mysql
    - mysql-server
    - MySQL-python


- name: Start MySQL service
  sudo: yes
  service: name=mysqld state=started enabled=true


- name: Update MySQL root password for root account
  sudo: yes
  mysql_user: name=root password={{ db_root_password }} priv=*.*:ALL,GRANT


- name: Create .my.cnf file with root password credentials
  sudo: yes
  template: src=.my.cnf.j2 dest=/root/.my.cnf owner=root group=root mode=0600
  notify:
  - restart mysql


- name: Create a database
  sudo: yes
  mysql_db: name={{ db_name }}
            collation=utf8_general_ci
            encoding=utf8
            state=present


- name: Create a database user
  sudo: yes
  mysql_user: name={{ db_user }}
              password={{ db_user_password }}
              priv="{{ db_name }}.*:ALL"
              host=localhost
              state=present

Handler :处理程序

---

- name: restart mysql
  service: name=mysqld state=restarted

.my.cnf.j2 : .my.cnf.j2 :

[client]
user=root
password={{ db_root_password }}

The following will Work (Insert my.cnf in between 2 mysql_user calls)以下将起作用(在 2 个 mysql_user 调用之间插入 my.cnf)


- name: 'Install MySQL'
    yum: name={{ item }} state=present
    with_items:
    - MySQL-python
    - mysql
    - mysql-server
    notify:
     - restart-mysql
- name: 'Start Mysql Service'
  action: service name=mysqld state=started enabled=yes
- name: 'Update Mysql Root Password'
  mysql_user: name=root host=localhost password={{ mysql_root_password }} state=present
- name: 'Copy Conf file with root password credentials'
  template: src=../templates/my.cnf.j2 dest=/root/.my.cnf owner=root mode=0600
- name: 'Update Rest-Mysql Root Password'
  mysql_user: name=root host={{ item }} password={{ mysql_root_password }} state=present
    with_items:
    - "{{ ansible_hostname }}"
    - "{{ ansible_eth0.ipv4.address }}"
    - 127.0.0.1
    - ::1
- name: 'Delete anonymous MySQL server user from server'
  mysql_user: name="" host={{ ansible_hostname }} state="absent"

please try this for mysql installation using ansible playbook请尝试使用 ansible playbook 安装 mysql

hosts: slave.server.com become: yes主机:slave.server.com 变为:是

tasks:任务:

  • name: "Installing Repo" shell: sudo rpm -Uvh http://dev.mysql.com/get/mysql57-community-release-el6-7.noarch.rpm ignore_errors: yes名称:“安装回购”外壳:sudo rpm -Uvh http://dev.mysql.com/get/mysql57-community-release-el6-7.noarch.rpm ignore_errors:是

  • name: "Installing MySQL 5.7" package: name=mysql-community-server state=present名称:“安装 MySQL 5.7”包:名称=mysql-community-server state=present

  • name: Start the MySQL service service: name: mysqld state: started enabled: yes name:启动MySQL服务 service:name:mysqld state:started enabled:yes

  • name: Find MySQL root password shell: "echo grep 'temporary.*root@localhost' /var/log/mysqld.log | sed 's/.*root@localhost: //' " register: mysql_root_pass name: 查找 MySQL root 密码 shell: "echo grep 'temporary.*root@localhost' /var/log/mysqld.log | sed 's/.*root@localhost: //' " register: mysql_root_pass

I know this is an old question, but I am sharing my working playbook for those, who are looking for it:我知道这是一个老问题,但我正在为那些正在寻找它的人分享我的工作手册:

mysql.yml mysql.yml

---
 - name: Install the MySQL packages
   apt: name={{ item }} state=installed update_cache=yes
   with_items:
     - mysql-server-5.6
     - mysql-client-5.6
     - python-mysqldb
     - libmysqlclient-dev

 - name: Copy the configuration file (my.cnf)
   template: src=my.cnf.j2 dest=/etc/mysql/my.cnf
   notify:
     - Restart MySQL

 - name: Update MySQL root password for all root accounts
   mysql_user: name=root host={{ item }} password={{ mysql_root_pass }} state=present
   with_items:
     - "{{ ansible_hostname }}"
     - 127.0.0.1
     - ::1
     - localhost

 - name: Copy the root credentials as .my.cnf file
   template: src=root.cnf.j2 dest=~/.my.cnf mode=0600

 - name: Ensure Anonymous user(s) are not in the database
   mysql_user: name='' host={{ item }} state=absent
   with_items:
     - localhost
     - "{{ ansible_hostname }}"

 - name: Remove the test database
   mysql_db: name=test state=absent
   notify:
     - Restart MySQL

vars.yml变量名

---
 mysql_port: 3306 #Default is 3306, please change it if you are using non-standard
 mysql_bind_address: "127.0.0.1" #Change it to "0.0.0.0",if you want to listen everywhere
 mysql_root_pass: mypassword #MySQL Root Password

my.cnf.j2我的.cnf.j2

[client]
port            = 3306
socket          = /var/run/mysqld/mysqld.sock

[mysqld_safe]
socket          = /var/run/mysqld/mysqld.sock
nice            = 0

[mysqld]
user            = mysql
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
port            = {{ mysql_port }}
basedir         = /usr
datadir         = /var/lib/mysql
tmpdir          = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
bind-address            = {{ mysql_bind_address }}
key_buffer              = 16M
max_allowed_packet      = 64M
thread_stack            = 192K
thread_cache_size       = 8
myisam-recover         = BACKUP
query_cache_limit       = 1M
query_cache_size        = 16M
log_error = /var/log/mysql/error.log
expire_logs_days        = 10
max_binlog_size         = 100M

[mysqldump]
quick
quote-names
max_allowed_packet      = 64M

[mysql]

[isamchk]
key_buffer              = 16M

!includedir /etc/mysql/conf.d/

root.cnf.j2根.cnf.j2

[client]
user=root
password={{ mysql_root_pass }}

It is important to start/re-start the mysql server prior to setting the root password.在设置 root 密码之前启动/重新启动 mysql 服务器很重要。 Also, I had tried everything posted up to this post [date] and discovered it is imperative to pass login_password and login_user .另外,我已经尝试了在这篇文章 [date] 之前发布的所有内容,并发现必须传递login_passwordlogin_user

(ie) Any Plays after setting the mysql_user user:root and password= {{ SOMEPASSWORD }} , you must connect using login_password and login_user for any subsequent play. (即)设置mysql_user user:rootpassword= {{ SOMEPASSWORD }}后的任何播放,您必须使用login_passwordlogin_user进行连接以进行任何后续播放。

Note: The with_items below is based on what Ansible &/ MariaDB default hosts created .注意:下面的with_items是基于 Ansible &/ MariaDB 默认主机创建的

Example for Securing a MariaDB Server:保护 MariaDB 服务器的示例:

---
# 'secure_mariadb.yml'

- name: 'Ensure MariaDB server is started and enabled on boot'
  service: name={{ mariadb_service_name }} state=started enabled=yes

# localhost needs to be the last item for idempotency, see
# http://ansible.cc/docs/modules.html#mysql-user
- name: 'Update Mysql Root Password'
  mysql_user: name=root
              host={{ item }}
              password={{ root_db_password }}
              priv=*.*:ALL,GRANT
              state=present
  with_items:
    - 127.0.0.1
    - ::1
    - instance-1 # Created by MariaDB to prevent conflicts between port and sockets if multi-instances running on the same computer.
    - localhost

- name: 'Create MariaDB main configuration file'
  template: >
    src=my.cnf.j2
    dest=/etc/mysql/my.cnf
    owner=root
    group=root
    mode=0600

- name: 'Ensure anonymous users are not in the database'
  mysql_user: login_user=root 
              login_password={{ root_db_password }}
              name=''
              host={{ item }}
              state=absent
  with_items:
    - 127.0.0.1
    - localhost

- name: 'Remove the test database'
  mysql_db: login_user=root 
            login_password={{ root_db_password }}
            name=test
            state=absent

- name: 'Reload privilege tables'
  command: 'mysql -ne "{{ item }}"'
  with_items:
    - FLUSH PRIVILEGES
  changed_when: False

- name: 'Ensure MariaDB server is started and enabled on boot'
  service: name={{ mariadb_service_name }} state=started enabled=yes


# 'End Of File'

I'm adding my own take on the various approaches (centos 7).我正在添加我自己对各种方法的看法(centos 7)。

The variable mysql_root_password should be stored in an ansible-vault (better) or passed on the command-line (worse)变量 mysql_root_password 应该存储在 ansible-vault(更好)或通过命令行传递(更糟)

- name: "Ensure mariadb packages are installed"
  yum: name={{ item }} state="present"
  with_items:
    - mariadb
    - mariadb-server

- name: "Ensure mariadb is running and configured to start at boot"
  service: name=mariadb state=started enabled=yes

# idempotently ensure secure mariadb installation --
# - attempts to connect as root user with no password and then set the root@ mysql password for each mysql root user mode.
# - ignore_errors is true because this task will always fail on subsequent runs (as the root user password has been changed from "")
- name: Change root user password on first run, this will only succeed (and only needs to succeed) on first playbook run
  mysql_user: login_user=root
              login_password=''
              name=root
              password={{ mysql_root_password }}
              priv=*.*:ALL,GRANT
              host={{ item }}
  with_items:
    - "{{ ansible_hostname }}"
    - 127.0.0.1
    - ::1
    - localhost
  ignore_errors: true

- name: Ensure the anonymous mysql user ""@{{ansible_hostname}} is deleted
  action: mysql_user user="" host="{{ ansible_hostname }}" state="absent" login_user=root login_password={{ mysql_root_password }}

- name: Ensure the anonymous mysql user ""@localhost is deleted
  action: mysql_user user="" state="absent" login_user=root login_password={{ sts_ad_password }}

- name: Ensure the mysql test database is deleted
  action: mysql_db db=test state=absent login_user=root login_password={{ mysql_root_password }}

We have spent a lot of time on this issue.我们在这个问题上花了很多时间。 For MySQL 5.7 and above we concluded it is easier to simply ignore the root account, and set permissions on a regular MySQL user.对于 MySQL 5.7 及更高版本,我们得出结论,简单地忽略 root 帐户并为常规 MySQL 用户设置权限更容易。

Reasons原因

  1. Setting the root password is difficult设置root密码很困难
  2. unix_socket auth plugin conflicts with the standard auth plugin unix_socket身份验证插件与标准身份验证插件冲突
  3. Reliably changing the root password after disabling unix_socket plugin is almost impossible禁用unix_socket插件后可靠地更改 root 密码几乎是不可能的
  4. Ansible is not well suited to atomically changing the root password in one step Ansible 不太适合一步原子地更改 root 密码
  5. Using a normal account broadly works well广泛使用普通帐户效果很好

If you abandon idempotency, then you can get it to work fine.如果你放弃幂等性,那么你可以让它正常工作。 However, since the ansible value proposition is that idempotency is possible, we find that developers waste time with the wrong assumption.然而,由于 ansible 的价值主张是幂等性是可能的,我们发现开发人员在错误的假设上浪费时间。

The mere existence of a hack option like check_implicit_admin starts to hint to us that deterministic MySQL setup is not that easy.仅仅存在像check_implicit_admin这样的 hack 选项check_implicit_admin开始向我们暗示确定性的 MySQL 设置并不那么容易。 If it's actually deterministic, there should be no "check", there should only be "do".如果它实际上是确定性的,就不应该有“检查”,应该只有“做”。

I am using Ansible 2.9.20 and have created the playbook for mysql Installation of version 8.0.26.我正在使用 Ansible 2.9.20 并为 8.0.26 版的 mysql 安装创建了剧本。 There are some changes for this mysql version Installation, so adding the solution here which worked for me.此 mysql 版本安装有一些更改,因此在此处添加对我有用的解决方案。

MySQL.yml MySQL.yml

---
# tasks file for mysql_setup
- name: Upgrade all packages
  yum:
    name: "*"
    state: latest

- name: Install MySQL repository
  yum:
    name: "https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm"
    state: present

- name: Install MySQL
  yum:
    name: ['mysql-community-devel*', 'mysql-community-server*', 'MySQL-python']
    state: present

- name: copy my.cnf
  copy:
    src: ../files/etc/my.cnf
    dest: /etc/my.cnf
    mode: 0644

- name: Enable the MySQL service
  service:
    name: mysqld
    state: restarted
    enabled: true

- name: Read secret file
  include_vars: "defaults/secret.yml"

- name: get root password
  shell: "grep 'A temporary password is generated for root@localhost' /var/log/mysqld.log | awk -F ' ' '{print $(NF)}'"
  register: root_password

- name: Ensure root can login into MySQL localhost using temporary password
  shell: "mysql -uroot -p'{{ root_password.stdout }}' --connect-expired-password"
  with_items:
    - 127.0.0.1
    - ::1
    - localhost
  register: root_login_tmp_pass
  ignore_errors: yes

- name: update expired root user password
  command: mysql --user root --password={{ root_password.stdout }} --connect-expired-password --execute="ALTER USER 'root'@'localhost' IDENTIFIED BY '{{ secret.passwd_mysql_root }}';"
  when: root_login_tmp_pass is succeeded

- name: update root user password
  command: mysql --user root --password={{ secret.current_passwd_mysql_root }} --execute="ALTER USER 'root'@'localhost' IDENTIFIED BY '{{ secret.passwd_mysql_root }}';"
  when: root_login_tmp_pass is failed

- name: Copy root .my.cnf file
  template:
    src: ../templates/root-my.cnf.j2
    dest: /root/.my.cnf
    owner: root
    group: root
    mode: 0600

- name: Create a database
  mysql_db: name={{ db_name }}
            collation=utf8_general_ci
            encoding=utf8
            state=present

- name: Create a database user
  mysql_user: name={{ db_user }}
              password={{ secret.db_user_password }}
              priv="{{ db_name }}.*:ALL"
              host=localhost
              state=present

templates/root-my.cnf.j2模板/root-my.cnf.j2

[client]
user=root
password={{ secret.passwd_mysql_root }}

files/etc/my.cnf文件/etc/my.cnf

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
default-authentication-plugin=mysql_native_password

defaults/main.yml默认值/main.yml

---
# defaults file for mysql_setup
db_name: mydb
db_user: iamuser

defaults/secret.yml默认值/secret.yml

secret:
  passwd_mysql_root: RootPassword2!3
  db_user_password: iamdbpassword
  current_passwd_mysql_root: currRootPass2!3

After running this playbook twice, you have to update this secret.yml file with your current password (current_passwd_mysql_root) and root Password that you want to set (passwd_mysql_root).运行此剧本两次后,您必须使用当前密码 (current_passwd_mysql_root) 和要设置的 root 密码 (passwd_mysql_root) 更新此 secret.yml 文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 ansible 剧本中使用密码执行 mysql 查询 - How to execute mysql query with password in ansible playbook 对于ansible来说,优雅的重载是幂等的吗? - Is a graceful reload idempotent for ansible? Ansible playbook错误:无法在路径中找到所需的可执行mysql - Ansible playbook error: Failed to find required executable mysql in paths 使用 Ansible playbook 为增量备份启用 mysql bin 日志记录 - Use Ansible playbook to enable mysql bin logging for incremental backups Ansible playbook在尝试执行mysql操作时遇到困难 - Ansible playbook gets stuck trying to perform mysql operations Ansible Playbook 使用 mysql 1044,“用户 'root'@'localhost' 对数据库 'scm' 的访问被拒绝” - Ansible Playbook using mysql 1044, "Access denied for user 'root'@'localhost' to database 'scm'" ansible-playbook zlib 数据压缩错误使用 mysql_user 模块 - ansible-playbook zlib data compression error using mysql_user module 如何使用基于binlog的Ansible Playbook在mysql中实现“ 1小时定时增量备份”? - How can I achieve 'incremental backup with 1 hour timing' period in mysql using Ansible Playbook based on binlog? 在MySQL中使用值插入创建幂等表和索引 - Idempotent table and index creation with value insertion in MySQL Ansible 剧本通过 maxscale 在 mariadb 上创建数据库 - Ansible playbook to create database on mariadb via maxscale
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM