ansible-playbook實戰之批量部署mysql主從同步

簡介

ansible-playbook實戰之批量安裝mysql介紹瞭如何批量安裝mysql,本篇博文用於按照自定義的參數批量部署mysql主從同步。

ansible-playbook配置思路:
ansible配合使用mysql_user、mysql_db、mysql_replication在客戶端創建數據庫、創建用戶及配置主從。

playbook的目錄結構

|____hosts
|____mysql_repl.yml
|____roles
| |____mysql_repl
| | |____files
| | |____meta
| | |____templates
| | | |____modify_repldb.sh
| | |____handlers
| | | |____main.yml
| | |____tasks
| | | |____main.yml
| | |____vars
| | | |____main.yml

其中我們使用modify_repldb.sh讀取變量,來修改my.cnf中的關於主從同步的相關參數,如:replicate-do-db、binlog-do-db、inlog-ignore-db

具體操作

1.添加hosts文件

[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

- 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: /home/db/mysql/src/
mysql_root_pwd: test2017
mysql_port: 13306
socket: /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"'

其中:
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中定義了遠程使用賬戶信息和同步賬戶信息,並都授予了相關權限。

4.創建任務文件

#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

以上是自動配置主從同步的過程,其中每個步驟都設定了條件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是把獲取的信息存到相關變量中;

5.編寫模板腳本

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.cnf
sed -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 %}

此腳本的作用是獲取vars變量中的mysql_db中參數,根據replicate:yes和replicate:no,將需要同步或不同步的庫寫到my.cnf

6.定製部署
通過以上我們就可以隨意部署一組主從了,我們可以定義mysql_repl.yml和vars/main.yml中變量來定製主從了。

執行playbook

#檢查文件
[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

發佈了179 篇原創文章 · 獲贊 299 · 訪問量 61萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章