标签为 Mysql 的文章

使用innobackupex备份和恢复MySQL

参考资料:
https://www.percona.com/doc/percona-xtrabackup/2.2/innobackupex/privileges.html
https://www.percona.com/doc/percona-xtrabackup/2.1/innobackupex/streaming_backups_innobackupex.html
https://www.percona.com/doc/percona-xtrabackup/2.1/howtos/recipes_ibkx_compressed.html
https://www.percona.com/doc/percona-xtrabackup/2.1/innobackupex/incremental_backups_innobackupex.html

背景介绍:
在一些技术群里面,看到仍然有一些运维在用mysqldump这样的命令来备份MySQL,于是感觉有必要介绍一下innobackupex。
现在,绝大多数使用MySQL的场景中,都用到了Master-Slave这样的架构。相对于mysqldump而言,使用innobackupex备份有以下好处:
1. 以数据文件为备份对象,文件级别备份,速度快,尤其适合需要对所有数据进行备份的场景;
2. 热备份,不会对现有的数据库访问造成影响;
3. 记录binlog以及replication相关信息,在创建和恢复Slave时非常有用;
4. 支持对备份后的数据进行同步并行压缩,有效节省磁盘空间;

目前,在我们的线上环境中,数据库的大小,在没有压缩之前为500G左右,压缩之后的大小为90G左右。
而在风哥的环境中,数据库的大小已经超过了1T,以下是风哥的几点补充:
1.用innobackupex可以做到不停业务在线备份,前提是对innodb引擎,对myisam也会锁表;
2.在备份过程会导致IO很高,建议在一台slave上做备份(一般用一台slave只做备份用),不建议在主上备份;
3.innobackupex可以用增量与全量备份方式配合;

另外,杨总在学习了ITIL之后,补充到:对于最近的一次全量备份,除了要做到异地备份以外,还应该尽量在数据库所在的服务器本地保存一份没有经过压缩打包的备份,这样在进行灾难恢复的时候,能够节省大量的时间。

具体用例:
环境介绍

架构:Master-Slave
服务器:idc1-master1, idc1-slave1
MySQL端口:3308
配置文件:/etc/my_3308.cnf
备份目录:/mysql-backup/3308
MySQL数据目录:/opt/mysql_3308/data
服务脚本:/etc/init.d/mysql_3308

1. 在Master和Slave上安装xtrabackup:
注意:如果你安装的不是Percona版本的MySQL,或者MySQL版本低于5.5,请安装percona-xtrabackup-20,并忽略下面所有压缩相关的步骤与参数。

# yum install http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm
# yum install -y percona-xtrabackup qpress
# yum install -y percona-xtrabackup-20 # 非Percona版本的MySQL,或者MySQL版本低于5.5

2. 在Master和Slave上创建一个用于备份的用户backup-user:

mysql> CREATE USER 'backup-user'@'localhost' IDENTIFIED BY 'backup-pass';
mysql> GRANT SUPER, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'backup-user'@'localhost';
mysql> FLUSH PRIVILEGES;
mysql> EXIT;

注意:对于非Percona版本的MySQL,或者MySQL版本低于5.5,如5.1,需要额外增加SELECT权限,否则会出现mysql系统数据库备份权限不足的问题。

mysql> GRANT SELECT, SUPER, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'backup-user'@'localhost';

3. 在Master上备份
常规方式

[root@idc1-master1 ~]# innobackupex --defaults-file=/etc/my_3308.cnf --user=backup-user --password=backup-pass --use-memory=4G /mysql-backup/3308

[root@idc1-master1 ~]# ls -rt1 /mysql-backup/3308/ | tail -n 1
2015-10-26_03-00-10

压缩打包方式

[root@idc1-master1 ~]# innobackupex --defaults-file=/etc/my_3308.cnf --user=backup-user --password=backup-pass --use-memory=4G --compress --compress-threads=8 --stream=xbstream --parallel=4 /mysql-backup/3308 > /mysql-backup/3308/$(date +%Y-%m-%d_%H-%M-%S).xbstream

[root@idc1-master1 ~]# ls -rt1 /mysql-backup/3308/ | tail -n 1
2015-10-26_03-05-05.xbstream

4. 在Slave上备份
常规方式

[root@idc1-slave1 ~]# innobackupex --defaults-file=/etc/my_3308.cnf --user=backup-user --password=backup-pass --use-memory=4G --slave-info --safe-slave-backup /mysql-backup/3308

[root@idc1-slave1 ~]# ls -rt1 /mysql-backup/3308/ | tail -n 1
2015-10-26_03-11-03

压缩打包方式

[root@idc1-slave1 ~]# innobackupex --defaults-file=/etc/my_3308.cnf --user=backup-user --password=backup-pass --use-memory=4G --slave-info --safe-slave-backup --compress --compress-threads=8 --stream=xbstream --parallel=4 /mysql-backup/3308 > /mysql-backup/3308/$(date +%Y-%m-%d_%H-%M-%S).xbstream

[root@idc1-slave1 ~]# ls -rt1 /mysql-backup/3308/ | tail -n 1
2015-10-26_03-15-03.xbstream

5. 在Master上恢复

[root@idc1-master1 ~]# /etc/init.d/mysql_3308 stop

[root@idc1-master1 ~]# mv /opt/mysql_3308/data /opt/mysql_3308/data_broken
[root@idc1-master1 ~]# mkdir /opt/mysql_3308/data

# 常规方式
[root@idc1-master1 ~]# innobackupex --apply-log --use-memory=4G /mysql-backup/3308/2015-10-26_03-00-10
[root@idc1-master1 ~]# innobackupex --defaults-file=/etc/my_3308.cnf --copy-back --use-memory=4G /mysql-backup/3308/2015-10-26_03-00-10 

# 压缩打包方式
[root@idc1-master1 ~]# mkdir -p /mysql-backup/3308/2015-10-26_03-05-05
[root@idc1-master1 ~]# xbstream -x < /mysql-backup/3308/2015-10-26_03-05-05.xbstream -C /mysql-backup/3308/2015-10-26_03-05-05
[root@idc1-master1 ~]# innobackupex --decompress --parallel=4 /mysql-backup/3308/2015-10-26_03-05-05
[root@idc1-master1 ~]# find /mysql-backup/3308/2015-10-26_03-05-05 -name "*.qp" -delete
[root@idc1-master1 ~]# innobackupex --apply-log --use-memory=4G /mysql-backup/3308/2015-10-26_03-05-05
[root@idc1-master1 ~]# innobackupex --defaults-file=/etc/my_3308.cnf --copy-back --use-memory=4G /mysql-backup/3308/2015-10-26_03-05-05 

[root@idc1-master1 ~]# chown -R mysql:mysql /opt/mysql_3308/data

[root@idc1-master1 ~]# /etc/init.d/mysql_3308 start

6. 在Slave上恢复

[root@idc1-slave1 ~]# /etc/init.d/mysql_3308 stop

[root@idc1-slave1 ~]# mv /opt/mysql_3308/data /opt/mysql_3308/data_broken
[root@idc1-slave1 ~]# mkdir /opt/mysql_3308/data

# 常规方式
[root@idc1-slave1 ~]# innobackupex --apply-log --use-memory=4G /mysql-backup/3308/2015-10-26_03-11-03
[root@idc1-slave1 ~]# innobackupex --defaults-file=/etc/my_3308.cnf --copy-back --use-memory=4G /mysql-backup/3308/2015-10-26_03-11-03 

# 压缩打包方式
[root@idc1-slave1 ~]# mkdir -p /mysql-backup/3308/2015-10-26_03-15-03
[root@idc1-slave1 ~]# xbstream -x < /mysql-backup/3308/2015-10-26_03-15-03.xbstream -C /mysql-backup/3308/2015-10-26_03-15-03 
[root@idc1-slave1 ~]# innobackupex --decompress --parallel=4 /mysql-backup/3308/2015-10-26_03-15-03 
[root@idc1-slave1 ~]# find /mysql-backup/3308/2015-10-26_03-15-03 -name "*.qp" -delete [root@idc1-slave1 ~]# innobackupex --apply-log --use-memory=4G /mysql-backup/3308/2015-10-26_03-15-03 
[root@idc1-slave1 ~]# innobackupex --defaults-file=/etc/my_3308.cnf --copy-back --use-memory=4G /mysql-backup/3308/2015-10-26_03-15-03 

[root@idc1-slave1 ~]# chown -R mysql:mysql /opt/mysql_3308/data 
[root@idc1-slave1 ~]# /etc/init.d/mysql_3308 start 

[root@idc1-slave1 ~]# cd /opt/mysql_3308/data 

# 从Master的备份中恢复时查看 xtrabackup_binlog_pos_innodb 
[root@idc1-slave1 data]# cat xtrabackup_binlog_pos_innodb ./bin-log-mysqld.000222 222333 

# 从Slave的备份中恢复时查看 xtrabackup_slave_info 
[root@idc1-slave1 data]# cat xtrabackup_slave_info 
CHANGE MASTER TO MASTER_LOG_FILE='bin-log-mysqld.000222', MASTER_LOG_POS=222333 

[root@idc1-slave1 data]# mysql_3308 -uroot -p 
mysql> change master to
master_host='idc1-master1',
master_port=3308,
master_user='backup-user',
master_password='backup-pass',
master_log_file='bin-log-mysqld.000222',
master_log_pos=222333;
mysql> start slave;
mysql> show slave status\G;
mysql> exit;

7. 增量备份与恢复
增量备份的原理是,基于一个现有的完整备份,针对InnoDB-based表仅备份增量的部分,针对MyISAM表则仍然保持全量备份。

备份环境:
在Slave服务器上进行

备份策略:
每天1次完整备份 + 每天2次增量备份

具体步骤:
7.1 增量备份
7.1.1 准备完整备份(压缩但不打包方式):

[root@idc1-slave1 ~]# innobackupex --defaults-file=/etc/my_3308.cnf --user=backup-user --password=backup-pass --use-memory=4G --slave-info --safe-slave-backup --compress --compress-threads=8 /mysql-backup/3308

[root@idc1-slave1 ~]# ls -rt1 /mysql-backup/3308/ | tail -n 1
2015-10-26_06-48-33

[root@idc1-slave1 ~]# cat /mysql-backup/3308/2015-10-26_06-48-33/xtrabackup_checkpoints
backup_type = full-backuped
from_lsn = 0
to_lsn = 1631145
last_lsn = 1631145
compact = 0
recover_binlog_info = 0

7.1.2 进行第1次增量备份(压缩但不打包方式):

[root@idc1-slave1 ~]# innobackupex --defaults-file=/etc/my_3308.cnf --user=backup-user --password=backup-pass --use-memory=4G --slave-info --safe-slave-backup --compress --compress-threads=8 --incremental /mysql-backup/3308 --incremental-basedir=/mysql-backup/3308/2015-10-26_06-48-33

[root@idc1-slave1 ~]# ls -rt1 /mysql-backup/3308/ | tail -n 1
2015-10-26_06-55-12

[root@idc1-slave1 ~]# cat /mysql-backup/3308/2015-10-26_06-55-12/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 1631145
to_lsn = 1635418
last_lsn = 1635418
compact = 0
recover_binlog_info = 0

7.1.3 进行第2次增量备份(压缩但不打包方式):

[root@idc1-slave1 ~]# innobackupex --defaults-file=/etc/my_3308.cnf --user=backup-user --password=backup-pass --use-memory=4G --slave-info --safe-slave-backup --compress --compress-threads=8 --incremental /mysql-backup/3308 --incremental-basedir=/mysql-backup/3308/2015-10-26_06-55-12

[root@idc1-slave1 ~]# ls -rt1 /mysql-backup/3308/ | tail -n 1
2015-10-26_06-59-49

[root@idc1-slave1 ~]# cat /mysql-backup/3308/2015-10-26_06-59-49/xtrabackup_checkpoints
backup_type = incremental
from_lsn = 1635418
to_lsn = 1639678
last_lsn = 1639678
compact = 0
recover_binlog_info = 0

7.2 增量恢复:
7.2.1 取回完整备份(必须加参数 --redo-only)

[root@idc1-slave1 ~]# innobackupex --decompress --parallel=4 /mysql-backup/3308/2015-10-26_06-48-33
[root@idc1-slave1 ~]# find /mysql-backup/3308/2015-10-26_06-48-33 -name "*.qp" -delete
[root@idc1-slave1 ~]# innobackupex --apply-log --redo-only --use-memory=4G /mysql-backup/3308/2015-10-26_06-48-33

7.2.2 合并第1个增量(必须加参数 --redo-only)

[root@idc1-slave1 ~]# innobackupex --decompress --parallel=4 /mysql-backup/3308/2015-10-26_06-55-12
[root@idc1-slave1 ~]# find /mysql-backup/3308/2015-10-26_06-55-12 -name "*.qp" -delete
[root@idc1-slave1 ~]# innobackupex --apply-log --redo-only --use-memory=4G /mysql-backup/3308/2015-10-26_06-48-33 --incremental-dir=/mysql-backup/3308/2015-10-26_06-55-12

7.2.3 合并第2个增量(合并最后一个增量备份时不加 --redo-only)

[root@idc1-slave1 ~]# innobackupex --decompress --parallel=4 /mysql-backup/3308/2015-10-26_06-59-49
[root@idc1-slave1 ~]# find /mysql-backup/3308/2015-10-26_06-59-49 -name "*.qp" -delete
[root@idc1-slave1 ~]# innobackupex --apply-log --use-memory=4G /mysql-backup/3308/2015-10-26_06-48-33 --incremental-dir=/mysql-backup/3308/2015-10-26_06-59-49

7.2.4 准备完整备份(定稿完整备份时不加 --redo-only)

[root@idc1-slave1 ~]# innobackupex --apply-log --use-memory=4G /mysql-backup/3308/2015-10-26_06-48-33

7.2.5 恢复完整备份(按照以上 常规方式,执行从--copy-back开始及之后的步骤)

,

No Comments

Nginx+PHP(FastCGI)+MySQL在小内存VPS(t1.micro)上的安装配置与优化

参考资料:
http://blog.s135.com/nginx_php_v6/
http://blog.s135.com/post/375/

背景介绍:
以前,因为AWS EC2的价格比较昂贵而租用了其它国外小厂商的VPS,在使用了3年多之后,发现AWS EC2的价格居然比现在正在使用的VPS还要便宜。
全球线路与速度最理想的日本节点的t1.micro型号,选择3年长期合约的价格在3000元人民币左右,一年下来也不到1000元,所以就打算将Blog迁移到AWS EC2上。
ec2_tokyo_t1_micro

之前在部署VPS环境的时候,基本上是完整的参考了张宴的两篇文档,包括操作系统的选择也是相同的。
但这一次我想采用目前较新的CentOS 6.4 minimal x86_64
同时选择版本最新的Nginx,PHP以及MySQL,引入EPEL仓库来简化安装与部署过程中对额外的依赖软件的安装,优化一些原来的工作方式,比如创建服务管理脚本来启动/停止Nginx与MySQL,使用logrotate来切割日志等;
经过了一番折腾,在填了不少的坑之后,终于成功的完成了新环境的部署,感觉非常不错。

下面,就是此次的整个安装配置过程:
1. 安装常用工具
yum install -y vim wget unzip screen tree mlocate

2. 安装编译工具
yum install -y gcc gcc-c++ autoconf patch cmake automake

3. 安装EPEL仓库
yum install -y http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

4. 安装所有必需的软件包
yum install -y libjpeg-turbo libjpeg-turbo-devel libpng libpng-devel freetype freetype-devel
yum install -y libxml2 libxml2-devel zlib zlib-devel glibc glibc-devel glib2 glib2-devel gmp gmp-devel
yum install -y bzip2 bzip2-devel ncurses ncurses-devel curl curl-devel e2fsprogs e2fsprogs-devel unixODBC unixODBC-devel
yum install -y krb5-libs krb5-devel libidn libidn-devel openssl openssl-devel openldap openldap-devel
yum install -y libgcrypt libgcrypt-devel libtool
yum install -y libmcrypt libmcrypt-devel mhash mhash-devel mcrypt pcre pcre-devel
yum install -y ImageMagick ImageMagick-devel

5. 下载所有必需的软件源码包
mkdir /root/packages
cd /root/packages
wget http://nginx.org/download/nginx-1.4.7.tar.gz
wget http://museum.php.net/php5/php-5.2.17.tar.gz
wget http://php-fpm.org/downloads/php-5.2.17-fpm-0.5.14.diff.gz
wget http://mirrors.sohu.com/mysql/MySQL-5.5/mysql-5.5.36.tar.gz
wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.14.tar.gz
wget http://pecl.php.net/get/PDO_MYSQL-1.0.2.tgz
wget http://pecl.php.net/get/imagick-3.2.0RC1.tgz
wget https://github.com/downloads/eaccelerator/eaccelerator/eaccelerator-0.9.6.1.tar.bz2

6. 编译安装iconv
cd /root/packages
tar xzvf libiconv-1.14.tar.gz
cd libiconv-1.14
./configure
make
make install
阅读全文 »

, , , , , ,

2 Comments

MySQL 官方 Auto-Failover 功能测试

参考资料:
http://www.clusterdb.com/mysql/replication-and-auto-failover-made-easy-with-mysql-utilities

环境介绍:
master: demoenv-trial-1
slaves: demoenv-trial-2 demoenv-trial-3

1. 安装 Percona Server,在所有服务器上:
$ sudo yum install http://www.percona.com/downloads/percona-release/percona-release-0.0-1.x86_64.rpm
$ sudo yum install Percona-Server-shared-compat
$ sudo yum install Percona-Server-server-56

$ sudo yum install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
$ sudo yum install mysql-utilities

2. 配置 /etc/my.cnf,在所有服务器上:
注意:确保 server-id 不同且 report-host 与自身主机名相同
$ sudo vim /etc/my.cnf

[mysqld]
# basic setting
datadir = /opt/mysql/data
tmpdir = /opt/mysql/tmp
socket = /opt/mysql/run/mysqld.sock
port = 3306
pid-file = /opt/mysql/run/mysqld.pid

# innodb setting
default-storage-engine = INNODB
innodb_file_per_table = 1
log-bin = /opt/mysql/binlogs/bin-log-mysqld
log-bin-index = /opt/mysql/binlogs/bin-log-mysqld.index
innodb_data_home_dir = /opt/mysql/data
innodb_data_file_path = ibdata1:10M:autoextend
innodb_log_group_home_dir = /opt/mysql/data
binlog-do-db = testdb

# server id
server-id=1

# gtids setting
binlog-format = ROW
log-slave-updates = true
gtid-mode = on
enforce-gtid-consistency = true
report-host = demoenv-trial-1
report-port = 3306
master-info-repository = TABLE
relay-log-info-repository = TABLE
sync-master-info = 1

# other settings
[mysqld_safe]
log-error = /opt/mysql/log/mysqld.log
pid-file = /opt/mysql/run/mysqld.pid
open-files-limit = 8192

[mysqlhotcopy]
interactive-timeout

[client]
port = 3306
socket = /opt/mysql/run/mysqld.sock
default-character-set = utf8

3. 创建所需目录,在所有服务器上:
$ sudo mkdir -p /opt/mysql/{data,tmp,run,binlogs,log}
$ sudo chown mysql:mysql /opt/mysql/{data,tmp,run,binlogs,log}

4. 初始化数据库,在所有服务器上:
$ sudo -i
# su - mysql
$ mysql_install_db --user=mysql --datadir=/opt/mysql/data/
$ exit
# exit
$ sudo /etc/init.d/mysql start

5. 创建授权用户 root@'%' 以便通过 mysqlreplicate 来进行主从复制的配置,在所有服务器上:
$ mysql -uroot

mysql> grant all on *.* to root@'%' identified by 'pass' with grant option;
mysql> quit;

6. 创建复制所需的用户,在所有服务器上:
$ mysql -uroot

mysql> grant replication slave on *.* to 'rpl'@'%' identified by 'rpl';
mysql> quit;

7. 配置主从复制,可选择任意一台服务器操作:
[dong.guo@demoenv-trial-1 ~]$ mysql -uroot

mysql> use mysql;
mysql> drop user root@'demoenv-trial-1';
mysql> quit;

[dong.guo@demoenv-trial-1 ~]$ mysqlreplicate --master=root:pass@'demoenv-trial-1':3306 --slave=root:pass@'demoenv-trial-2':3306 --rpl-user=rpl:rpl

# master on demoenv-trial-1: ... connected.
# slave on demoenv-trial-2: ... connected.
# Checking for binary logging on master...
# set up replication...
# ...done.

阅读全文 »

, ,

No Comments

坑爹的nextgen-gallery插件导致MySQL binlog暴涨

我的Blog在优化过后,一直运行良好,速度也很快。可是从昨天开始突然就变得很卡,登陆到服务器上一看,我擦,磁盘空间占用率100%。仔细一看MySQL binlog占据了绝大部分空间,增长速度迅猛,每10分钟500M的节奏。

fuckedbyng1

这肯定不正常啊,我去。我平均每个月才更新1-3文章。而且前来评论的人也不多,就算是Spam也不会有这么大的量啊。为了找出到底是什么SQL的干活,我停掉了Nginx,然后登陆到mysql中,选定一个binlog文件,执行"mysql -uroot -p -e 'show binlog events in 'binlog.000041' limit 10;' > /tmp/fuckedbyng.log",然后就看到了不断重复的那个坑爹的SQL。

fuckedbyng2

通过这个SQL中的相关内容,Google到了问题的原因,那就是坑爹的刚刚更新过的nextgen-gellery插件的一个Bug。
http://wordpress.org/support/topic/a-warning-ngg_delete_expired_transients-cronjob

fuckedbyng3

在上面的论坛中,有人给出了解决方案,就是注释掉一部分更新后产生的新的相关代码。
因为我已经被激怒了,所以我首先按照以上方法修正了这个bug,再重新启动了我的Nginx,接着直接删除了这个坑爹的插件。其实我本身也不太用得上这个相册插件,呵呵。

, ,

2 Comments

使用参数innodb_file_per_table支持MySQL InnoDB表数据共享空间自动收缩

参考资料:
http://linuxfun.me/?p=1263

使用过MySQL的同学,刚开始接触最多的莫过于MyISAM表引擎了,这种引擎的数据库会分别创建三个文件:表结构、表索引、表数据空间。我们可以将某个数据库目录直接迁移到其他数据库也可以正常工作。
然而当你使用InnoDB的时候,一切都变了。InnoDB 默认会将所有的数据库InnoDB引擎的表数据存储在一个共享空间中:ibdata1,这样就感觉不爽,增删数据库的时候,ibdata1文件不会自动收缩,单个数据库的备份也将成为问题。通常只能将数据使用mysqldump 导出,然后再导入解决这个问题。
在MySQL的配置文件[mysqld]部分,增加innodb_file_per_table参数,可以修改InnoDB为独立表空间模式,每个数据库的每个表都会生成一个数据空间。

独立表空间
优点:
1.每个表都有自已独立的表空间。
2.每个表的数据和索引都会存在自已的表空间中。
3.可以实现单表在不同的数据库中移动。
4.空间可以回收(drop/truncate table方式操作表空间不能自动回收)
5.对于使用独立表空间的表,不管怎么删除,表空间的碎片不会太严重的影响性能,而且还有机会处理。

缺点:
单表增加比共享空间方式更大。

结论:
共享表空间在Insert操作上有一些优势,但在其它都没独立表空间表现好。
当启用独立表空间时,请合理调整一下 innodb_open_files 参数。

下面,就是一次针对线上Zabbix的MySQL数据库history历史记录过多导致ibdata1文件过大的实战解决步骤
1.查看文件大小
$ sudo cd /var/lib/mysql
$ ls -lh

 
total 14G
-rw-r--r-- 1 root root 0 Dec 1 14:31 debian-5.1.flag
-rw-rw---- 1 mysql mysql 5.0M Jan 17 21:31 ib_logfile0
-rw-rw---- 1 mysql mysql 5.0M Jan 17 21:29 ib_logfile1
-rw-rw---- 1 mysql mysql 14G Jan 17 21:31 ibdata1
drwx------ 2 mysql root 4.0K Dec 1 14:31 mysql
-rw-rw---- 1 root root 6 Dec 1 14:31 mysql_upgrade_info
drwx------ 2 mysql mysql 4.0K Jan 17 21:29 zabbix

共享表数据空间文件ibdata1大小已经达到了14G
阅读全文 »

, ,

No Comments

安装部署CloudStack 4.0企业私有云平台[原创分享]

参考资料
CloudStack Installation_Guide/installation.html
CloudStack Admin_guide/working-with-iso.html
CloudStack Admin_guide/creating-vms.html
CloudStack Admin_guide/create-templates-overview.html

目录结构
1. 什么是CloudStack
2. 宿主机的系统需求
3. 配置安装源
4. 安装Management Server
5. 安装配置KVM虚拟化Host主机
6. 用户界面
7. 配置Management Server
8. 创建Instance类型
9. 创建ISO安装源并创建Instance
10. 创建并定制Template
11. 通过定制的Template创建VM Instance
12. 其它优化设置

环境介绍
OS: Ubuntu Server 12.04.1 64-bit
Server:
10.6.203.10 cloudstack-server-1
- CloudStack Management Server
- CloudStack Agent
- NFS Server
- MySQL Server
注:CloudStack支持很好的分布式架构,上面 - 代表的所有角色都可以部署在不同的机器上,但在测试环境中因为条件有限我全部都部署到了一台机器上。

1. 什么是CloudStack
CloudStack是一个开源的具有高可用性及扩展性的云计算平台。
提到开源的云计算平台,相信大家首先想到的可能是OpenStack,目前国内的几家云计算平台如阿里云、盛大云以及新浪SAE貌似都基于OpenStack做了二次开发。
但使用过CloudStack之后,你会发现其实CloudStack更像是一个商业化过后的产品,有着非常好的用户界面,各个模块默认集成的很好,且安装与部署过程也相对容易一些。

事实上,CloudStack的前身是Cloud.com,后来被思杰收购。2011年7月,Citrix收购Cloud.com,将CloudStack 100%开源并交给Apache软件基金会管理。
同时,CloudStack已经有了许多商用客户,包括GoDaddy、英国电信、日本电报电话公司、塔塔集团、韩国电信等。

因此,CloudStack本身其实就是一个商业化过后的产品,然后在面对OpenStack等开源系统的巨大竞争压力的情况下选择了同样的开源。

目前Cloudstack支持管理大部分主流的hypervisors,如KVM,XenServer,VMware,Oracle VM,Xen等。
CloudStack具有商业软件所拥有的完善的用户权限管理,可以让用户构建一个安全的多租户云计算环境。
同时兼容Amazon AWS API 接口,可用来管理AWS的资源。
  
CloudStack的官方网址如下(目前还处于Apache基金会的孵化器中):
http://incubator.apache.org/cloudstack/

以下是CloudStack的系统架构,基本上与其他云计算平台相同:

2. 宿主机的系统需求
由于CloudStack 4.0 限定了libvirt版本 > 0.9.4,并在社区宣称所支持的OS为 CentOS/RHEL 6.2 以上或 Ubuntu Server 12.04。
因此,这里我们选择 Ubuntu Server 12.04.1 作为我们的操作系统。
官方下载地址:http://releases.ubuntu.com/precise/ubuntu-12.04.1-server-amd64.iso

另外,官方要求硬件至少满足以下条件:
1) 支持硬件虚拟化(Intel-VT 或 AMD-V)
2) 64位的x86 CPU
3) 4G内存
4) 36GB硬盘
5) 1张网卡

3. 配置安装源
配置国内的网易镜像源
$ sudo sed -i s/us.archive.ubuntu.com/mirrors.163.com/g /etc/apt/sources.list
$ sudo sed -i s/security.ubuntu.com/mirrors.163.com/g /etc/apt/sources.list

配置CloudStack官方源
$ sudo vim /etc/apt/sources.list.d/cloudstack.list
deb http://cloudstack.apt-get.eu/ubuntu precise 4.0

配置CloudStack官方源证书
$ wget -O - http://cloudstack.apt-get.eu/release.asc| sudo apt-key add -

更新系统的安装源
$ sudo apt-get update

4. 安装Management Server
4.1 准备好操作系统环境
查看主机名
$ hostname --fqdn
cloudstack-server-1

$ sudo vim /etc/hosts
添加以下记录
10.6.203.10 cloudstack-server-1

安装时间服务器
$ sudo apt-get install openntpd

4.2 下载安装 CloudStack Management Server 与 vhd-util
安装CloudStack Management Server
$ sudo apt-get install cloud-client
阅读全文 »

, , , , , ,

58 Comments

MySQL InnoDB 故障解决记录

这是一起生产环境的故障解决记录,出错的数据库属于Zabbix监控系统,而整个操作过程由公司的专职DBA完成并记录。

1. 故障表现:Mysqld 进程持续重启,大量的错误日志:
120906 7:29:43 InnoDB: Page checksum 4195361555, prior-to-4.0.14-form checksum 2124157186
InnoDB: stored checksum 3323954773, prior-to-4.0.14-form stored checksum 2124157186
InnoDB: Page lsn 54 139070759, low 4 bytes of lsn at page end 139070759
InnoDB: Page number (if stored to page already) 134634,
InnoDB: space id (if created with >= MySQL-4.1.1 and stored already) 0
InnoDB: Page may be an index page where index id is 0 89
InnoDB: (index "history_1" of table "zabbix"."history")
InnoDB: Database page corruption on disk or a failed
InnoDB: file read of page 134634.
InnoDB: You may have to recover from a backup.
InnoDB: It is also possible that your operating
InnoDB: system has corrupted its own file cache
InnoDB: and rebooting your computer removes the
InnoDB: error.
InnoDB: If the corrupt page is an index page
InnoDB: you can also try to fix the corruption
InnoDB: by dumping, dropping, and reimporting
InnoDB: the corrupt table. You can use CHECK
InnoDB: TABLE to scan your table for corruption.
InnoDB: See also http://dev.mysql.com/doc/refman/5.1/en/forcing-innodb-recovery.html
InnoDB: about forcing recovery.
InnoDB: Ending processing because of a corrupt database page.

2. 故障原因,这类情况一般有2种情况:
mysql 服务异常关闭和硬件磁盘损坏。Innodb 自检过程中checksum与退出时不一致便会去recover;
或者退出时buffer中flush到磁盘的任务未正常结束并update checksum。

3. 解决办法。首先确定出错的数据表。(index "history_1" of table "zabbix"."history")。按下面的顺序尝试。
A. 进入mysql,如果mysql持续报错,但mysqld线程稳定,使用check table,optmize table 进行修复,大部分情况是失败。无响应或者ERROR 2013 (HY000): Lost connection to MySQL server during query
B. mysqld 进程不断重启(由innodb引擎发起的重启),check 和optimize 几乎无法在一个重启周期内完成。在my.cnf文件增加innodb_force_recovery=1 保证进程稳定。

4. 数据的恢复。
Check table 和 Optmize 其实对innodb效果不明显,所以80%解决不了问题,数据恢复有2种情况:
A.表数据完整,但checksum不一致
a) 新建同结构表,engine=myisam
b) Insert into new select * from old
c) Alter table new type=innodb
d) Drop table old,rename table new to old
B.表数据丢失,这种一般是磁盘损坏,方法和上面一样,区别在于,需要去需找破坏点,找到损坏的数据页面范围,达到最小数据损失。在有主键id的情况下相对容易且损失数据更小。

5. 恢复后在配置文件中注释 innodb_force_recovery=1 ,并重启。

No Comments

一次由MySQL跨库操作所引发的主从复制中断

今天,所有MySQL从服务器上的主从复制都被异常中断了,登陆到其中一台上执行show slave status\G,发现如下错误:
--
Last_Error: Error 'Operation DROP USER failed for 'guest'@'localhost'' on query. Default database: 'work'. Query: 'drop user 'guest'@'localhost''
--
也就是说,是 drop user 'guest'@'localhost' 这条命令导致的,而这样的操作我们通常都只会在Master上进行,并且该操作应该只会影响到“mysql”这个系统数据库。之前这种操作进行了很多次,可为什么唯独这一次会出问题呢?
经过一番调查之后,最终找到了问题的根源,那就是,
“binlog-do-db, binlog-ignore-db, replicate-do-db, replicate-ignore-db” 这一类参数,并非想象中可靠!

通常,我们会以为只要设定了以上参数,MySQL的主从复制就会只对我们设定的数据库生效。但事实上,MySQL不是根据内容来判断的,而是很傻瓜的根据你执行了“use work”或在初始连接时指定的数据库来判断的。
而这次,我们在执行drop user之前,因为需要从“work”数据库select一些数据,就use work进入到了work数据库,而大家都知道在执行drop user的时候是不需要进入“mysql”这个系统数据库的,所以就直接执行了drop user,但因为MySQL的判断我们是在use work之后执行的,所以认为是针对“work”数据库的操作就同步了下去,而从服务上都是没有guest@localhost这样的用户的,所以就造成了错误,导致主从复制的中断。

因此,在有主从复制架构的MySQL服务器环境中,我们要尽量避免这样的跨库操作,确保是在执行了正确的use dbname之后再执行命令。

这类故障的恢复方案很简单,就是跳过这一条SQL。
--
stop slave;
set global sql_slave_skip_counter=1;
start slave;
show slave status\G
--

参考资料:
http://www.mysqlperformanceblog.com/2009/05/14/why-mysqls-binlog-do-db-option-is-dangerous/

2 Comments

MySQL 5.5.x 单机多实例配置实践

背景/需求:
在一台服务器上通过源码编译安装一个版本为5.5以上的MySQL数据库;
将所有配置文件与数据等均存放在/opt/mysql,便于今后实现快速迁移、整体备份和快速复制;
在同一个MySQL中运行两个实例,一个绑定在端口3306,另一个绑定在端口3307;
绑定在3306端口的实例,不开启binlog,数据存放在/opt/mysql/data;
绑定在3307端口的实例,开启binlog,数据存放在/opt/mysql/data2;
两个实例均采用InnoDB作为默认的存储引擎,字符编码采用UTF-8;
两个实例均采用相同的性能优化配置参数;

实践/方案:
在编译安装时,将数据库的配置文件my.cnf以及data目录等均指向到/opt/mysql目录;
通过mysqld_multi的方式来管理两个不同的实例,采用相同的配置文件共享性能优化配置参数;
在同一个配置文件中,利用[mysqld1]与[mysqld2]标签实现不同实例的差异化配置;

配置步骤:
一、编译安装MySQL
1.安装cmake
MySQL从5.5版本开始,通过./configure进行编译配置方式已经被取消,取而代之的是cmake工具。
因此,我们首先要在系统中源码编译安装cmake工具。
# wget http://www.cmake.org/files/v2.8/cmake-2.8.4.tar.gz

# tar zxvf cmake-2.8.4.tar.gz

# cd cmake-2.8.4

# ./configure
# make
# make install

2.确保以下所需系统软件包已经被安装
通过 rpm -qa | grep name 的方式验证以下软件包是否已全部安装。

gcc* gcc-c++* autoconf* automake* zlib* libxml* ncurses-devel* libgcrypt* libtool*

如果缺少相关的软件包,可通过yum -y install 的方式在线安装,或直接从系统安装光盘中找到并通过rpm -ivh 的方式安装。

3. 安装前的系统设置
建立mysql安装目录及数据存放目录
# mkdir /opt/mysql
# mkdir /opt/mysql/data

创建用户和用户组
# groupadd mysql
# useradd -g mysql mysql

赋予数据存放目录权限
# chown mysql:mysql -R /opt/mysql/data

4.开始编译安装 MySQL
通过http://www.mysql.com/downloads/mysql官方网址或国内的sohu镜像下载软件包,如目前最新的MySQL 5.5.20。
# wget http://mirrors.sohu.com/mysql/MySQL-5.5/mysql-5.5.20.tar.gz

# tar zxvf mysql-5.5.20.tar.gz

# cd mysql-5.5.20
# cmake -DCMAKE_INSTALL_PREFIX=/opt/mysql \
-DSYSCONFDIR=/opt/mysql/etc \
-DMYSQL_DATADIR=/opt/mysql/data \
-DMYSQL_TCP_PORT=3306 \
-DMYSQL_UNIX_ADDR=/tmp/mysqld.sock \
-DMYSQL_USER=mysql \
-DEXTRA_CHARSETS=all \
-DWITH_READLINE=1 \
-DWITH_SSL=system \
-DWITH_EMBEDDED_SERVER=1 \
-DENABLED_LOCAL_INFILE=1 \
-DWITH_INNOBASE_STORAGE_ENGINE=1

# make
# make install

在make与make install的时候可以看到进度百分比,感觉这一点要比configure方式要好。

二、创建支持多实例的配置文件
进入MySQL主目录
# cd /opt/mysql/

删除默认的data目录
# rm -rf data

创建需要的目录
# mkdir etc tmp run log binlogs data data2
# chown -R mysql:mysql tmp run log binlogs data data2

创建my.cnf配置文件
# vim etc/my.cnf

## This server may run 2+ separate instances
## So we use mysqld_multi to manage their services
[mysqld_multi]
mysqld = /opt/mysql/bin/mysqld_safe
mysqladmin = /opt/mysql/bin/mysqladmin
log = /opt/mysql/log/mysqld_multi.log
user = root ## Used for stopping the server via mysqladmin
#password = 

## This is the general purpose database
## The locations are default
# They are left in [mysqld] in case the server is started normally instead of by mysqld_multi
[mysqld1]
socket = /opt/mysql/run/mysqld.sock
port = 3306
pid-file = /opt/mysql/run/mysqld.pid
datadir = /opt/mysql/data
lc-messages-dir = /opt/mysql/share/english

## These support master - master replication
#auto-increment-increment = 4
#auto-increment-offset = 1  ## Since it is master 1
#log-bin = /opt/mysql/binlogs/bin-log-mysqld1
#log-bin-index = /opt/mysql/binlogs/bin-log-mysqld1.index
#binlog-do-db = ## Leave this blank if you want to control it on slave

## This is exlusively for mysqld2
## It is on 3307 with data directory /opt/mysqld/data2
[mysqld2]
socket = /opt/mysql/run/mysqld.sock2
port = 3307
pid-file = /opt/mysql/run/mysqld.pid2
datadir = /opt/mysql/data2
lc-messages-dir = /opt/mysql/share/english

## Disable DNS lookups
#skip-name-resolve

## These support master - slave replication
log-bin = /opt/mysql/binlogs/bin-log-mysqld2
log-bin-index = /opt/mysql/binlogs/bin-log-mysqld2.index
#binlog-do-db =  ## Leave this blank if you want to control it on slave

## Relay log settings
#relay-log = /opt/mysql/log/relay-log-mysqld2
#relay-log-index = /opt/mysql/log/relay-log-mysqld2.index
#relay-log-space-limit = 4G

## Slow query log settings
#log-slow-queries = /opt/mysql/log/slow-log-mysqld2
#long_query_time = 2
#log-queries-not-using-indexes

## The rest of the my.cnf is shared
## Here follows entries for some specific programs
## The MySQL server
[mysqld]
basedir = /opt/mysql
tmpdir = /opt/mysql/tmp
socket = /opt/mysql/run/mysqld.sock
port = 3306
pid-file = /opt/mysql/run/mysqld.pid
datadir = /opt/mysql/data
lc-messages-dir = /opt/mysql/share/english

skip-external-locking
key_buffer_size = 16K
max_allowed_packet = 64M
table_open_cache = 4
sort_buffer_size = 64K
read_buffer_size = 256K
read_rnd_buffer_size = 256K
net_buffer_length = 2K
thread_stack = 128K

## Increase the max connections
max_connections = 1024

## Increase the max connect errors
max_connect_errors = 10000

## Increase the connect timeout
connect_timeout = 10

## Decrease the timeout and increase the retrieves of replication
slave-net-timeout = 60
master-connect-retry = 10

## The expiration time for logs, including binlogs
expire_logs_days = 14

## Set the character as utf8
character-set-server = utf8
collation-server = utf8_unicode_ci

## This is usually only needed when setting up chained replication
#log-slave-updates

## Enable this to make replication more resilient against server crashes and restarts
## but can cause higher I/O on the server
#sync_binlog = 1

## The server id, should be unique in same network
server-id = 1

## Set this to force MySQL to use a particular engine/table-type for new tables
## This setting can still be overridden by specifying the engine explicitly
## in the CREATE TABLE statement
default-storage-engine = INNODB

## Enable Per Table Data for InnoDB to shrink ibdata1
innodb_file_per_table = 1

## Set the max size of each binlog file
max_binlog_size = 1024M

## Set the binlog format
binlog_format = ROW

## Uncomment the following if you are using InnoDB tables
#innodb_data_home_dir = /opt/mysql/data
#innodb_data_file_path = ibdata1:10M:autoextend
#innodb_log_group_home_dir = /opt/mysql/data
## You can set .._buffer_pool_size up to 50 - 80 % of RAM
## but beware of setting memory usage too high
innodb_buffer_pool_size = 16M
innodb_additional_mem_pool_size = 2M
## Set .._log_file_size to 25 % of buffer pool size
innodb_log_file_size = 5M
innodb_log_buffer_size = 8M
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50

[mysqldump]
quick
max_allowed_packet = 64M

[mysql]
no-auto-rehash

[myisamchk]
key_buffer_size = 8M
sort_buffer_size = 8M

[mysqlhotcopy]
interactive-timeout

[mysql.server]
user = mysql

[mysqld_safe]
log-error = /opt/mysql/log/mysqld.log
pid-file = /opt/mysql/run/mysqld.pid
open-files-limit = 8192

[client]
default-character-set = utf8

阅读全文 »

,

3 Comments

推荐一篇针对MySQL数据库缓存参数优化的文章

简朝阳以前是阿里巴巴的DBA,在MySQL方面非常厉害,著有《MySQL性能调优与架构设计》一书,这本书我也买了。
针对MySQL数据库性能优化中的缓存参数优化,我在博客上向他提出了能否提供一些具体的建议取值范围后,他根据自己多年的经验在文章中进行了详细的补充,非常值得我们参考。

文章链接:http://isky000.com/database/mysql-perfornamce-tuning-cache-parameter

下面是相关内容:
---
上面这几个参数是 MySQL 中为了减少磁盘物理IO而设计的主要参数,对 MySQL 的性能起到了至关重要的作用。
—EOF—
按照 mcsrainbow 朋友的要求,这里列一下根据以往经验得到的相关参数的建议值:
query_cache_type : 如果全部使用innodb存储引擎,建议为0,如果使用MyISAM 存储引擎,建议为2,同时在SQL语句中显式控制是否使用query cache;
query_cache_size: 根据 命中率(Qcache_hits/(Qcache_hits+Qcache_inserts)*100))进行调整,一般不建议太大,256MB可能已经差不多了,大型的配置型静态数据可适当调大;
binlog_cache_size: 一般环境2MB~4MB是一个合适的选择,事务较大且写入频繁的数据库环境可以适当调大,但不建议超过32MB;
key_buffer_size: 如果不使用MyISAM存储引擎,16MB足以,用来缓存一些系统表信息等。如果使用 MyISAM存储引擎,在内存允许的情况下,尽可能将所有索引放入内存,简单来说就是“越大越好”;
bulk_insert_buffer_size: 如果经常性的需要使用批量插入的特殊语句(上面有说明)来插入数据,可以适当调大该参数至16MB~32MB,不建议继续增大,默认8MB;
innodb_buffer_pool_size: 如果不使用InnoDB存储引擎,可以不用调整这个参数,如果需要使用,在内存允许的情况下,尽可能将所有的InnoDB数据文件存放如内存中,同样将但来说也是“越大越好”;
innodb_additional_mem_pool_size: 一般的数据库建议调整到8MB~16MB,如果表特别多,可以调整到32MB,可以根据error log中的信息判断是否需要增大;
innodb_log_buffer_size: 默认是1MB,系的如频繁的系统可适当增大至4MB~8MB。当然如上面介绍所说,这个参数实际上还和另外的flush参数相关。一般来说不建议超过32MB;
innodb_max_dirty_pages_pct: 根据以往的经验,重启恢复的数据如果要超过1GB的话,启动速度会比较慢,几乎难以接受,所以建议不大于 1GB/innodb_buffer_pool_size(GB)*100 这个值。当然,如果你能够忍受启动时间比较长,而且希望尽量减少内存至磁盘的flush,可以将这个值调整到90,但不建议超过90;

1 Comment