4月 18

监控mysql从机同步状态脚本

  mysql数据库主从运行。为了知道从机的同步情况,写了个脚本,放在crontab中,如果同步出错,则邮件报警。去年写的,放上来做个备忘。

#!/usr/local/bin/python
# -------------------------------------------------------------------------------
# Filename:    .py
# Revision:    1.0
# Date:        2012-03-20
# Author:      simonzhang
# Web:         www.simonzhang.net
# Email:       simon-zzm@163.com
# -------------------------------------------------------------------------------
import os
import pexpect
import time
import smtplib
from email.mime.text import MIMEText

#### base se
mysql_bin = '/mysql5/bin/mysql'
mysql_user = ''
mysql_pass = ''
mail_host = 'smtp.exmail.qq.com'
mail_user = 'XXX@XXX.net'
mail_pwd = 'XXXX'
mail_to = "xxxxx@xxx.com"
####

def mail_warn(error_ip):
    content = 'IP %s mysql slave is error!'%error_ip
    msg = MIMEText(content)
    msg['From'] = mail_user
    msg['Subject'] = 'mysql warnning %s'%error_ip
    msg['To'] = mail_to
    try:
        s = smtplib.SMTP()
        s.connect(mail_host)
        s.login(mail_user,mail_pwd)
        s.sendmail(mail_user,[mail_to],msg.as_string())
        s.close()
    except Exception ,e:
        print e

def main():
    status = os.popen("%s -u%s -p%s -e 'show slave status\G'"%
                      (mysql_bin,mysql_user,mysql_pass)).read() 
    io_status = status[status.find('Slave_IO_Running: ')+18]
    sql_status = status[status.find('Slave_SQL_Running: ')+19]
    if (io_status == 'Y') or (sql_status == 'Y'):
        ip = os.popen("/sbin/ifconfig|grep 'inet addr'|awk '{print $2}'").read()
        get_local_ip = ip[ip.find(':')+1:ip.find('n')]
        mail_warn("%s"%get_local_ip)

if __name__ == "__main__":
    main()
7月 13

mysql 索引文件错误修复

服务器出现宕机,重启后查看数据库日志报错如下:
120712 9:25:50 [ERROR] /program/mysql/libexec/mysqld: Table ‘./week_lib’ is marked as crashed and should be repaired

在mysql的bin目录中找到myisamchk可执行文件进行修复。
使用的命令如下:
/program/mysql/bin/myisamchk -c -r /program/mysql/data/test/week_lib.

如果还不行,就-f 强制修复

如果有phpmyadmin就方便多了。直接在右则勾选中错误信息中的表,选择下拉菜单(With selected:)中”Repair table”进行修复。
造成此类错误的主要原因是,突然断电、宕机、磁盘损坏导致数据文件出错。

2月 17

mysql 升级5.5.20 注意问题记录

当前使用mysql5.1但是有些表情字符不能加入,所以决定将数据库
升级到5.5.20。从官方下载二进制64位工具。
http://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-5.5.20-linux2.6-x86_64.tar.gz/from/http://mysql.cs.pu.edu.tw/

直接解压,将老版本的数据直接拷贝过来,启动数据库。整个过程比较顺利,
数据库已经运行,为了避免以下错误,还需要进行以下操作。

a) 错误1548 – Cannot load from mysql.proc. The table is probably corrupted.

需要对数据进行升级。执行以下命令。
$ mysql_upgrade -u root -p
在出现一堆ok后升级完成。

b) 岁然数据库和数据升级了,还需要修改表的字符集。(根据需要进行修改)

登录mysql,进入相关库,使用如下命令。
> alter table xxxx charset utf8mb4;
当前数据库可以支持iphone表情和奇怪的字符集了。

升级过程注意保存原有配置。

9月 11

mysql双机热备恢复问题

Mysql中双机热备比较常见。运维过程中遇到一个问题,备机或主机的其中一台遇到硬盘物理故障,重装系统后需要重新同步数据。这时就遇到了一个问题,用“FLUSH TABLES WITH READ LOCK;”命令锁上所有表或者再mysqldump数据时使用“–lock-all-tables”或“–master-data”参数导出数据,但是数据库被锁不能操作,前台业务会报错,问题很严重。在oracle中有SCNThe System Change Number),在mysql的二进制日志中有position,所以只能从此处考虑。

所以我写一个脚本,思维逻辑如下:

a) 使用语句“show master statusG;” 获得导出开始的position的点

b) 开始导出整库数据

c) 导出完毕,再使用语句“show master statusG;” 获得导出结束的position的点

d) binlog中导出开始position点到结束position点得变化的增量数据

导入逻辑:

a) 先导入整库数据

b) 再导入增量的数据

c) 然后确认开始同步的position点,开始同步

做增量的数据需要使用mysql自带的mysqlbinlog命令,mysqlbinlog也可以远程使用,为了防止网络问题所以没有采用远程的方案。

Mysqlbinlog命令的主要参数如下:

-d, –database=name 仅列出该数据库相关的

-F, –force-if-open 强行读出正在使用的二进制文件

-j, –start-position=# 开始读取点

–stop-position=# 结束读取点

 –start-date 开始获取时间

 –stop-date 结束获取时间

导出完毕,在备机上先恢复整库文件,再恢复增量文件,再设置恢复点。还有几个文件问题没有太仔细考虑,如备份过程中二进制日志切换,数据量大的时候会出现增量和整库的重复等问题未考虑。本处只是抛砖引玉。

脚本如下(注意折行问题):

#!/bin/sh

#————————————————

# file name: mysql_dump_binlog.sh

# Revision: 1.0

# Date: 2011-09-10

# Author: simon-zzm

# Email: simon-zzm@163.com

# ———————————————–

#############set bases value

mysql_path=’/usr/local/mysql’

dump_path=’/usr/local/checksystem’

mysql_host=’192.168.1.12′

mysql_user=’root’

mysql_pass=’qq’

mysql_data=’test’

#############main

start_time=`/bin/date +%Y-%m-%d %H:%M:%S`

${mysql_path}/bin/mysql -h${mysql_host} -u${mysql_user} -p${mysql_pass} -e ‘show master statusg;’>/tmp/mysql_start_read_mast

get_start_f=`tail -1 /tmp/mysql_start_read_mast|/bin/awk ‘ ”{print $1}’`

#${mysql_path}/bin/mysqldump -h${mysql_host} -u${mysql_user} -p${mysql_pass} ${mysql_data}>${dump_path}/${mysql_data}_${now_time}.sql

sleep 30

${mysql_path}/bin/mysql -h${mysql_host} -u${mysql_user} -p${mysql_pass} -e ‘show master statusg;’>/tmp/mysql_end_read_mast

get_end_p=`/usr/bin/tail -1 /tmp/mysql_end_read_mast|/bin/awk ‘ ”{print $2}’`

get_end_f=`/usr/bin/tail -1 /tmp/mysql_end_read_mast|/bin/awk ‘ ”{print $1}’`

echo “dump database ${mysql_data} ok.”

stop_time=`/bin/date +%Y-%m-%d %H:%M:%S`

${mysql_path}/bin/mysqlbinlog -d${mysql_data} -F –start-date=”${start_time}” –stop-date=”${stop_time}” ${mysql_path}/data/${get_start_f}>${dump_path}/${mysql_data}_repair_${now_time}.sql

echo “CHANGE MASTER TO MASTER_LOG_FILE=’${get_end_f}’,MASTER_LOG_POS=${get_end_p} ; “

/bin/rm -rf /tmp/mysql_start_read_mast /tmp/mysql_end_read_mast

echo “repair database ${mysql_data} ok.”

9月 07

测试mydumper导出效果

网上介绍mydumper可以同时备份多个table,导出速度比较mysqldump快,今天测试一下。

首先升级模块

yum install glib2-devel mysql-devel zlib-devel pcre-devel

还需要安装cmake

# wget http://www.cmake.org/files/v2.8/cmake-2.8.5.tar.gz

# tar zxvf cmake-2.8.5.tar.gz

# cd cmake-2.8.5

# ./configure && make && make install

开始安装工具

# wget http://launchpad.net/mydumper/0.2/0.2.3/+download/mydumper-0.2.3.tar.gz

# tar zxvf mydumper-0.2.3.tar.gz

# cd mydumper-0.2.3

# cmake .
# make
# make install

有两个工具

备份工具:mydumper

恢复工具:myloader

使用mydumper导出测试

# time mydumper -u root -p test -h 127.0.0.1 -P 3306 -B test -S /tmp/mysql.sock -o /tmp/mysql

real 2m11.954s

user 0m20.359s

sys 0m11.472s

使用mydump导出测试

# time mysqldump -u root -p -h 127.0.0.1 -P 3306 test>/tmp/test.sql

Enter password:

real 3m0.272s

user 0m47.459s

sys 0m16.837s

初步看导出速度提高的并不是很大。