利用ansible快速部署MySQL主从复制

Posted Oracle一体机用户组

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了利用ansible快速部署MySQL主从复制相关的知识,希望对你有一定的参考价值。

作者简介

裴征峰,现就职于北京海天起点,专家组成员,南京办事处负责人,持有OCP 10g、OCP 11g、OCM11g证书,主要从事客户的现场维护,重大问题的解决,数据库性能分析,服务质量保证等工作。拥有超过八年的Oracle服务经验,具备丰富的行业服务背景,对Oracle数据库有深刻的理解,在Oracle数据库RAC以及高可用解决方案方面具有深厚的实践经验,擅长数据库故障诊断,数据库性能调优。


概述


在互联网工业化水平日渐成熟的今天,IT运维面临着越来越多的挑战,维护的机器数量从数十个、几百个,发展到成千上万。这时侯如果还靠着运维工程师人工部署、维护,那部署维护效率可能会完全跟不上业务发展的速度,运维工程师的压力会越来越大。这时侯,就需要依靠自动化配置管理工具,当前自动化配置管理工具有很多了,这里主要介绍利用ansible来快速部署mysql的主从复制,达到数据库服务快速开通的目的。


ansible介绍


自动化配置管理工具在大型互联网企业中使用较多,传统企业中使用较少。ansible是一个简单高效的自动化运维管理工具,用Python开发,能大批量管理多台机器,可以并发地在多台机器上部署应用、安装软件、执行命令、配置和编排任务。ansible的介绍、安装和使用,在网上已经有很多,一些简单的维护命令可以自行网上查找,这里主要介绍一下ansible playbooks,本文介绍的自动化地部署mysql主从复制,就是由ansible playbooks完成。

 

playbooks是Ansible的配置、部署和编排语言,它可以描述希望目标系统执行的策略,或一般IT流程中的一组步骤,它将一系列ansible模块串起来,完成一系列复杂的维护部署。ansible playbooks脚本比较简单,运维工程师可以很快上手。在使用ansible或ansible playbooks之前,需要配置ansible管理服务器到目标机器的SSH信任。


YAML语法

 

Playbooks 语言是以YAML 格式表示,它不是一个编程或者脚本语言,而是一种配置文件的语言,简洁、可读性高。这里简单介绍一下YAML语法:


- name: 创建目录

    file:

      dest: "{{ item }}"

      state: directory

      owner: root

      group: root

      mode: 0775

    with_items:

    - /mnt/iso

    - "{{DATADIR}}/soft"


大部分的play,都是这个样子,这里这个play的名称是“创建目录”,利用file模块,“{{ item }}”是变量,要创建两个目录/mnt/iso和“{{DATADIR}}/soft”,其中DATADIR是个常量定义,在常量定义文件里定义,并在playbooks调用脚本中被引入,owner和group为用户和组,mode为权限。这就是一个简单的play模块,整个playbooks就是靠这种小的play模块堆积起来,完成复杂的操作。

 

一个模块可以有多个参数,如果不清楚,可以使用ansible-doc命令查看。比如要查看file模块有多少个配置参数,可以使用如下命令:


# ansible-doc file


这些参数,都可以在play中设置。


Playbooks的结构

 

我们看一下自动部署mysql主从复制的playbooks目录结构:


# pwd

/root/playbooks/mysql

# tree

.

├── install_master.yml

├── install_slave.yml

├── launch_master.sh

├── launch_slave.sh

├── roles

│   ├── master

│   │   ├── tasks

│   │   │   ├── create_db.yml

│   │   │   └── main.yml

│   │   └── templates

│   │       ├── install_mysql_master.sh

│   │       └── my.cnf

│   ├── service

│   │   ├── files

│   │   │   └── ntp.conf

│   │   └── tasks

│   │       ├── main.yml

│   │       ├── service_opt_RedHat6.yml

│   │       └── service_opt_RedHat7.yml

│   ├── slave

│   │   ├── tasks

│   │   │   ├── create_db.yml

│   │   │   └── main.yml

│   │   └── templates

│   │       ├── config_slave.sh

│   │       ├── install_mysql_slave.sh

│   │       └── my.cnf

│   ├── user

│   │   ├── files

│   │   │   └── mysql-5.7.20-linux-glibc2.12-x86_64.tar.gz -> /backup/soft/mysql/mysql-5.7.20-linux-glibc2.12-x86_64.tar.gz

│   │   └── tasks

│   │       ├── copy_5.7.yml

│   │       ├── create_os_user.yml

│   │       └── main.yml

│   └── yum

│       ├── files

│       │   ├── RedHat6.8-x86_64.iso -> /backup/soft/os/rhel-server-6.8-x86_64-dvd.iso

│       │   └── RedHat7.2-x86_64.iso -> /backup/soft/os/rhel-server-7.2-x86_64-dvd.iso

│       ├── tasks

│       │   ├── copy.yml

│       │   ├── create_dir.yml

│       │   ├── install_5.7.yml

│       │   ├── main.yml

│       │   ├── mount.yml

│       │   └── umount.yml

│       └── templates

│           ├── RedHat6.8.repo

│           └── RedHat7.2.repo

└── vars.yml


不要看结构这么复杂,其实很好理解。


# tree -f -L 1

.

├── ./install_master.yml

├── ./install_slave.yml

├── ./launch_master.sh

├── ./launch_slave.sh

├── ./roles

└── ./vars.yml


第一层目录里就是一些调用脚本,playbook变量定义文件,roles目录里有一些角色定义,定义角色的目的就是为了重用。我们先看一下调用脚本,如安装MySQL主库时,执行launch_master.sh,会调用install_master.yml


# cat launch_master.sh

ansible-playbook -i ../hosts install_master.yml

# cat install_master.yml

---

- hosts: master

  vars_files:

    - vars.yml

  remote_user: root

  gather_facts: true

  roles:

    - yum

    - service

    - user

    - master


这里install_master.yml引入了变量文件vars.yml,远程执行用户是root,在执行之前,先收集远程服务器的一些信息,按顺序调用的角色有:yum、service、user、master,playbooks会按照角色出现的顺序,分别进入角色中完成相关任务。hosts为playbooks在master组中定义的主机完成调用,安装备机时调用的install_slave.yml中就设置为slave,这里不再查看。我们看一下hosts文件的定义:


# cat ../hosts

[master]

192.168.1.XX1

[slave]

192.168.1.XX2


我们进入roles目录看一下,这里包括了五个角色,作用大致做一下说明master角色是安装mysql主库时调用,slave是安装mysql备库时调用,service角色是设置redhat系统的一些服务,比如:iptables、NTP等,user角色是创建mysql用户、分发mysql软件,yum角色是安装mysql数据库必要的一些操作系统包。


# cd roles

# tree -f -L 1

.

├── ./master

├── ./service

├── ./slave

├── ./user

└── ./yum


在角色目录里,又分各种任务,以yum角色为例:


# cd yum

# tree

.

├── files

│   ├── RedHat6.8-x86_64.iso -> /backup/soft/os/rhel-server-6.8-x86_64-dvd.iso

│   └── RedHat7.2-x86_64.iso -> /backup/soft/os/rhel-server-7.2-x86_64-dvd.iso

├── tasks

│   ├── copy.yml

│   ├── create_dir.yml

│   ├── install_5.7.yml

│   ├── main.yml

│   ├── mount.yml

│   └── umount.yml

└── templates

    ├── RedHat6.8.repo

    └── RedHat7.2.repo


在yum角色目录下,又有3个目录,tasks、files、templates。task目录中的yml脚本就是一个个任务,playbooks进入每个角色后,都会到tasks目录中执行main.yml文件,如果想把任务按功能拆散,就可以在mian.yml中引入其它yml文件,这里我们可以看下main.yml文件:


# cat main.yml

- import_tasks: create_dir.yml

- import_tasks: copy.yml

- import_tasks: mount.yml

- import_tasks: "install_{{MYSQLVERSION}}.yml"

- import_tasks: umount.yml


这里,main.yml引入了5个其它任务文件,然后playbooks就会按次序执行这5个任务文件。

 

上面yum角色目录下,有两个其它目录:file和templates目录,这两个目录是file模块和templates模块使用,当file模块将ansible管理机器上的文件分发到目标机器时,如果不写全路径,可以将文件放入这个目录,或者在这个目录下做软链接。templates目录也一样,主要是给template模块使用。


部署MySQL主从复制的关键技术点


利用ansible部署mysql主从复制的关键在于master和slave角色。如部署主库时,将主库的建库脚本复制到目标机器后,在目标机器上执行建库脚本。


- name: 复制my.cnf文件

    template:

      src: my.cnf

      dest: "/etc/my.cnf"

      owner: root

      group: root

      mode: 0644

 

  - name: 复制MySQL安装脚本

    template:

      src: "{{ item }}"

      dest: /tmp/

      owner: root

      group: root

      mode: 0755

    with_items:

      - install_mysql_master.sh

 

  - name: 执行MySQL安装脚本

    shell: /bin/bash /tmp/install_mysql_master.sh


这里使用template模块复制脚本,可以自动做变量替代,然后利用shell模块执行脚本。


# cat install_mysql_master.sh

#!/bin/sh

\cp -f {{BASEDIR}}/mysql/support-files/mysql.server /etc/rc.d/init.d/

{{BASEDIR}}/mysql/bin/mysqld --initialize-insecure --user=mysql --datadir={{DATADIR}}/{{DBNAME}} --console

/etc/init.d/mysql.server start

ln -sf {{BASEDIR}}/mysql/bin/mysql /usr/bin/mysql

ln -sf {{DATADIR}}/{{DBNAME}}/mysql.sock /tmp/mysql.sock

{{BASEDIR}}/mysql/bin/mysql -uroot -hlocalhost -S{{DATADIR}}/{{DBNAME}}/mysql.sock -e "grant replication slave,reload,super on *.* to '{{REPLUSER}}'@'{{ ansible_default_ipv4.address.split('.')[0] }}.{{ ansible_default_ipv4.address.split('.')[1] }}.{{ ansible_default_ipv4.address.split('.')[2] }}.%' identified by '{{REPLPWD}}'; SET PASSWORD = PASSWORD('{{ROOTPWD}}'); flush privileges;"

rm -rf /tmp/$(basename $0)


而自动部署从库时,由于主库也是空库,从库在完成建库后,查询主库的binlog位置就可以实现复制。


# cat config_slave.sh

#!/bin/sh

 

{{BASEDIR}}/mysql/bin/mysql -u{{REPLUSER}} -p{{REPLPWD}} -h{{groups['master'][0]}} -P{{MYSQLPORT}} -e 'show master status\G' > /tmp/master.txt

MASTER_LOG_FILE=`grep File /tmp/master.txt | awk -F":" '{print $2}' | sed 's/^[ ]\{1,\}//;s/[ ]\{1,\}$//g'`

MASTER_LOG_POS=`grep Position /tmp/master.txt | awk -F":" '{print $2}' | sed 's/^[ ]\{1,\}//;s/[ ]\{1,\}$//g'`

{{BASEDIR}}/mysql/bin/mysql -uroot -p{{ROOTPWD}} -hlocalhost -S{{DATADIR}}/{{DBNAME}}/mysql.sock -e "change master to master_host='{{groups['master'][0]}}', master_port={{MYSQLPORT}}, master_user='{{REPLUSER}}', master_password='{{REPLPWD}}', master_log_file='$MASTER_LOG_FILE', master_log_pos=$MASTER_LOG_POS;"

{{BASEDIR}}/mysql/bin/mysql -uroot -p{{ROOTPWD}} -hlocalhost -S{{DATADIR}}/{{DBNAME}}/mysql.sock -e "start slave;"

rm -rf /tmp/$(basename $0)


总结


这里完成的是简单的MySQL主从复制配置,暂时没有添加MySQL半同步、GTID、并行复制等特性的配置。通过ansible自动化部署,可以达到几分钟开通MySQL主从复制的数据库服务,并且所有安装配置标准统一化。以下是自动化部署MySQL主库过程:


原创文章,版权归本文作者所有,如需转载请注明出处


喜欢本文请长按下方的二维码订阅Oracle一体机用户组

以上是关于利用ansible快速部署MySQL主从复制的主要内容,如果未能解决你的问题,请参考以下文章

利用Amoeba实现MySQL主从复制和读写分离

如何利用docker快速构建MySQL主从复制环境

利用Xtrabackup工具在线部署MySQL 8.0主从复制

Ansible-playbook自动部署MySQL主从

Mysql5.7实现主从 延迟数据复制

Ansible 管理MySQL主从复制