查看原文
其他

ansible自动化:mysql主从同步

木讷大叔爱运维 木讷大叔爱运维 2022-07-13

点击上方蓝色字体,关注我们




读完需 8 分钟

速读需 4 分钟 



ansible自动化:编译安装mysql》一文介绍了如何自动化编译安装mysql,如何再进一步按照自定义的参数实现mysql主从同步?下面就是我们本文要介绍的内容。


1

配置思路


ansible配合mysql_user、mysql_db、mysql_replication等模块,在客户端创建数据库、创建用户及配置主从。


2

目录结构


Playbook的目录组织结构如下:

  • files:存放需要同步到异地服务器的源码文件及配置文件;

  • handlers:当资源发生变化时需要进行的操作,若没有此目录可以不建或为空;

  • meta:角色定义可留空;

  • tasks:mysql主从配置过程需要进行的执行的任务;

  • templates:用于需要同步数据库的模板文件,一般为脚本;

  • vars:本次安装定义的变量;

[root@test ansible]# mkdir -p roles/mysql_install/{files,handlers,meta,tasks,templates,vars}[root@test ansible]# tree /etc/ansible├── ansible.cfg├── hosts├── mysql_repl.yml|____roles| |____mysql_repl| | |____files| | |____meta| | |____templates| | | |____modify_repldb.sh| | |____handlers| | | |____main.yml| | |____tasks| | | |____main.yml| | |____vars| | | |____main.yml


3

具体实现


1.添加hosts文件

在此将mysql主从角色分为以下两组

[mysql_slave]128.196.11.61 ansible_ssh_user=root ansible_ssh_pass=Root[mysql_master]128.196.11.60 ansible_ssh_user=root ansible_ssh_pass=Root

2.创建mysql角色文件,用于调用mysql_repl

# vim mysql_repl.yml - hosts: mysql_master remote_user: root gather_facts: False roles: - {role: mysql_repl,mysql_repl_role: master}
- hosts: mysql_slave remote_user: root gather_facts: False roles:    - {role: mysql_repl,mysql_repl_role: slave,mysql_repl_master: 128.196.11.60,mysql_repl_user: [{name: repl,passwd: repl}]}

以上由于主从使用同一套脚本,因此我们在role角色中通过mysql_repl_role定义了主、从角色,以此来区分在不同角色执行不同的操作,另外通过mysql_repl_user来指定同步用户,此用户需要和vars中的一样。


3.创建变量文件

其中相关变量用途如下:

  • source_dir:客户端脚本存放目录;

  • mysql_root_pwd:数据库root用户密码;

  • mysql_port:数据库端口;

  • socket:数据库socket,ansible通过socket登陆数据库;

  • mysql_db:name为数据库名字,replicate定义了哪些库需要同步,哪些不需要同步,设置此参数的目的是modify_repldb.sh脚本调用来修改my.cnf配置文件;

  • mysql_remote_user:定义了远程使用账户信息,并都授予了相关权限;

  • mysql_repl_user:定义了同步账户信息,并都授予了相关权限;

# vim vars/main.ymlsource_dir: /home/db/mysql/src/mysql_root_pwd: test2017mysql_port: 13306socket: /tmp/mysql.sock
mysql_db:- name: test1 replicate: yes- name: test2 replicate: no- name: test3 replicate: no
mysql_remote_user:- name: remote passwd: remote priv: "*.*:ALL"
mysql_repl_user:- name: repl passwd: repl  priv: '*.*:"REPLICATION SLAVE"'

4.创建任务文件

自动配置主从同步步骤都设定了条件when,以防止主从在缺少依赖条件下仍会自动配置,导致我们浪费时间查找文件。其中有几点需要注意的地方:

  1. “create repl database”这步本打算是建好库后进行主从同步,但是测试发现提前建库,无法同步到slave上;但是建好同步后,再建库是可以同步的,因此此步骤注释掉;

  2. “restart mysqld service”这步本来打算使用handlers,但是发现修改配置文件无法立即触发重启mysql的handlers,此handlers会在所有步骤完成后最后执行,导致无法自动start slave。因此我们虽定义了handlers,但未使用;

  3. ignore_errors的使用是忽略执行某一步骤失败后导致整个ansible退出

  4. delegate_to的使用目的是在从上执行changemaster时,委派任务到master上getmaster同步信息;

  5. register是把获取的信息存到相关变量中;


# vim tasks/main.yml# 1.客户端必须安装MySQL-python- name: install MySQL-python yum: name=MySQL-python # 此步骤为建库#- name: create repl database# mysql_db: name={{item.name}} login_host=127.0.0.1 login_port={{mysql_port}} login_user=root login_password={{mysql_root_pwd}} state=present# with_items: mysql_db# when: mysql_repl_role == "master"
# 2.创建远程使用用户- name: create database remote user mysql_user: login_host=127.0.0.1 login_port={{mysql_port}} login_user=root login_password={{mysql_root_pwd}} name={{item.name}} password={{item.passwd}} priv={{item.priv}} state=present host="%" with_items: mysql_remote_user when: mysql_remote_user|lower() != 'none'
# 3.在主库上创建同步账户- name: create replication user mysql_user: login_host=127.0.0.1 login_port={{mysql_port}} login_user=root login_password={{mysql_root_pwd}} name={{item.name}} password={{item.passwd}} priv={{item.priv}} state=present host="%" with_items: mysql_repl_user when: mysql_repl_role == "master"
# 4.复制脚本到客户端- name: copy modify replication db script to client template: src=modify_repldb.sh dest={{source_dir}} owner=root group=root mode=0775
# 5.执行脚本按照master、slave修改my.cnf- name: modify replication db in my.cnf shell: bash {{source_dir}}/modify_repldb.sh
# 6.修改配置文件后重启数据库- name: restart mysqld service #service: name=mysqld state=restarted command: su mysql -c "service mysqld restart"
# 7.在slave上判断是否配置过主从信息,若没有为false,并将其存到slave变量中。- name: check if slave is already configured for replication mysql_replication: login_unix_socket={{socket}} login_user=root login_password={{mysql_root_pwd}} mode=getslave ignore_errors: true register: slave when: mysql_repl_role == "slave"
# 8.在从上变量slave为false,并且从节点定义了需要同步的主节点(mysql_repl_master),则通过delegate_to委派在主上执行getmaster获取同步信息,并将这些信息存到repl_master_status变量中- name: get the current master servers replication status mysql_replication: login_unix_socket={{socket}} login_user=root login_password={{mysql_root_pwd}} mode=getmaster delegate_to: "{{mysql_repl_master}}" register: repl_master_status when: slave|failed and mysql_repl_role == "slave" and mysql_repl_master is defined
# 9.在从上变量slave为false,并且从节点定义了需要同步的主节点(mysql_repl_master),则在从上执行changemaster- name: change the master on slave to start the replication mysql_replication: login_unix_socket={{socket}} login_user=root login_password={{mysql_root_pwd}} mode=changemaster master_host={{mysql_repl_master}} master_port={{mysql_port}} master_log_file={{repl_master_status.File}} master_log_pos={{repl_master_status.Position}} master_user={{mysql_repl_user[0].name}} master_password={{mysql_repl_user[0].passwd}} ignore_errors: true when: slave|failed and mysql_repl_role == "slave" and mysql_repl_master is defined
# 10.在从上启动同步- name: start slave on slave to start the replication mysql_replication: login_unix_socket={{socket}} login_user=root login_password={{mysql_root_pwd}} mode=startslave when: slave|failed and mysql_repl_role == "slave" and mysql_repl_master is defined


5.编写模板脚本

此模板脚本的作用是获取vars变量中的mysql_db中参数,根据replicate:yes和replicate:no,将需要同步或不同步的库写到my.cnf。

# vim templates/modify_repldb.sh#!/bin/bash#auth:yanggd#content: modify replication db
{% if mysql_repl_role == "master" %}{% for i in mysql_db %}{% if i.replicate|default(1) %}sed -i "/server-id/a replicate-do-db={{i.name}}" /etc/my.cnfsed -i "/server-id/a binlog-do-db={{i.name}}" /etc/my.cnf{% endif %}{% endfor %}
{% for i in mysql_db %}{% if not i.replicate|default(1) %}sed -i "/server-id/a binlog-ignore-db={{i.name}}" /etc/my.cnf{% endif %}{% endfor %}{% endif %}

{% if mysql_repl_role == "slave" %}{% for i in mysql_db %}{% if i.replicate|default(1) %}sed -i "/server-id/a replicate-do-db={{i.name}}" /etc/my.cnf{% endif %}{% endfor %}
{% for i in mysql_db %}{% if not i.replicate|default(1) %}sed -i "/server-id/a binlog-ignore-db={{i.name}}" /etc/my.cnf{% endif %}{% endfor %}{% endif %}

6.定制部署
通过以上我们就可以随意部署一组主从了,我们可以定义mysql_repl.yml和vars/main.yml中变量来定制主从了。

#检查文件[root@test ansible]# ansible-playbook -C mysql_repl.yml#执行playbook[root@test ansible]# ansible-playbook mysql_repl.yml

执行完成后,我们在主库上创建test1、test2、test3,可看到从库上test1进行了同步,而test2、test3没有,因为我们设置的test1的属性为replicate:yes。


4

总结


至此,关于mysql的自动化操作的实现,为数据层的相关自动化操作提供了初步的思路。后续有其他的需求,也可以通过playbook编排实现。



面对中小企业的开源运维平台spug

版本发布过程中的屏蔽/恢复告警

vcenter自定义规范定制虚拟机-vsphere client

腾讯蓝鲸实现vsphere虚拟机交付

Docker动态构建Jenkins Slave

Teleport:开源简单易用的堡垒机



你与世界

只差一个

公众号




您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存