调用:/etc/sbin/mmm_mond
注意: 启动后,mmm_control 不能马上使用,需要等几秒之后才能使用
配置文件路径优先级:/etc, /etc/mmm, /etc/mysql-mmm
改进:
参数MMM_AGENTD_PIDFILE在文件中写死的,不会使用配置mmm_mon.conf中的定义
MMM_MOND_BIN 启动是调用的脚本/usr/sbin/mmm_mond
MMM_MOND_PIDFILE 生成的PID文件 /var/run/mmm_mond.pid,不改动没啥影响
rep_backlog 代表从库的延迟读取 Seconds_Behind_Master值,不够准确
====================================== /etc/sbin/mmm_mond
初始化日志文件,调用 lib\Common\Log.pm :: init("mmm_mon_log.conf", "mmm_mond")
查找 mmm_agent_log.conf 配置文件; 若找不到则默认为/var/log/mysql-mmm/mmm_mond.log
读取并检查配置文件,调用 lib\Common\Config.pm :: read("mmm_mon"),check('MONITOR');
查找 mmm_mon.conf 配置文件; 若找不到,则退出
如果未开启debug,使用 Daemon 模式,并且重新做一次"初始化日志"
生成PID(pid = fork();),如果尝试10次未成功,则退出。调用 lib\Common\Angel.pm 中Init方法
监测系统信号:
$SIG{INT} ,$SIG{TERM},$SIG{QUIT}。这3种信号都会使agent结束
$SIG{CHLD} 。创建childhandler??my $pid = waitpid(-1, WNOHANG)
初始化 Monitor, 调用 \lib\Monitor\Monitor.pm 中 init 方法
检查所有IP(mmm_mon.conf中配置的ping_ips)的网络状态。Net::Ping->(icmp)
初始化队列(new Thread::Queue::):checker_queue,command_queue,result_queue
进行一次检查['ping', 'mysql', 'rep_backlog', 'rep_threads']。调用 lib\Monitor\Checker.pm 中对应的方法
rep_backlog 代表从库的延迟读取 Seconds_Behind_Master值,不够准确
设置monitor mode:默认是active。共4种 'passive', 'active', 'manual', 'wait',mmm_mon.conf中
各种值的意思?
设置 kill_host_bin,默认情况下不用关心
检查master的配置
若只有1个master,则直接跳过
若多余2个master,则报错退出
主要检查内容:是否能连接,是否互主,自增设置
创建agent对象。 调用 lib\Monitor\Agents.pm :: _new_instance 方法
从status文件中读取agent的状态信息,第一次启动时文件为空。status文件路径 mmm_mon.conf中 status_path 配置
循环检测所有agent的状态,并存入status文件中。状态包含内容:本机host,state,role,master
调用 lib\Monitor\StartupStatus.pm :: set_agent_status 方法进行设置
通过发送命令进行收集agent的状态。调用 lib\Monitor\Agent.pm --> lib\Common\Socket.pm :: create_sender 方法
GET_AGENT_STATUS 收集 host, state, roles, master
GET_SYSTEM_STATUS 收集 host, writable, roles, master
收集成功,则重新设置agent 状态数据;
若收集失败,并且返回的state 不等于ADMIN_OFFLINE,当ping|mysql|agent这3中check中有1个失败, 则设置该agent的agent_down=1
设置每个agent的state和role。调用 lib\Monitor\StartupStatus.pm :: determine_status 方法
根据agent返回的select @@read_only值来记录此host是否writable。疑问:agent的read_only何时设置?
并且设置state为online,除了下面几种情况
if ($state eq 'ADMIN_OFFLINE' || (!$is_manual && $state ne 'ONLINE' && $state ne 'AWAITING_RECOVERY'))
检测是否有ip冲突
若monitor mode不是passive,则通知client清除自己的role(VIP)
调用 cleanup_and_send_status 方法
通知顺序:passive_master, slave, active_master
如果不按此顺序会有什么问题?
个人理解:必须保证 passiveM在activeM之前就可以,防止activeM停止时切换到passiveM
启动 Monitor 主函数, 调用 main 方法
创建check相关内容线程。即init时创建的那4个
检查周期为 check_period,默认为 5s
主循环
处理check结果
_process_check_results --> lib\Monitor\ChecksStatus.pm :: handle_result 方法
保存最新的 message, state, last_change. state和last_change不是每次都会更新
检查host状态
_check_host_states 方法,根据当前host的不同状态做相应处理
ONLINE
若无法ping通或mysql连不上
则从ONLINE 转为 HARD_OFFLINE
若是非manual模式, 则清除对应的role, 并且将最新状态发给agent
进行下一个host检查
若host是activeM,则不再进行检查
若上一次检查距离当前时间小于 60 (peer_online_since 配置) 秒
检查复制线程与复制延迟,若有异常则更新最新状态,并发送到 agent
AWAITING_RECOVERY
若无法ping通或mysql连不上
则转为 HARD_OFFLINE
进行下一个host检查
若所有check都正常, 并配置了auto_set_online,间隔时间大于auto_set_online
则转为 ONLINE, 并发送到 agent
进行下一个host检查
HARD_OFFLINE
若ping通 并且mysql可以连接
若activeM不为空
若replication失败
转为 REPLICATION_FAIL, 并发送到 agent
进行下一个host检查
若replication 延迟
转为 REPLICATION_DELAY, 并发送到 agent
进行下一个host检查
转为 AWAITING_RECOVERY, 并发送到 agent
进行下一个host检查
REPLICATION_FAIL
若存在replication 延迟
转为 REPLICATION_DELAY
进行下一个host检查
若所有check都正常
转为 ONLINE, 并发送到 agent
进行下一个host检查
若无法ping通或mysql连不上
转为 HARD_OFFLINE, 并发送到 agent
进行下一个host检查
REPLICATION_DELAY
若存在replication 失败
转为 REPLICATION_FAIL
进行下一个host检查
若所有check都正常
转为 ONLINE, 并发送到 agent
进行下一个host检查
若无法ping通或mysql连不上
转为 HARD_OFFLINE, 并发送到 agent
进行下一个host检查
若mode是wait模式
如果两个M中有一个正常,则设置activeM,优先级按配置中顺序
若mode此时改为active,则清除role,比发送给agent
非passive模式下,保存agent状态
处理命令行
_process_commands 处理cmd线程获取的命令(保存在队列中)
每个命令对应的方法在 lib\Monitor\Commands.pm 可以找到
重新分布roles
_distribute_roles 方法
按配置的role,ips顺序一次给role分配相应的ip
如果new activeM不等于old activeM,则通知agent
发送最新状态到agent。 send_status_to_agents 方法
锁定cmd队列
lock($command_queue);
3秒后或者收到 cond_signal or cond_broadcast 信号,解除锁定
cond_timedwait($command_queue, time() + 3);
$command_queue 必须先被lock,才能被此方法使用
参见:http://search.cpan.org/~jdhedden/threads-shared-1.46/lib/threads/shared.pm
如果没有shutdown命令,则继续下一循环
回收线程。使用join方式