《 Mysql-mmm 实现 HA 》 《瞬间表锁  mmm-tools 实现快照备份》 演讲人 : 冯  浩 网  名 :FH.CN|ISADBA Email : [email_address]   Blog:  www.mysqlops.com   | linuxguest.blog.51cto.com ChinaUnix 技术沙龙
什么是 HA ? HA  (High Availability) 所谓的 HA 就是高可用,度量高可用行使用平均无故障时间( MTTF ),可维护性使用平均维修时间( MTTR )来度量。计算计算机的可用性定义使用 MTTF/(MTTF+MTTR)*100% 公式来计算。 为了达到这一目的就需要对提供服务器的设备提供冗余,在主设备挂掉的时候,从设备能够顶上来,代替主设备,再失效的设备恢复以后,可以优先成为主设备提供服务或者成为现在主设备的从设备。 HA 有三种工作方式 主从方式 双机双工方式 集群工作方式
什么是 LB ? LB  (load balancing) 简单的理解为整合优化资源,将一个单元不能处理的压力尽量平均的分摊到多个单元上处理 五个目标 一致性 高效性 可用性 透明性 可伸缩性 根据 ISO7 层网络结构定义,负载均衡技术可以通过 2-7 层来实现, 2 层主要是网络设备的链路聚合技术,现在开源的负载均衡方案中,多以操作 4-7 层来达到负载均衡目的。 硬件 F5 、深信服、梭子鱼 等 软件 LVS 、 HAPROXY 、 Nginx 、 Varnish , DNS  等 商业产品 智能 DNS 、 CDN  等
mysql 常用 HA 和 LB 方案 常用的 Mysql 的 HA+LB 开源方案一般有以下几种 强调下 mysql 的架构特殊性,一般只有一个写入点, LB 主要通过读写分离实现 主主复制 主从复制 Mysql-proxy Mysql 集群套件 Mysql-mmm DRBD+heartbeat Lvs+keepalive Haproxy Amoeba 应用层软件自主开发( mysql_rw_php )
mysql-mmm 项目介绍 介绍: MMM(Master-Master replication manager for Mysql) 是一套灵活的脚本程序,使用 perl 语言开发。 功能: 用来监控和管理 mysql Master-Master 复制的配置  ( 同一时间只有一个节点是可写的 ) 做到故障切换的功能 。 附带的工具套件可以实现多个 slaves 的 read 负载均衡 ( 我至今还不知道附带的哪个工具有这个功能 ) ,不过我们可以通过其他的开源产品组合达到 LB 的功能。 你可以 让 mmm 自动的或者 使用 mmm 自带的 工具 手工的 移除一组服务器中复制延迟较高的服务器的虚拟 IP ,它还可以备份数据,两节点之间再同步等等。
mysql-mmm 有点和缺点 优点: 稳定和成熟的开源产品,经过了时间的考验 核心技术是 mysql 自己的技术,只是使用脚本程序来控制,所以在原理上比较容易理解,而且管理能够更智能化。 安装简单,配置简单,使用简单 功能强大 ( HA , failover , tools 套件, cluster 模式可以一个 monitor 管理多个 mmm 组) 缺点: 由于架构里只有一个写入点,所以扩展性是有限的,但是对一般中型企业够用了。 解决方案:对于大应用可以采取垂直拆分到多个 mmm 架构的方式,使用 mmm cluster 来管理。 对于读写分离和读负载均衡还是要程序来开发或者使用其他工具完成。 需要大量 perl 库支持,安装比较耗时。
mysql-mmm 架构 ( 一 ) 主主复制 MMM monitor Mysql Master A Mysql Master B 应用程序 real ip real ip virtual ip virtual ip
mysql-mmm 架构 ( 二 ) 主主复制 MMM monitor Mysql Master A Mysql Master B 应用程序 Mysql Slave C virtual ip virtual ip virtual ip real ip real ip
mysql-mmm 运行机制 MMM_MONITOR Listen:tcp9988 Mysql Master A Agent Mysql Master B Agent Mysql slave C Agent Listen:tcp9989 Listen:tcp9989 Listen:tcp9989 mmm_monitor 进程用监控的数据和读取配置文件中的信息,通过 tcp9988 和 9989 与客户端通信,完成各种对客户端的设置操作,比如虚拟 IP 的添加和删除…… mmm_monitor 进程读取配置文件中的信息连接到 agent 的 mysql 端口,检查 mysql 的的相关状态 。
mysql-mmm 安装规划 安装步骤规划 安装系统,完成 lvm 分区的规划 完成 IP 规划,完成数据库的编译和安装。 安装 mysql mmm 需要的 perl 模块 在数据库里面创建 mysql mmm 相关的用户和分配对应的权限 下载 mysql-mmm 安装 mysql-mmm 修改配置文件 启动 mysql-mmm 进程 测试 mysql-mmm 添加 slave 并测试
mysql-mmm 安装需求 ( 一 ) Server  n+1 N 台安装 mysql 的机器和 1 台安装 mmm monitor 的机器。 2*(n+1)Ips 每个主机一个固定 ip 、一个虚拟 IP(reader role), 全局一个 writer role IP Monitor User 一个可以在 mmm monitor 机器上使用的并且拥有 REPLICATION CLIENT 权限的 mysql 用户 Agent User 一个可以在 mmm agent 机器上使用的并且拥有 super , replication client , process 权限的 mysql 用户 Replication user 一个 slaves 主机上可以使用的并且有用 replication slave 权限的用户 Tools user 一个 mmm tools 主机可以使用的,并且有用 super , replication client , reload 权限的 mysql 用户
mysql-mmm 安装需求 ( 二 ) Mysql_mmm 是有 perl 编写的,所以肯定对 perl 的一些模块有依耐关系,下面我们来理一理 mmm 需要哪些 perl 模块 Monitor host 需要安装的 perl 模块: Fping( 如果你想要使用非 root 用户运行 mmm_mond 进程 ) Algorithm::Diff Class:Singleton DBI and DBD::mysql File::Basename File::stat File::Temp Log::Dispatch Log::Log4perl Mail::Send Net::Ping Proc::Daemon Thread::Queue Time::HiRes
mysql-mmm 安装需求 ( 三 ) nodes host 需要安装的 perl 库 Iproute Send_arp(solaris) Perl 模块如下: Fping( 如果你想要使用非 root 用户运行 mmm_mond 进程 ) Algorithm::Diff DBI and DBD::mysql File::Basename File::stat Log::Dispatch Log::Log4perl Mail::Send N et::ARP(linux) Proc::Daemon Time::HiRes
安装 perl 模块的方法 普通青年: #perl –MCPAN –e shell cpan>install  模块名 文艺青年: cd /usr/sbin/ wget http://xrl.us/cpanm --no-check-certificate chmod 755 cpanm #cpanm  模块名 技术青年: 当然你也可以通过 cpan 下载后,自己手工编译安装相关模块,只是比较麻烦一点 注意:安装 DBD::mysql 的前,如果是自己编译安装的 mysql ,需要在 /etc/ld.so.conf 文件中加上 mysql 库所在的位置,然后运行 ldconfig 命令。 Example : # cat /etc/ld.so.conf include ld.so.conf.d/*.conf /usr/local/mysql/lib/mysql/
完成 IP 规划 我们以两台 master 和一台 slave 的架构来演示 三台安装 mysql 的服务器 虚拟 IP 规划 主机名 IP 地址 角色 Mysql_server_id db1 192.168.199.128 masterA 1 db2 192.168.199.129 masterB 2 db3 192.168.199.130 slaveC 3 mmm 192.168.199.127 mmm_mon - IP 地址 角色 描述 192.168.199.200 writer 应用服务器连接此服务器 写入 数据 192.168.199.201 reader 应用服务器连接此服务器 读取 数据 192.168.199.202 reader 应用服务器连接此服务器 读取 数据 192.168.199.203 reader 应用服务器连接此服务器 读取 数据
mysql-mmm 下载安装 在数据库里面创建 mysql mmm 相关的用户和分配对应的权限 mysql> grant replication slave on *.* to 'slave'@'192.168.199.%' identified by 'slave'; mysql> grant replication client,process,super  on *.* to 'mmm_agent'@'192.168.199.%' identified by 'mmm_agent';  mysql> grant replication client  on *.* to 'mmm_monitor'@'192.168.199.%' identified by 'mmm_monitor';  mysql> grant replication client,reload,super  on *.* to 'mmm_tools'@'192.168.199.%' identified by 'mmm_tools';  下载 mysql-mmm http://mysql-mmm.org/_media/:mmm2:mysql-mmm-2.2.1.tar.gz 在 mysql-mmm 架构中的所有机器上安装 mysql-mmm 软件 # wget http://mysql-mmm.org/_media/:mmm2:mysql-mmm-2.2.1.tar.gz # mv :mmm2:mysql-mmm-2.2.1.tar.gz mysql-mmm-2.2.1.tar.gz # tar -zxvf mysql-mmm-2.2.1.tar.gz # cd mysql-mmm-2.2.1 # make install
mysql-mmm 安装后文件一览 文件目录 描述 /usr/lib/perl5/vendor_perl/5.8.8/MMM MMM 使用的 perl 模块 /usr/lib/mysql-mmm MMM 的脚本插件 /usr/sbin  MMM 的命令保存路径 /var/log/mysql-mmm  MMM 的日志保存路径 /etc  MMM 配置文件保存的路径 /etc/mysql-mmm  MMM 配置文件保存的路径,优先级最高 /etc/init.d/ agentd 和 monitor 的启动关闭脚本
mysql-mmm 配置文件介绍 mysql-mmm 有以下几个配置文件 mmm_agent.conf mmm_agent 进程调用,作用是确定当前的节点名字 mmm_common.conf monitor 和 agent 都会调用,大部分配置内容都在这里面 mmm_mon.conf mmm_mon 进程调用, monitor 相关的配置 mmm_tools.conf mmm_tools 调用的配置文件,如果要使用 mmm_tools 工具就需要配置此文件
mmm_common.conf( 一 ) 默认的主机定义部分 active_master_role  writer <host default> cluster_interface  eth0 pid_path  /var/run/mmm_agentd.pid bin_path  /usr/lib/mysql-mmm/ replication_user  slave replication_password  slave agent_user  mmm_agent agent_password  mmm_agent mysql_port  9188 </host>
mmm_common.conf( 二 ) 主机配置部分 <host db1> ip  192.168.199.128 mode  master peer  db2 </host> <host db2> ip  192.168.199.129 mode  master peer  db1 </host> <host db3> ip  192.168.199.130 mode  slave </host>
mmm_common.conf( 三 ) 角色配置部分 <role writer> hosts  db1, db2 ips  192.168.199.200 mode  exclusive prefer  db1 </role> <role reader> hosts  db1, db2,db3 ips  192.168.199.201,192.168.199.202,192.168.199.203 mode  balanced </role>
mmm_agent.conf 此配置文件在启动 mmm_agent 进程的机器上配置,由于每个服务器上的 mmm_common.conf 都一样,这个服务器紧紧需要指定当前节点的 host 名字,需要和 common.conf 中主机配置中的内容想对应。 include mmm_common.conf this db1
mmm_mon.conf 此文件只需要在 mmm_mon 进程的机器上配置 include mmm_common.conf <monitor> ip  192.168.199.127 pid_path  /var/run/mmm_mond.pid bin_path  /usr/lib/mysql-mmm/ status_path  /var/lib/misc/mmm_mond.status ping_ips  192.168.199.128,192.168.199.129,192.168.199.130 auto_set_online  10 </monitor> <host default> monitor_user  mmm_monitor monitor_password  mmm_monitor </host> debug 0
mysql-mmm 启动 启动 monitor # /etc/init.d/mysql-mmm-monitor start Daemon bin: '/usr/sbin/mmm_mond' Daemon pid: '/var/run/mmm_mond.pid' Starting MMM Monitor daemon: Ok 启动 agent # /etc/init.d/mysql-mmm-agent start Daemon bin: '/usr/sbin/mmm_agentd' Daemon pid: '/var/run/mmm_agentd.pid' Starting MMM Agent daemon... Ok 可以使用 /etc/init.d/mysql-mmm-monitor –help 查看使用方法, agent 也可以。 使用 ps aux | grep mmm  或者  netstat –tulnp | grep mmm  查看进程是否启动成功
mysql-mmm 管理工具 # mmm_control help Valid commands are: help  - show this message ping  - ping monitor show  - show status checks [<host>|all [<check>|all]] - show checks status set_online <host>  - set host <host> online set_offline <host>  - set host <host> offline mode  - print current mode. set_active  - switch into active mode. set_manual  - switch into manual mode. set_passive  - switch into passive mode. move_role [--force] <role> <host> - move exclusive role <role> to host <host> (Only use --force if you know what you are doing!) set_ip <ip> <host>  - set role with ip <ip> to host <host>
mysql-mmm 运行状态分析 # mmm_control show  // 查看当前虚拟 IP 的分布状况   db1(192.168.199.128) master/ONLINE. Roles: reader(192.168.199.201), writer(192.168.199.200)   db2(192.168.199.129) master/ONLINE. Roles: reader(192.168.199.203)   db3(192.168.199.130) slave/ONLINE. Roles: reader(192.168.199.202) # mmm_control checks all  // 对所有节点进行所有检查 db2  ping  [last change: 2011/12/07 19:03:05]  OK db2  mysql  [last change: 2011/12/07 19:03:05]  OK db2  rep_threads  [last change: 2011/12/07 19:03:05]  OK db2  rep_backlog  [last change: 2011/12/07 19:03:05]  OK: Backlog is null db3  ping  [last change: 2011/12/07 18:17:41]  OK db3  mysql  [last change: 2011/12/07 18:58:28]  OK db3  rep_threads  [last change: 2011/12/07 19:16:29]  OK db3  rep_backlog  [last change: 2011/12/07 18:17:41]  OK: Backlog is null db1  ping  [last change: 2011/12/07 16:40:10]  OK db1  mysql  [last change: 2011/12/07 16:40:10]  OK db1  rep_threads  [last change: 2011/12/07 16:40:10]  OK db1  rep_backlog  [last change: 2011/12/07 16:40:10]  OK: Backlog is null # mmm_control  mode // 查看 mmm 当前运行的模式 ACTIVE
mysql-mmm 故障处理机制 MMM_MONITOR Listen:tcp9988 Mysql Master A Agent Mysql Master B Agent Mysql slave C Agent Listen:tcp9989 Listen:tcp9989 Listen:tcp9989 monitor 检查 agent 的以下几个状态 1 、 agent 进程 2 、 ping 3 、 mysql 4 、 rep_threads 、 5 、 rep_backlog ping 检查默认是 1s ,通过 ping_interval 配置 mysql 相关的检查默认是 5s ,通过 check_period 配置, trap_period 表示一个节点检测不成功持续的时间,默认为 10 秒,如果超过这个时间就认为这个节点失败了。 如果活动的 master 检测到失败,那么 writer role 将从原来的主机上移除。 active master : 1 、 mysql 设置为 read_only 模式 2 、删除活动的连接 3 、删除虚拟 IP slave : 1 、完成原来主机上的复制工作 2 、切换 master 到新的主机上 new active master : 1 、 mysql 设置为可写模式 2 、配置虚拟 ip
mysql-mmm 故障模拟 ( 一 ) 备份 master 故障演示 通过 iptables 来模拟 mysql 故障 on db2 : # iptables -A INPUT -p tcp --dport 9188 -j DROP && date 大概 15 秒 mmm 完成了故障切换 # mmm_control show db1(192.168.199.128) master/ONLINE. Roles: reader(192.168.199.201), writer(192.168.199.200) db2(192.168.199.129) master/HARD_OFFLINE. Roles:  db3(192.168.199.130) slave/ONLINE. Roles: reader(192.168.199.202), reader(192.168.199.203) #mmm_control checks all db2  ping  [last change: 2011/12/07 23:32:12]  OK db2  mysql  [last change: 2011/12/07 23:36:06]  ERROR: Connect error (host = 192.168.199.129:9188, user = mmm_monitor)! Can't connect to MySQL server on '192.168.199.129' (4) 故障修复后,大概 5 秒完成了 恢复。
mysql-mmm 故障模拟 ( 二 ) 活动的 master 故障演示 on  db1 # iptables -A INPUT -p tcp --dport 9188 -j DROP && date 大概 15 秒 mmm 完成了故障切换 # mmm_control show db1(192.168.199.128) master/HARD_OFFLINE. Roles:  db2(192.168.199.129) master/ONLINE. Roles: reader(192.168.199.202), writer(192.168.199.200) db3(192.168.199.130) slave/ONLINE. Roles: reader(192.168.199.201), reader(192.168.199.203) # mmm_control checks all db1  mysql  [last change: 2011/12/07 23:48:39]  ERROR: Connect error (host = 192.168.199.128:9188, user = mmm_monitor)! Can't connect to MySQL server on '192.168.199.128' (4) db1  rep_threads  [last change: 2011/12/07 23:35:05]  OK db1  rep_backlog  [last change: 2011/12/07 23:32:12]  OK: Backlog is null 故障切换完成以后,检查 DB3 slave 的复制情况,发现已经自动调整到 masterB 了。 故障修复后,大概 5 秒完成了恢复。
基于 mysql-mmm 的 LB 实现 之前已经介绍了什么是 LB 和 mysql LB 的实现方式。 下面我以 php 代码为例,完成的实现基于 mysql-mmm 的读写分离和读负载均衡。 该代码是否 mysql_rw_php 项目修改而来 require_once('mysql_rw_php.class.php'); $ro_host=array(“192.168.199.201:9188”,“ 192.168.199.202:9188 ” ,“ 192.168.199.203:9188 ” ); $a=array_rand($ro_host,1); //rw info $db_rw = array( 'dbhost'=>‘192.168.199.200:9188', 'dbuser'=>'andy', 'dbpw'=>'andy', 'dbname'=>'test‘ ); $db_ro = array( 'dbhost'=>$ro_host[$a], 'dbuser'=>'andy', 'dbpw'=>'andy‘ );
mmm-tools 介绍 mmm_tools 是 mysql-mmm 软件附带的一个工具箱,自带三个工具 mmm_clone 用来克隆一个 mysql 数据库到另外的机器,并且自动完成 master-master 或者 master-slave 的环境搭建,很好用。 ( 前面我们的架构只搭建了 master-master 的架构,我们将用 mmm_clone 完成 master-master-slave 的架构 ) mmm_backup 用来备份一个 mysql 数据库,备份的时候使用了 lvm 快照技术,所以支持热备,并且锁表的时间相当的短 , 支持三种拷贝的方法, scp , ssh-gz , rdiff ,下面会详细介绍。 mmm_restore 还原数据到一个 mysql 数据库,并完成 master-master 或者 master-slave 的环境搭建,不过还原还是建议手动操作,除非你对此工具很熟悉,能够熟练使用,这样才能降低操作带来的风险
mmm_tools 预备知识 mysql-mmm 中文手册: http://linuxguest.blog.51cto.com/195664/578311 mysql-mmm 安装手册: http://linuxguest.blog.51cto.com/195664/578307 lvm 快照技术: http://asram.blog.51cto.com/1442164/313073 使用 lvm 快照备份 mysql : http://linuxguest.blog.51cto.com/195664/585036 如果你对以上知识没有了解的话,请先阅读以上资料,并预先搭建好 mysql-mmm 架构,应为 mmm_tools 是依赖 mysql-mmm 架构工作的。
mmm-tools 环境需求 搭建好 mysql-mmm 环境, 安装 mmm-tools 需要的 perl 插件和创建 tools 的 mysql 用户 Path::Class Data::Dumper 安装好 mysql 数据库,所有服务器尽量使用相同的 mysql 版本 mysql 数据库软件放在 lvm 的逻辑卷上面(备份需要 lvm 快照功能),并且存放 mysql 数据库的逻辑卷组除了 mysql 数据库使用的空间外,还要剩余 1-10G 的空间用于创建快照,快照空间大小根据你数据库的大小和备份时会改变的数据量大小来定,宁多勿少。 安装 rdiff-backup , rdiff-backup 是支持增量备份的一种软件。在 mysql-backup rdiff 拷贝方法中会用到。 参考: http://wiki.rdiff-backup.org/wiki/index.php/Installations
mmm_tools.conf( 一 ) 更详细的配置参见我提供的《 mmm-tools 配置手册》 工具全局的配置和主机的默认配置 include mmm_agent.conf default_copy_method  scp clone_dirs  data <host default> ssh_user  root lvm_snapshot_size  1G lvm_logical_volume  lvmdb lvm_volume_group  myvg lvm_mount_dir  /mmm_snapshot  // 需要自己创建 lvm_mount_opts  -o rw tools_user  mmm_tools tools_password  mmm_tools backup_dir  /mmm_backup  // 需要自己创建 restore_dir  /mysql  // 需要自己创建 </host>
mmm_tools.conf( 二 ) <copy_method scp> // 三种备份方法相关的配置 backup_command scp -c blowfish -r %SSH_USER%@%IP%:%SNAPSHOT%/%CLONE_DIR% %DEST_DIR%/ restore_command cp -axv %BACKUP_DIR%/* %DEST_DIR%/ true_copy 1 </copy_method> <copy_method rdiff> backup_command rdiff-backup --ssh-no-compression -v 5 !--include %SNAPSHOT%/%CLONE_DIR%! --exclude %SNAPSHOT% %SSH_USER%@%IP%::%SNAPSHOT%/ %DEST_DIR%/ restore_command rdiff-backup --force -v 5 -r %VERSION% %BACKUP_DIR% %DEST_DIR%/.mmm_restore; cp -axvl --remove-destination %DEST_DIR%/.mmm_restore/*  %DEST_DIR%/; rm -r %DEST_DIR%/.mmm_restore/ incremental_command rdiff-backup --parsable-output -l %BACKUP_DIR% single_run 1 incremental 1 </copy_method> <copy_method ssh-gz> backup_command ssh -c blowfish %SSH_USER%@%IP% &quot;cd '%SNAPSHOT%'; tar cv !'%CLONE_DIR%'!&quot; | gzip > %DEST_DIR%/backup.tar.gz restore_command cd %DEST_DIR%; tar xzfv %BACKUP_DIR%/backup.tar.gz single_run 1 </copy_method>
mmm_clone 介绍及演示 ( 一 ) 用法 : Usage: /usr/sbin/mmm_clone [--config <config file>] --host <host> --clone-mode <mode> [--copy-method <copy method>] [--dest-dir <dir>] Where: host  : db1 | db2 clone-mode : master-master | master-slave | slave-slave copy-method: scp (default: ssh-gz) dest-dir  : directory where data should be cloned to 需求:将 db1 的数据克隆到 db2 ,并搭建 master-master 的复制架构 准备工作 : 1 、 mysql-mmm 已经安装好, mmm 相关的配置文件已经完成 。 2 、 my.cnf 已经配置好(具体配置和注意事项请参照 《 mysql-mmm 安装手册 》 )。 3 、将要使用的数据导入到 db1 完成以上任务后,启动 db1 。把 db2 的数据库关闭
mmm_clone 介绍及演示 ( 二 ) 现在我们使用 mmm_clone 完成 db1 到 db2 的数据同步,并且完成 master-master 架构的搭建。 在 db2 上运行下面命令 : #mmm_clone --host db1  --copy-method scp  --clone-mode master-master --dest-dir /usr/local/mysql/ INFO: Checking destination directory '/usr/local/mysql/'... INFO: Directory is ok Source host  : db1 Destination dir  : /usr/local/mysql/ Dirs to clone  : var Clone mode  : master-master Copy method  : scp Replication peer  : db1 Setup master-master replication: yes Dry run  : no WARN: MySQL is not running now, skipping shutdown ... INFO: Verifying ssh connection to remote host 'root@192.168.199.128' (command: ssh  -p 22 root@192.168.199.128 date)... root@192.168.199.128's password:
mmm_clone 介绍及演示 ( 三 ) File descriptor 4 (socket:[1661904]) leaked on lvcreate invocation. Parent PID 1141: perl Logical volume &quot;mmm_snapshot&quot; created OK: Snapshot created! INFO: Copying 'var' from snapshot on host 'db1' with copy method 'scp' INFO: Executing command scp -P22 -c blowfish -r  root@192.168.199.128:/mmm_snapshot/var /usr/local/mysql// 拷贝文件到 db2 INFO: Copied directory var! INFO: Copying '_mmm' from snapshot on host 'db1' with copy method 'scp' INFO: Executing command scp -P22 -c blowfish -r root@192.168.199.128:/mmm_snapshot/_mmm /usr/local/mysql// root@192.168.199.128's password:  status.txt  100% 2454  2.4KB/s  00:00  my.cnf  100% 5570  5.4KB/s  00:00  INFO: Copied directory _mmm! INFO: ssh  -p 22 root@192.168.199.128 /usr/lib/mysql-mmm//tools/remove_snapshot root@192.168.199.128's password:  Logical volume &quot;mmm_snapshot&quot; successfully removed OK: Snapshot removed! INFO: Cleaning dump from master.info and binary logs... INFO: Deleting master binary logs: mysql-bin.* 已删除“ /usr/local/mysql/var/mysql-bin.index” 已删除“ /usr/local/mysql/var/mysql-bin.000002” 已删除“ /usr/local/mysql/var/mysql-bin.000003” 已删除“ /usr/local/mysql/var/mysql-bin.000001” INFO: Deleting relay binary logs: andy-relay-bin.* 已删除“ /usr/local/mysql/var/andy-relay-bin.000008” 已删除“ /usr/local/mysql/var/andy-relay-bin.000007” 已删除“ /usr/local/mysql/var/andy-relay-bin.index” INFO: Deleting .info and .pid  files... 已删除“ /usr/local/mysql/var/master.info” 已删除“ /usr/local/mysql/var/relay-log.info” 已删除“ /usr/local/mysql/var/andy.example.com.pid” INFO: Changing permissions on mysql data dir... INFO: MySQL is not running. Going to start it... Starting MySQL......................  [ 确定 ] INFO: MySQL has been started! INFO: Changing master of host db2 to 192.168.199.128 ... INFO: Successfully changed master. INFO: Changing master of host db1 to 192.168.199.129 ... INFO: Successfully changed master. INFO: Clone operation finished!
mmm_clone 介绍及演示 ( 三 ) [root@andy var]# mmm_control show db1(192.168.199.128) master/AWAITING_RECOVERY. Roles:  db2(192.168.199.129) master/ONLINE. Roles: reader(192.168.199.201), reader(192.168.199.202), writer(192.168.199.200) [root@andy var]# mmm_control set_online db1 OK: State of 'db1' changed to ONLINE. Now you can wait some time and check its new roles! [root@andy var]# mmm_control show db1(192.168.199.128) master/ONLINE. Roles: reader(192.168.199.202) db2(192.168.199.129) master/ONLINE. Roles: reader(192.168.199.201), writer(192.168.199.200) [root@andy var]# mmm_control checks all db2  ping  [last change: 2011/07/03 02:10:35]  OK db2  mysql  [last change: 2011/07/09 21:48:05]  OK db2  rep_threads  [last change: 2011/07/09 22:01:22]  OK db2  rep_backlog  [last change: 2011/07/09 22:01:22]  OK: Backlog is null db1  ping  [last change: 2011/07/02 18:27:51]  OK db1  mysql  [last change: 2011/07/09 22:01:22]  OK db1  rep_threads  [last change: 2011/07/09 22:01:22]  OK db1  rep_backlog  [last change: 2011/07/02 18:27:51]  OK: Backlog is null 当然,你还可以登陆到每台机器,使用   show slave status\G 来详细检查。呵呵,是不是很爽呢。
mmm_backup 介绍 基于上面搭建的环境,我们来演示三种 copy 方法。 用法: Usage: /usr/sbin/mmm_backup [--config <config file>] --host <host> [--copy-method <copy method>] [--dest-dir <dir>] Where: host  : db1 | db2 copy-method: rdiff | scp | ssh-gz (default: ssh-gz) dest-dir  : directory where data should be backed up to
mmm_backup 的 scp 方法 ( 一 ) 使用 scp 方法把 db1 的数据备份到本地的 /mmm_backup 中。 [root@andy ~]# mmm_backup --host db1 --copy-method scp --dest-dir /mmm_backup/ File descriptor 4 (socket:[1785871]) leaked on lvcreate invocation. Parent PID 16900: perl Logical volume &quot;mmm_snapshot&quot; created OK: Snapshot created! INFO: Copying 'var' from snapshot on host 'db1' with copy method 'scp' INFO: Executing command scp -P22 -c blowfish -r  root@192.168.199.128:/mmm_snapshot/var /mmm_backup// 拷贝文件  INFO: Copied directory var! INFO: Copying '_mmm' from snapshot on host 'db1' with copy method 'scp' INFO: Executing command scp -P22 -c blowfish -r root@192.168.199.128:/mmm_snapshot/_mmm /mmm_backup// status.txt  100% 2345  2.3KB/s  00:00  my.cnf  100% 5570  5.4KB/s  00:00  INFO: Copied directory _mmm! INFO: ssh  -p 22 root@192.168.199.128 /usr/lib/mysql-mmm//tools/remove_snapshot Logical volume &quot;mmm_snapshot&quot; successfully removed OK: Snapshot removed!
mmm_backup 的 scp 方法 ( 二 ) 备份的结果 备份完成后,  --dest-dir 里有两个目录 _mmm 和 var 。 _mmm :主要保存三个文件 Copy_method.txt 备份使用的拷贝方法 My.cnf  备份的 my.cnf Status.txt  包含备份的节点名字,备份时的 master 状态和 slave 状态 var : 保存了备份数据库 /var 目录下的所有文件,包括数据文件, bin-log , relay-log ,等
mmm_backup 的 ssh-gz 方法 B 、 使用 ssh-gz 方法把 db1 的数据备份到本地的 /mmm_backup 中。 注意,此时 /mmm_backup 中已经存在一个备份了,所以在备份到这个目录会不成功,我们可以重新指定一个目录,或者将此目录中备份删掉。 db1 : # cd /mmm_backup/ [root@andy mmm_backup]# ls _mmm  var [root@andy mmm_backup]# rm -rf * [root@andy mmm_backup]# mmm_backup --host db1 --copy-method ssh-gz --dest-dir /mmm_backup/ 备份的结果有一个 _mmm 目录和一个 backup.tar.gz 文件。 _mmm 目录和 scp 方法备份出来的一样 Backup.tar.gz 就是 var 使用 gzip 压缩以后的文件,可以大大节约存储空间 推荐使用这种方法备份
mmm_backup 的 rdiff 方法 C 、 使用 rdiff 方法把 db2 的数据备份到本地的 /mmm_backup 中。 使用词拷贝方法,记得要先安装 rdiff-backup 工具。 db1 : [root@andy mmm_backup]# mmm_backup --host db2 --copy-method rdiff --dest-dir /mmm_backup/
mmm_restore 介绍 还原也分三种拷贝模式, scp 和 ssh-gz 差不多, rdiff 属于增量备份,可以选择还原的版本号。这里我们就只演示 scp 和 rdiff 两种还原。 用法: Usage: /usr/sbin/mmm_restore [--config <config file>] [--mode <mode>] [--version <version | list>] [--src-dir <dir>] [--dest-dir <dir>] [--dry-run] Where: src-dir : directory where backup resides dest-dir: directory where backup should be restored to mode  : data-only, single-single, slave-single, master-single, master-slave, slave-slave version :  when run with 'list' parameter, displays available versions of incremental backups if version is specified, tries to restore backup for specified version dry-run : check everything and exit without any changes 从上面可以看出, mmm_restore 使用的 — src-dir 和 — dest-dir ,而不是 — host 。
mmm_restore 的 scp 和 ssh-gz 方法 使用 scp 拷贝模式还原数据库 现在我们模仿 db1 数据库文件丢失,需要还原数据的场景。首先手工删除 test 数据文件。 [root@andy var]# cd /usr/local/mysql/var/ && rm -rf test/ [root@andy var]# ls andy.example.com.pid  andy-relay-bin.000002  master.info  mysql-bin.000001  relay-log.info andy-relay-bin.000001  andy-relay-bin.index  mysql  mysql-bin.index 还原数据: [root@andy var]# mmm_restore  INFO: Checking restore source directory '/mmm_backup'... 这里并没有演示完整还原,因为还原或导致 master-master 复制失败,还原完成, db1 已经自动把 master 转向 db2 ,但是 db2 对 db1 的复制失败了,应为 db1 的 bin-log 发生了变化,需要手工恢复 master-master 复制。 如果真实情况 master 数据丢失需要还原的话,就需要先 resote 到 master ,然后再 mmm_clone 生成复制架构。如果只是 slave 损坏,没必要还原,直接 mmm_clone 过来就可以了
mmm_restore 的 rdiff 方法 还原 rdiff 的备份 [root@andy ~]# mmm_restore  --mode master-slave --version list --src-dir /mmm_backup/ --dest-dir /usr/local/mysql/ --dry-run  INFO: Checking restore source directory '/mmm_backup/'... INFO: Directory is ok Following backup versions are available: Version  |  Date 1310222305 | Sat Jul  9 22:38:25 2011 1310222616 | Sat Jul  9 22:43:36 2011 [root@andy ~]# mmm_restore  --mode master-slave --version 1310222616 --src-dir /mmm_backup/ --dest-dir /usr/local/mysql/ --dry-run  --version // 选择 version 编号或者使用 — list 显示可用的编号。 --dry-run // 测试是否可以运行,不真正运行。 使用还原前关掉 mysql 数据库,貌似 mmm_tools 存在一个 bug ,关于还原前和 clone 前关闭数据库的命令。 [root@andy var]# mmm_restore  --mode master-slave --version 1310222616 --src-dir /mmm_backup/ --dest-dir /usr/local/mysql/  还原完成, db1 已经自动把 master 转向 db2 ,但是 db2 对 db1 的复制失败了,应为 db1 的 bin-log 发生了变化,这个只有手工处理。
mmm 故障总结 mysql-mmm 出现故障的最大可能就是你的 perl 模块没有安装齐全,导致 mysql-mmm 不能够预期工作 定期优化检查 myisam 表,定期使用 mk-table-checksum 检查主从的一致性 mmm-tools 存在以下几个注意 如果当命令执行到一半而由于配置错误退出时,快照已经生成,但是命令未执行完,导致快照没有删除,需要自己使用 lvremove –f  快照名 删除快照。 注意 mmm_tools.cnf 要针对所在主机环境配置,不是所有都一样,特别注意 server-id 和自动增长列。 生产环境下,备份好以后,需要转移做测试,看备份是否可以用。还原最好手工操作,避免误伤。 最后:上线前各种故障模拟测试,故障后日志是解决问题的关键。
Mysql mmm演讲-冯浩

Mysql mmm演讲-冯浩

  • 1.
    《 Mysql-mmm 实现HA 》 《瞬间表锁 mmm-tools 实现快照备份》 演讲人 : 冯 浩 网 名 :FH.CN|ISADBA Email : [email_address] Blog: www.mysqlops.com | linuxguest.blog.51cto.com ChinaUnix 技术沙龙
  • 3.
    什么是 HA ?HA (High Availability) 所谓的 HA 就是高可用,度量高可用行使用平均无故障时间( MTTF ),可维护性使用平均维修时间( MTTR )来度量。计算计算机的可用性定义使用 MTTF/(MTTF+MTTR)*100% 公式来计算。 为了达到这一目的就需要对提供服务器的设备提供冗余,在主设备挂掉的时候,从设备能够顶上来,代替主设备,再失效的设备恢复以后,可以优先成为主设备提供服务或者成为现在主设备的从设备。 HA 有三种工作方式 主从方式 双机双工方式 集群工作方式
  • 4.
    什么是 LB ?LB (load balancing) 简单的理解为整合优化资源,将一个单元不能处理的压力尽量平均的分摊到多个单元上处理 五个目标 一致性 高效性 可用性 透明性 可伸缩性 根据 ISO7 层网络结构定义,负载均衡技术可以通过 2-7 层来实现, 2 层主要是网络设备的链路聚合技术,现在开源的负载均衡方案中,多以操作 4-7 层来达到负载均衡目的。 硬件 F5 、深信服、梭子鱼 等 软件 LVS 、 HAPROXY 、 Nginx 、 Varnish , DNS 等 商业产品 智能 DNS 、 CDN 等
  • 5.
    mysql 常用 HA和 LB 方案 常用的 Mysql 的 HA+LB 开源方案一般有以下几种 强调下 mysql 的架构特殊性,一般只有一个写入点, LB 主要通过读写分离实现 主主复制 主从复制 Mysql-proxy Mysql 集群套件 Mysql-mmm DRBD+heartbeat Lvs+keepalive Haproxy Amoeba 应用层软件自主开发( mysql_rw_php )
  • 6.
    mysql-mmm 项目介绍 介绍:MMM(Master-Master replication manager for Mysql) 是一套灵活的脚本程序,使用 perl 语言开发。 功能: 用来监控和管理 mysql Master-Master 复制的配置 ( 同一时间只有一个节点是可写的 ) 做到故障切换的功能 。 附带的工具套件可以实现多个 slaves 的 read 负载均衡 ( 我至今还不知道附带的哪个工具有这个功能 ) ,不过我们可以通过其他的开源产品组合达到 LB 的功能。 你可以 让 mmm 自动的或者 使用 mmm 自带的 工具 手工的 移除一组服务器中复制延迟较高的服务器的虚拟 IP ,它还可以备份数据,两节点之间再同步等等。
  • 7.
    mysql-mmm 有点和缺点 优点:稳定和成熟的开源产品,经过了时间的考验 核心技术是 mysql 自己的技术,只是使用脚本程序来控制,所以在原理上比较容易理解,而且管理能够更智能化。 安装简单,配置简单,使用简单 功能强大 ( HA , failover , tools 套件, cluster 模式可以一个 monitor 管理多个 mmm 组) 缺点: 由于架构里只有一个写入点,所以扩展性是有限的,但是对一般中型企业够用了。 解决方案:对于大应用可以采取垂直拆分到多个 mmm 架构的方式,使用 mmm cluster 来管理。 对于读写分离和读负载均衡还是要程序来开发或者使用其他工具完成。 需要大量 perl 库支持,安装比较耗时。
  • 8.
    mysql-mmm 架构 (一 ) 主主复制 MMM monitor Mysql Master A Mysql Master B 应用程序 real ip real ip virtual ip virtual ip
  • 9.
    mysql-mmm 架构 (二 ) 主主复制 MMM monitor Mysql Master A Mysql Master B 应用程序 Mysql Slave C virtual ip virtual ip virtual ip real ip real ip
  • 10.
    mysql-mmm 运行机制 MMM_MONITORListen:tcp9988 Mysql Master A Agent Mysql Master B Agent Mysql slave C Agent Listen:tcp9989 Listen:tcp9989 Listen:tcp9989 mmm_monitor 进程用监控的数据和读取配置文件中的信息,通过 tcp9988 和 9989 与客户端通信,完成各种对客户端的设置操作,比如虚拟 IP 的添加和删除…… mmm_monitor 进程读取配置文件中的信息连接到 agent 的 mysql 端口,检查 mysql 的的相关状态 。
  • 11.
    mysql-mmm 安装规划 安装步骤规划安装系统,完成 lvm 分区的规划 完成 IP 规划,完成数据库的编译和安装。 安装 mysql mmm 需要的 perl 模块 在数据库里面创建 mysql mmm 相关的用户和分配对应的权限 下载 mysql-mmm 安装 mysql-mmm 修改配置文件 启动 mysql-mmm 进程 测试 mysql-mmm 添加 slave 并测试
  • 12.
    mysql-mmm 安装需求 (一 ) Server n+1 N 台安装 mysql 的机器和 1 台安装 mmm monitor 的机器。 2*(n+1)Ips 每个主机一个固定 ip 、一个虚拟 IP(reader role), 全局一个 writer role IP Monitor User 一个可以在 mmm monitor 机器上使用的并且拥有 REPLICATION CLIENT 权限的 mysql 用户 Agent User 一个可以在 mmm agent 机器上使用的并且拥有 super , replication client , process 权限的 mysql 用户 Replication user 一个 slaves 主机上可以使用的并且有用 replication slave 权限的用户 Tools user 一个 mmm tools 主机可以使用的,并且有用 super , replication client , reload 权限的 mysql 用户
  • 13.
    mysql-mmm 安装需求 (二 ) Mysql_mmm 是有 perl 编写的,所以肯定对 perl 的一些模块有依耐关系,下面我们来理一理 mmm 需要哪些 perl 模块 Monitor host 需要安装的 perl 模块: Fping( 如果你想要使用非 root 用户运行 mmm_mond 进程 ) Algorithm::Diff Class:Singleton DBI and DBD::mysql File::Basename File::stat File::Temp Log::Dispatch Log::Log4perl Mail::Send Net::Ping Proc::Daemon Thread::Queue Time::HiRes
  • 14.
    mysql-mmm 安装需求 (三 ) nodes host 需要安装的 perl 库 Iproute Send_arp(solaris) Perl 模块如下: Fping( 如果你想要使用非 root 用户运行 mmm_mond 进程 ) Algorithm::Diff DBI and DBD::mysql File::Basename File::stat Log::Dispatch Log::Log4perl Mail::Send N et::ARP(linux) Proc::Daemon Time::HiRes
  • 15.
    安装 perl 模块的方法普通青年: #perl –MCPAN –e shell cpan>install 模块名 文艺青年: cd /usr/sbin/ wget http://xrl.us/cpanm --no-check-certificate chmod 755 cpanm #cpanm 模块名 技术青年: 当然你也可以通过 cpan 下载后,自己手工编译安装相关模块,只是比较麻烦一点 注意:安装 DBD::mysql 的前,如果是自己编译安装的 mysql ,需要在 /etc/ld.so.conf 文件中加上 mysql 库所在的位置,然后运行 ldconfig 命令。 Example : # cat /etc/ld.so.conf include ld.so.conf.d/*.conf /usr/local/mysql/lib/mysql/
  • 16.
    完成 IP 规划我们以两台 master 和一台 slave 的架构来演示 三台安装 mysql 的服务器 虚拟 IP 规划 主机名 IP 地址 角色 Mysql_server_id db1 192.168.199.128 masterA 1 db2 192.168.199.129 masterB 2 db3 192.168.199.130 slaveC 3 mmm 192.168.199.127 mmm_mon - IP 地址 角色 描述 192.168.199.200 writer 应用服务器连接此服务器 写入 数据 192.168.199.201 reader 应用服务器连接此服务器 读取 数据 192.168.199.202 reader 应用服务器连接此服务器 读取 数据 192.168.199.203 reader 应用服务器连接此服务器 读取 数据
  • 17.
    mysql-mmm 下载安装 在数据库里面创建mysql mmm 相关的用户和分配对应的权限 mysql> grant replication slave on *.* to 'slave'@'192.168.199.%' identified by 'slave'; mysql> grant replication client,process,super on *.* to 'mmm_agent'@'192.168.199.%' identified by 'mmm_agent'; mysql> grant replication client on *.* to 'mmm_monitor'@'192.168.199.%' identified by 'mmm_monitor'; mysql> grant replication client,reload,super on *.* to 'mmm_tools'@'192.168.199.%' identified by 'mmm_tools'; 下载 mysql-mmm http://mysql-mmm.org/_media/:mmm2:mysql-mmm-2.2.1.tar.gz 在 mysql-mmm 架构中的所有机器上安装 mysql-mmm 软件 # wget http://mysql-mmm.org/_media/:mmm2:mysql-mmm-2.2.1.tar.gz # mv :mmm2:mysql-mmm-2.2.1.tar.gz mysql-mmm-2.2.1.tar.gz # tar -zxvf mysql-mmm-2.2.1.tar.gz # cd mysql-mmm-2.2.1 # make install
  • 18.
    mysql-mmm 安装后文件一览 文件目录描述 /usr/lib/perl5/vendor_perl/5.8.8/MMM MMM 使用的 perl 模块 /usr/lib/mysql-mmm MMM 的脚本插件 /usr/sbin MMM 的命令保存路径 /var/log/mysql-mmm MMM 的日志保存路径 /etc MMM 配置文件保存的路径 /etc/mysql-mmm MMM 配置文件保存的路径,优先级最高 /etc/init.d/ agentd 和 monitor 的启动关闭脚本
  • 19.
    mysql-mmm 配置文件介绍 mysql-mmm有以下几个配置文件 mmm_agent.conf mmm_agent 进程调用,作用是确定当前的节点名字 mmm_common.conf monitor 和 agent 都会调用,大部分配置内容都在这里面 mmm_mon.conf mmm_mon 进程调用, monitor 相关的配置 mmm_tools.conf mmm_tools 调用的配置文件,如果要使用 mmm_tools 工具就需要配置此文件
  • 20.
    mmm_common.conf( 一 )默认的主机定义部分 active_master_role writer <host default> cluster_interface eth0 pid_path /var/run/mmm_agentd.pid bin_path /usr/lib/mysql-mmm/ replication_user slave replication_password slave agent_user mmm_agent agent_password mmm_agent mysql_port 9188 </host>
  • 21.
    mmm_common.conf( 二 )主机配置部分 <host db1> ip 192.168.199.128 mode master peer db2 </host> <host db2> ip 192.168.199.129 mode master peer db1 </host> <host db3> ip 192.168.199.130 mode slave </host>
  • 22.
    mmm_common.conf( 三 )角色配置部分 <role writer> hosts db1, db2 ips 192.168.199.200 mode exclusive prefer db1 </role> <role reader> hosts db1, db2,db3 ips 192.168.199.201,192.168.199.202,192.168.199.203 mode balanced </role>
  • 23.
    mmm_agent.conf 此配置文件在启动 mmm_agent进程的机器上配置,由于每个服务器上的 mmm_common.conf 都一样,这个服务器紧紧需要指定当前节点的 host 名字,需要和 common.conf 中主机配置中的内容想对应。 include mmm_common.conf this db1
  • 24.
    mmm_mon.conf 此文件只需要在 mmm_mon进程的机器上配置 include mmm_common.conf <monitor> ip 192.168.199.127 pid_path /var/run/mmm_mond.pid bin_path /usr/lib/mysql-mmm/ status_path /var/lib/misc/mmm_mond.status ping_ips 192.168.199.128,192.168.199.129,192.168.199.130 auto_set_online 10 </monitor> <host default> monitor_user mmm_monitor monitor_password mmm_monitor </host> debug 0
  • 25.
    mysql-mmm 启动 启动monitor # /etc/init.d/mysql-mmm-monitor start Daemon bin: '/usr/sbin/mmm_mond' Daemon pid: '/var/run/mmm_mond.pid' Starting MMM Monitor daemon: Ok 启动 agent # /etc/init.d/mysql-mmm-agent start Daemon bin: '/usr/sbin/mmm_agentd' Daemon pid: '/var/run/mmm_agentd.pid' Starting MMM Agent daemon... Ok 可以使用 /etc/init.d/mysql-mmm-monitor –help 查看使用方法, agent 也可以。 使用 ps aux | grep mmm 或者 netstat –tulnp | grep mmm 查看进程是否启动成功
  • 26.
    mysql-mmm 管理工具 #mmm_control help Valid commands are: help - show this message ping - ping monitor show - show status checks [<host>|all [<check>|all]] - show checks status set_online <host> - set host <host> online set_offline <host> - set host <host> offline mode - print current mode. set_active - switch into active mode. set_manual - switch into manual mode. set_passive - switch into passive mode. move_role [--force] <role> <host> - move exclusive role <role> to host <host> (Only use --force if you know what you are doing!) set_ip <ip> <host> - set role with ip <ip> to host <host>
  • 27.
    mysql-mmm 运行状态分析 #mmm_control show // 查看当前虚拟 IP 的分布状况 db1(192.168.199.128) master/ONLINE. Roles: reader(192.168.199.201), writer(192.168.199.200) db2(192.168.199.129) master/ONLINE. Roles: reader(192.168.199.203) db3(192.168.199.130) slave/ONLINE. Roles: reader(192.168.199.202) # mmm_control checks all // 对所有节点进行所有检查 db2 ping [last change: 2011/12/07 19:03:05] OK db2 mysql [last change: 2011/12/07 19:03:05] OK db2 rep_threads [last change: 2011/12/07 19:03:05] OK db2 rep_backlog [last change: 2011/12/07 19:03:05] OK: Backlog is null db3 ping [last change: 2011/12/07 18:17:41] OK db3 mysql [last change: 2011/12/07 18:58:28] OK db3 rep_threads [last change: 2011/12/07 19:16:29] OK db3 rep_backlog [last change: 2011/12/07 18:17:41] OK: Backlog is null db1 ping [last change: 2011/12/07 16:40:10] OK db1 mysql [last change: 2011/12/07 16:40:10] OK db1 rep_threads [last change: 2011/12/07 16:40:10] OK db1 rep_backlog [last change: 2011/12/07 16:40:10] OK: Backlog is null # mmm_control mode // 查看 mmm 当前运行的模式 ACTIVE
  • 28.
    mysql-mmm 故障处理机制 MMM_MONITORListen:tcp9988 Mysql Master A Agent Mysql Master B Agent Mysql slave C Agent Listen:tcp9989 Listen:tcp9989 Listen:tcp9989 monitor 检查 agent 的以下几个状态 1 、 agent 进程 2 、 ping 3 、 mysql 4 、 rep_threads 、 5 、 rep_backlog ping 检查默认是 1s ,通过 ping_interval 配置 mysql 相关的检查默认是 5s ,通过 check_period 配置, trap_period 表示一个节点检测不成功持续的时间,默认为 10 秒,如果超过这个时间就认为这个节点失败了。 如果活动的 master 检测到失败,那么 writer role 将从原来的主机上移除。 active master : 1 、 mysql 设置为 read_only 模式 2 、删除活动的连接 3 、删除虚拟 IP slave : 1 、完成原来主机上的复制工作 2 、切换 master 到新的主机上 new active master : 1 、 mysql 设置为可写模式 2 、配置虚拟 ip
  • 29.
    mysql-mmm 故障模拟 (一 ) 备份 master 故障演示 通过 iptables 来模拟 mysql 故障 on db2 : # iptables -A INPUT -p tcp --dport 9188 -j DROP && date 大概 15 秒 mmm 完成了故障切换 # mmm_control show db1(192.168.199.128) master/ONLINE. Roles: reader(192.168.199.201), writer(192.168.199.200) db2(192.168.199.129) master/HARD_OFFLINE. Roles: db3(192.168.199.130) slave/ONLINE. Roles: reader(192.168.199.202), reader(192.168.199.203) #mmm_control checks all db2 ping [last change: 2011/12/07 23:32:12] OK db2 mysql [last change: 2011/12/07 23:36:06] ERROR: Connect error (host = 192.168.199.129:9188, user = mmm_monitor)! Can't connect to MySQL server on '192.168.199.129' (4) 故障修复后,大概 5 秒完成了 恢复。
  • 30.
    mysql-mmm 故障模拟 (二 ) 活动的 master 故障演示 on db1 # iptables -A INPUT -p tcp --dport 9188 -j DROP && date 大概 15 秒 mmm 完成了故障切换 # mmm_control show db1(192.168.199.128) master/HARD_OFFLINE. Roles: db2(192.168.199.129) master/ONLINE. Roles: reader(192.168.199.202), writer(192.168.199.200) db3(192.168.199.130) slave/ONLINE. Roles: reader(192.168.199.201), reader(192.168.199.203) # mmm_control checks all db1 mysql [last change: 2011/12/07 23:48:39] ERROR: Connect error (host = 192.168.199.128:9188, user = mmm_monitor)! Can't connect to MySQL server on '192.168.199.128' (4) db1 rep_threads [last change: 2011/12/07 23:35:05] OK db1 rep_backlog [last change: 2011/12/07 23:32:12] OK: Backlog is null 故障切换完成以后,检查 DB3 slave 的复制情况,发现已经自动调整到 masterB 了。 故障修复后,大概 5 秒完成了恢复。
  • 31.
    基于 mysql-mmm 的LB 实现 之前已经介绍了什么是 LB 和 mysql LB 的实现方式。 下面我以 php 代码为例,完成的实现基于 mysql-mmm 的读写分离和读负载均衡。 该代码是否 mysql_rw_php 项目修改而来 require_once('mysql_rw_php.class.php'); $ro_host=array(“192.168.199.201:9188”,“ 192.168.199.202:9188 ” ,“ 192.168.199.203:9188 ” ); $a=array_rand($ro_host,1); //rw info $db_rw = array( 'dbhost'=>‘192.168.199.200:9188', 'dbuser'=>'andy', 'dbpw'=>'andy', 'dbname'=>'test‘ ); $db_ro = array( 'dbhost'=>$ro_host[$a], 'dbuser'=>'andy', 'dbpw'=>'andy‘ );
  • 33.
    mmm-tools 介绍 mmm_tools是 mysql-mmm 软件附带的一个工具箱,自带三个工具 mmm_clone 用来克隆一个 mysql 数据库到另外的机器,并且自动完成 master-master 或者 master-slave 的环境搭建,很好用。 ( 前面我们的架构只搭建了 master-master 的架构,我们将用 mmm_clone 完成 master-master-slave 的架构 ) mmm_backup 用来备份一个 mysql 数据库,备份的时候使用了 lvm 快照技术,所以支持热备,并且锁表的时间相当的短 , 支持三种拷贝的方法, scp , ssh-gz , rdiff ,下面会详细介绍。 mmm_restore 还原数据到一个 mysql 数据库,并完成 master-master 或者 master-slave 的环境搭建,不过还原还是建议手动操作,除非你对此工具很熟悉,能够熟练使用,这样才能降低操作带来的风险
  • 34.
    mmm_tools 预备知识 mysql-mmm中文手册: http://linuxguest.blog.51cto.com/195664/578311 mysql-mmm 安装手册: http://linuxguest.blog.51cto.com/195664/578307 lvm 快照技术: http://asram.blog.51cto.com/1442164/313073 使用 lvm 快照备份 mysql : http://linuxguest.blog.51cto.com/195664/585036 如果你对以上知识没有了解的话,请先阅读以上资料,并预先搭建好 mysql-mmm 架构,应为 mmm_tools 是依赖 mysql-mmm 架构工作的。
  • 35.
    mmm-tools 环境需求 搭建好mysql-mmm 环境, 安装 mmm-tools 需要的 perl 插件和创建 tools 的 mysql 用户 Path::Class Data::Dumper 安装好 mysql 数据库,所有服务器尽量使用相同的 mysql 版本 mysql 数据库软件放在 lvm 的逻辑卷上面(备份需要 lvm 快照功能),并且存放 mysql 数据库的逻辑卷组除了 mysql 数据库使用的空间外,还要剩余 1-10G 的空间用于创建快照,快照空间大小根据你数据库的大小和备份时会改变的数据量大小来定,宁多勿少。 安装 rdiff-backup , rdiff-backup 是支持增量备份的一种软件。在 mysql-backup rdiff 拷贝方法中会用到。 参考: http://wiki.rdiff-backup.org/wiki/index.php/Installations
  • 36.
    mmm_tools.conf( 一 )更详细的配置参见我提供的《 mmm-tools 配置手册》 工具全局的配置和主机的默认配置 include mmm_agent.conf default_copy_method scp clone_dirs data <host default> ssh_user root lvm_snapshot_size 1G lvm_logical_volume lvmdb lvm_volume_group myvg lvm_mount_dir /mmm_snapshot // 需要自己创建 lvm_mount_opts -o rw tools_user mmm_tools tools_password mmm_tools backup_dir /mmm_backup // 需要自己创建 restore_dir /mysql // 需要自己创建 </host>
  • 37.
    mmm_tools.conf( 二 )<copy_method scp> // 三种备份方法相关的配置 backup_command scp -c blowfish -r %SSH_USER%@%IP%:%SNAPSHOT%/%CLONE_DIR% %DEST_DIR%/ restore_command cp -axv %BACKUP_DIR%/* %DEST_DIR%/ true_copy 1 </copy_method> <copy_method rdiff> backup_command rdiff-backup --ssh-no-compression -v 5 !--include %SNAPSHOT%/%CLONE_DIR%! --exclude %SNAPSHOT% %SSH_USER%@%IP%::%SNAPSHOT%/ %DEST_DIR%/ restore_command rdiff-backup --force -v 5 -r %VERSION% %BACKUP_DIR% %DEST_DIR%/.mmm_restore; cp -axvl --remove-destination %DEST_DIR%/.mmm_restore/* %DEST_DIR%/; rm -r %DEST_DIR%/.mmm_restore/ incremental_command rdiff-backup --parsable-output -l %BACKUP_DIR% single_run 1 incremental 1 </copy_method> <copy_method ssh-gz> backup_command ssh -c blowfish %SSH_USER%@%IP% &quot;cd '%SNAPSHOT%'; tar cv !'%CLONE_DIR%'!&quot; | gzip > %DEST_DIR%/backup.tar.gz restore_command cd %DEST_DIR%; tar xzfv %BACKUP_DIR%/backup.tar.gz single_run 1 </copy_method>
  • 38.
    mmm_clone 介绍及演示 (一 ) 用法 : Usage: /usr/sbin/mmm_clone [--config <config file>] --host <host> --clone-mode <mode> [--copy-method <copy method>] [--dest-dir <dir>] Where: host : db1 | db2 clone-mode : master-master | master-slave | slave-slave copy-method: scp (default: ssh-gz) dest-dir : directory where data should be cloned to 需求:将 db1 的数据克隆到 db2 ,并搭建 master-master 的复制架构 准备工作 : 1 、 mysql-mmm 已经安装好, mmm 相关的配置文件已经完成 。 2 、 my.cnf 已经配置好(具体配置和注意事项请参照 《 mysql-mmm 安装手册 》 )。 3 、将要使用的数据导入到 db1 完成以上任务后,启动 db1 。把 db2 的数据库关闭
  • 39.
    mmm_clone 介绍及演示 (二 ) 现在我们使用 mmm_clone 完成 db1 到 db2 的数据同步,并且完成 master-master 架构的搭建。 在 db2 上运行下面命令 : #mmm_clone --host db1 --copy-method scp --clone-mode master-master --dest-dir /usr/local/mysql/ INFO: Checking destination directory '/usr/local/mysql/'... INFO: Directory is ok Source host : db1 Destination dir : /usr/local/mysql/ Dirs to clone : var Clone mode : master-master Copy method : scp Replication peer : db1 Setup master-master replication: yes Dry run : no WARN: MySQL is not running now, skipping shutdown ... INFO: Verifying ssh connection to remote host 'root@192.168.199.128' (command: ssh -p 22 root@192.168.199.128 date)... root@192.168.199.128's password:
  • 40.
    mmm_clone 介绍及演示 (三 ) File descriptor 4 (socket:[1661904]) leaked on lvcreate invocation. Parent PID 1141: perl Logical volume &quot;mmm_snapshot&quot; created OK: Snapshot created! INFO: Copying 'var' from snapshot on host 'db1' with copy method 'scp' INFO: Executing command scp -P22 -c blowfish -r root@192.168.199.128:/mmm_snapshot/var /usr/local/mysql// 拷贝文件到 db2 INFO: Copied directory var! INFO: Copying '_mmm' from snapshot on host 'db1' with copy method 'scp' INFO: Executing command scp -P22 -c blowfish -r root@192.168.199.128:/mmm_snapshot/_mmm /usr/local/mysql// root@192.168.199.128's password: status.txt 100% 2454 2.4KB/s 00:00 my.cnf 100% 5570 5.4KB/s 00:00 INFO: Copied directory _mmm! INFO: ssh -p 22 root@192.168.199.128 /usr/lib/mysql-mmm//tools/remove_snapshot root@192.168.199.128's password: Logical volume &quot;mmm_snapshot&quot; successfully removed OK: Snapshot removed! INFO: Cleaning dump from master.info and binary logs... INFO: Deleting master binary logs: mysql-bin.* 已删除“ /usr/local/mysql/var/mysql-bin.index” 已删除“ /usr/local/mysql/var/mysql-bin.000002” 已删除“ /usr/local/mysql/var/mysql-bin.000003” 已删除“ /usr/local/mysql/var/mysql-bin.000001” INFO: Deleting relay binary logs: andy-relay-bin.* 已删除“ /usr/local/mysql/var/andy-relay-bin.000008” 已删除“ /usr/local/mysql/var/andy-relay-bin.000007” 已删除“ /usr/local/mysql/var/andy-relay-bin.index” INFO: Deleting .info and .pid files... 已删除“ /usr/local/mysql/var/master.info” 已删除“ /usr/local/mysql/var/relay-log.info” 已删除“ /usr/local/mysql/var/andy.example.com.pid” INFO: Changing permissions on mysql data dir... INFO: MySQL is not running. Going to start it... Starting MySQL...................... [ 确定 ] INFO: MySQL has been started! INFO: Changing master of host db2 to 192.168.199.128 ... INFO: Successfully changed master. INFO: Changing master of host db1 to 192.168.199.129 ... INFO: Successfully changed master. INFO: Clone operation finished!
  • 41.
    mmm_clone 介绍及演示 (三 ) [root@andy var]# mmm_control show db1(192.168.199.128) master/AWAITING_RECOVERY. Roles: db2(192.168.199.129) master/ONLINE. Roles: reader(192.168.199.201), reader(192.168.199.202), writer(192.168.199.200) [root@andy var]# mmm_control set_online db1 OK: State of 'db1' changed to ONLINE. Now you can wait some time and check its new roles! [root@andy var]# mmm_control show db1(192.168.199.128) master/ONLINE. Roles: reader(192.168.199.202) db2(192.168.199.129) master/ONLINE. Roles: reader(192.168.199.201), writer(192.168.199.200) [root@andy var]# mmm_control checks all db2 ping [last change: 2011/07/03 02:10:35] OK db2 mysql [last change: 2011/07/09 21:48:05] OK db2 rep_threads [last change: 2011/07/09 22:01:22] OK db2 rep_backlog [last change: 2011/07/09 22:01:22] OK: Backlog is null db1 ping [last change: 2011/07/02 18:27:51] OK db1 mysql [last change: 2011/07/09 22:01:22] OK db1 rep_threads [last change: 2011/07/09 22:01:22] OK db1 rep_backlog [last change: 2011/07/02 18:27:51] OK: Backlog is null 当然,你还可以登陆到每台机器,使用 show slave status\G 来详细检查。呵呵,是不是很爽呢。
  • 42.
    mmm_backup 介绍 基于上面搭建的环境,我们来演示三种copy 方法。 用法: Usage: /usr/sbin/mmm_backup [--config <config file>] --host <host> [--copy-method <copy method>] [--dest-dir <dir>] Where: host : db1 | db2 copy-method: rdiff | scp | ssh-gz (default: ssh-gz) dest-dir : directory where data should be backed up to
  • 43.
    mmm_backup 的 scp方法 ( 一 ) 使用 scp 方法把 db1 的数据备份到本地的 /mmm_backup 中。 [root@andy ~]# mmm_backup --host db1 --copy-method scp --dest-dir /mmm_backup/ File descriptor 4 (socket:[1785871]) leaked on lvcreate invocation. Parent PID 16900: perl Logical volume &quot;mmm_snapshot&quot; created OK: Snapshot created! INFO: Copying 'var' from snapshot on host 'db1' with copy method 'scp' INFO: Executing command scp -P22 -c blowfish -r root@192.168.199.128:/mmm_snapshot/var /mmm_backup// 拷贝文件 INFO: Copied directory var! INFO: Copying '_mmm' from snapshot on host 'db1' with copy method 'scp' INFO: Executing command scp -P22 -c blowfish -r root@192.168.199.128:/mmm_snapshot/_mmm /mmm_backup// status.txt 100% 2345 2.3KB/s 00:00 my.cnf 100% 5570 5.4KB/s 00:00 INFO: Copied directory _mmm! INFO: ssh -p 22 root@192.168.199.128 /usr/lib/mysql-mmm//tools/remove_snapshot Logical volume &quot;mmm_snapshot&quot; successfully removed OK: Snapshot removed!
  • 44.
    mmm_backup 的 scp方法 ( 二 ) 备份的结果 备份完成后, --dest-dir 里有两个目录 _mmm 和 var 。 _mmm :主要保存三个文件 Copy_method.txt 备份使用的拷贝方法 My.cnf 备份的 my.cnf Status.txt 包含备份的节点名字,备份时的 master 状态和 slave 状态 var : 保存了备份数据库 /var 目录下的所有文件,包括数据文件, bin-log , relay-log ,等
  • 45.
    mmm_backup 的 ssh-gz方法 B 、 使用 ssh-gz 方法把 db1 的数据备份到本地的 /mmm_backup 中。 注意,此时 /mmm_backup 中已经存在一个备份了,所以在备份到这个目录会不成功,我们可以重新指定一个目录,或者将此目录中备份删掉。 db1 : # cd /mmm_backup/ [root@andy mmm_backup]# ls _mmm var [root@andy mmm_backup]# rm -rf * [root@andy mmm_backup]# mmm_backup --host db1 --copy-method ssh-gz --dest-dir /mmm_backup/ 备份的结果有一个 _mmm 目录和一个 backup.tar.gz 文件。 _mmm 目录和 scp 方法备份出来的一样 Backup.tar.gz 就是 var 使用 gzip 压缩以后的文件,可以大大节约存储空间 推荐使用这种方法备份
  • 46.
    mmm_backup 的 rdiff方法 C 、 使用 rdiff 方法把 db2 的数据备份到本地的 /mmm_backup 中。 使用词拷贝方法,记得要先安装 rdiff-backup 工具。 db1 : [root@andy mmm_backup]# mmm_backup --host db2 --copy-method rdiff --dest-dir /mmm_backup/
  • 47.
    mmm_restore 介绍 还原也分三种拷贝模式,scp 和 ssh-gz 差不多, rdiff 属于增量备份,可以选择还原的版本号。这里我们就只演示 scp 和 rdiff 两种还原。 用法: Usage: /usr/sbin/mmm_restore [--config <config file>] [--mode <mode>] [--version <version | list>] [--src-dir <dir>] [--dest-dir <dir>] [--dry-run] Where: src-dir : directory where backup resides dest-dir: directory where backup should be restored to mode : data-only, single-single, slave-single, master-single, master-slave, slave-slave version : when run with 'list' parameter, displays available versions of incremental backups if version is specified, tries to restore backup for specified version dry-run : check everything and exit without any changes 从上面可以看出, mmm_restore 使用的 — src-dir 和 — dest-dir ,而不是 — host 。
  • 48.
    mmm_restore 的 scp和 ssh-gz 方法 使用 scp 拷贝模式还原数据库 现在我们模仿 db1 数据库文件丢失,需要还原数据的场景。首先手工删除 test 数据文件。 [root@andy var]# cd /usr/local/mysql/var/ && rm -rf test/ [root@andy var]# ls andy.example.com.pid andy-relay-bin.000002 master.info mysql-bin.000001 relay-log.info andy-relay-bin.000001 andy-relay-bin.index mysql mysql-bin.index 还原数据: [root@andy var]# mmm_restore INFO: Checking restore source directory '/mmm_backup'... 这里并没有演示完整还原,因为还原或导致 master-master 复制失败,还原完成, db1 已经自动把 master 转向 db2 ,但是 db2 对 db1 的复制失败了,应为 db1 的 bin-log 发生了变化,需要手工恢复 master-master 复制。 如果真实情况 master 数据丢失需要还原的话,就需要先 resote 到 master ,然后再 mmm_clone 生成复制架构。如果只是 slave 损坏,没必要还原,直接 mmm_clone 过来就可以了
  • 49.
    mmm_restore 的 rdiff方法 还原 rdiff 的备份 [root@andy ~]# mmm_restore --mode master-slave --version list --src-dir /mmm_backup/ --dest-dir /usr/local/mysql/ --dry-run INFO: Checking restore source directory '/mmm_backup/'... INFO: Directory is ok Following backup versions are available: Version | Date 1310222305 | Sat Jul 9 22:38:25 2011 1310222616 | Sat Jul 9 22:43:36 2011 [root@andy ~]# mmm_restore --mode master-slave --version 1310222616 --src-dir /mmm_backup/ --dest-dir /usr/local/mysql/ --dry-run --version // 选择 version 编号或者使用 — list 显示可用的编号。 --dry-run // 测试是否可以运行,不真正运行。 使用还原前关掉 mysql 数据库,貌似 mmm_tools 存在一个 bug ,关于还原前和 clone 前关闭数据库的命令。 [root@andy var]# mmm_restore --mode master-slave --version 1310222616 --src-dir /mmm_backup/ --dest-dir /usr/local/mysql/ 还原完成, db1 已经自动把 master 转向 db2 ,但是 db2 对 db1 的复制失败了,应为 db1 的 bin-log 发生了变化,这个只有手工处理。
  • 50.
    mmm 故障总结 mysql-mmm出现故障的最大可能就是你的 perl 模块没有安装齐全,导致 mysql-mmm 不能够预期工作 定期优化检查 myisam 表,定期使用 mk-table-checksum 检查主从的一致性 mmm-tools 存在以下几个注意 如果当命令执行到一半而由于配置错误退出时,快照已经生成,但是命令未执行完,导致快照没有删除,需要自己使用 lvremove –f 快照名 删除快照。 注意 mmm_tools.cnf 要针对所在主机环境配置,不是所有都一样,特别注意 server-id 和自动增长列。 生产环境下,备份好以后,需要转移做测试,看备份是否可以用。还原最好手工操作,避免误伤。 最后:上线前各种故障模拟测试,故障后日志是解决问题的关键。

Editor's Notes

  • #2 12/12/11
  • #41 12/12/11
  • #44 [root@andy ~]# mmm_backup --host db1 --copy-method scp --dest-dir /mmm_backup/ INFO: Checking local destination directory &apos;/mmm_backup/&apos;... INFO: Directory is ok INFO: Verifying ssh connection to remote host &apos;root@192.168.199.128&apos; (command: ssh -p 22 root@192.168.199.128 date)... root@192.168.199.128&apos;s password: Thu Dec 8 00:05:42 CST 2011 INFO: OK: SSH connection works fine! INFO: ssh -p 22 root@192.168.199.128 /usr/lib/mysql-mmm//tools/create_snapshot root@192.168.199.128&apos;s password: File descriptor 4 (socket:[1785871]) leaked on lvcreate invocation. Parent PID 16900: perl Logical volume &amp;quot;mmm_snapshot&amp;quot; created OK: Snapshot created! INFO: Copying &apos;var&apos; from snapshot on host &apos;db1&apos; with copy method &apos;scp&apos; INFO: Executing command scp -P22 -c blowfish -r root@192.168.199.128:/mmm_snapshot/var /mmm_backup// 拷贝文件 INFO: Copied directory var! INFO: Copying &apos;_mmm&apos; from snapshot on host &apos;db1&apos; with copy method &apos;scp&apos; INFO: Executing command scp -P22 -c blowfish -r root@192.168.199.128:/mmm_snapshot/_mmm /mmm_backup// root@192.168.199.128&apos;s password: status.txt 100% 2345 2.3KB/s 00:00 my.cnf 100% 5570 5.4KB/s 00:00 INFO: Copied directory _mmm! INFO: ssh -p 22 root@192.168.199.128 /usr/lib/mysql-mmm//tools/remove_snapshot root@192.168.199.128&apos;s password: Logical volume &amp;quot;mmm_snapshot&amp;quot; successfully removed OK: Snapshot removed! 12/12/11