• ansible实现mysql数据库主从复制


    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

  • 相关阅读:
    failed to load the jni shared library jvm
    记一个简单的保护if 的sh脚本
    linux添加自定义的命令!
    fc-san
    DDN
    Everything search syntax
    启动 Apache2.2 的问题
    tomcat4 请求的处理——初步分析
    404 Not Found !
    浏览器 的 session 如何保持?!
  • 原文地址:https://www.cnblogs.com/syy1757528181/p/13168903.html
Copyright © 2020-2023  润新知