MySQL主从复制(读写分离)和集群的区别:
1、主从复制(读写分离):一般需要两台及以上数据库服务器即可(一台用于写入数据,一台用于同步主的数据并用于数据查询操作)。
局限性:
(1)配置好主从复制之后,同一张表,只能对一个服务器写操作。如果在从上执行了写操作,而之后主也操作了这张表,或导致主从不同步;据说可以配置成主主方式
(2)主数据库服务器宕机,需要手动将业务系统切换到从数据库服务器。无法做到高可用性(除非再通过部署keepalive做成高可用方案)。
2、集群是由N台数据库服务器组成,数据的写入和查询是随机到任意一台数据库服务器的,其他数据库服务器会自动同步数据库的操作。
任何一台数据库宕机,不会对整个集群造成大的影响。
局限性:我经过测试才知道目前mysql集群版本(MySQL Cluster)只能对NDB存储引擎的数据进行集群同步,如果是INNODB或其他的MySQL存储引擎是不行的。这个也导致了我放弃了在业务系统中应用这种方案。
######################接下来开始MySQL5.6.12的主从复制教程:
1、MySQL5.6开始主从复制有两种方式:基于日志(binlog);基于GTID(全局事务标示符)。
需要注意的是:GTID方式不支持临时表!所以如果你的业务系统要用到临时表的话就不要考虑这种方式了,至少目前最新版本MySQL5.6.12的GTID复制还是不支持临时表的。
所以此篇教程主要是告诉大家如何通过日志(binlog)方式做主从复制!
2、MySQL官方提供的MySQL Replication教程:
http://dev.mysql.com/doc/refman/5.6/en/replication.html
这个官方教程强烈建议大家阅读(需要一定的英语阅读能力哦!不行就google翻译后再阅读吧~)。
3、准备工作:
(1)配置MySQL主从复制(读写分离)之前,需要在主从两台服务器先安装好MySQL5.6。
(2)目前最新的MySQL5.6 GA版本是MySQL5.6.12(点此下载MySQL5.6.12源码包)。
个人推荐Linux(RedHat/CentOS 6.4)源码编译安装,具体可以看本站这篇教程:RedHat/CentOS源码编译安装MySQL5.6.12
(3)注意:
(a)如果你需要用于生产环境,安教程安装MySQL时不要急着做mysql启动操作。建议把mysql初始化生成的/usr/local/mysql/mysql.cnf删除,然后把你优化好的mysql配置文件my.cnf放到/etc下。
(b)建议主备两台服务器在同一局域网,主备两台数据库网络需要互通。
(4)我的环境:
主数据库IP:192.168.100.2
从数据库IP:192.168.100.3
4、修改主数据库的的配置文件:
[mysqld]
server-id=1
log-bin=mysqlmaster-bin.log
sync_binlog=1
#注意:下面这个参数需要修改为服务器内存的70%左右
innodb_buffer_pool_size = 512M
innodb_flush_log_at_trx_commit=1
sql_mode=STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_AUTO_VALUE_ON_ZERO
lower_case_table_names=1
log_bin_trust_function_creators=1
修改之后要重启mysql: /etc/init.d/mysql restart
--------------------------------------------------------
优化后的配置文件master-my.cnf
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html
[client]
port=3306
socket=/usr/local/mysql/mysql.sock
default-character-set=utf8
[mysqld]
sync_binlog=1
server-id=1
port=3306
socket=/usr/local/mysql/mysql.sock
pid-file=/home/mysql/temp/my3306.pid
user=mysql
datadir=/home/mysql/data
tmpdir=/home/mysql/temp/
log-bin=/home/mysql/data/mysqlmaster-bin
log-error=/home/mysql/logs/error.log
slow_query_log_file=/home/mysql/logs/slow.log
binlog_format=mixed
slow_query_log
long_query_time=10
wait_timeout=31536000
interactive_timeout=31536000
max_connections=500
max_user_connections=490
max_connect_errors=2
character_set_server=utf8
skip-external-locking
key_buffer_size = 128M
max_allowed_packet = 5M
table_open_cache = 512
sort_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size = 32M
# Try number of CPU‘s*2 for thread_concurrency
thread_concurrency = 4
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
replicate_ignore_db=mysql
replicate_ignore_db=information_schema
expire-logs-days=10
skip-slave-start
skip-name-resolve
lower_case_table_names=1
log_bin_trust_function_creators=1
# InnoDB
innodb_data_home_dir=/home/mysql/data
innodb_log_group_home_dir=/home/mysql/logs
innodb_data_file_path=ibdata1:128M:autoextend
innodb_buffer_pool_size=2G
innodb_log_file_size=10M
innodb_log_buffer_size=8M
innodb_lock_wait_timeout=50
innodb_file_per_table
innodb_flush_log_at_trx_commit=1
#sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
sql_mode=STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_AUTO_VALUE_ON_ZERO
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 256K
sort_buffer_size = 256K
read_buffer = 256K
write_buffer = 256K
[mysqlhotcopy]
interactive-timeout
------------------------------------------------
5、修改从数据库的的配置文件(server-id配置为大于1的数字即可):
[mysqld]
server-id=2
log-bin=mysqlslave-bin.log
sync_binlog=1
#注意:下面这个参数需要修改为服务器内存的70%左右
innodb_buffer_pool_size = 512M
innodb_flush_log_at_trx_commit=1
sql_mode=STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_AUTO_VALUE_ON_ZERO
lower_case_table_names=1
log_bin_trust_function_creators=1
修改之后要重启mysql:/etc/init.d/mysql restart
优化过的从数据库配置文件:slave-my.cnf
# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.6/en/server-configuration-defaults.html
[client]
port=3306
socket=/usr/local/mysql/mysql.sock
default-character-set=utf8
[mysqld]
sync_binlog=1
server-id=2
port=3306
socket=/usr/local/mysql/mysql.sock
pid-file=/home/mysql/temp/my3306.pid
user=mysql
datadir=/home/mysql/data
tmpdir=/home/mysql/temp/
log-bin=/home/mysql/data/mysqlslave-bin
log-error=/home/mysql/logs/error.log
slow_query_log_file=/home/mysql/logs/slow.log
binlog_format=mixed
slow_query_log
long_query_time=10
wait_timeout=31536000
interactive_timeout=31536000
max_connections=500
max_user_connections=490
max_connect_errors=2
character_set_server=utf8
skip-external-locking
key_buffer_size = 128M
max_allowed_packet = 5M
table_open_cache = 512
sort_buffer_size = 2M
read_buffer_size = 2M
read_rnd_buffer_size = 8M
myisam_sort_buffer_size = 64M
thread_cache_size = 8
query_cache_size = 32M
# Try number of CPU‘s*2 for thread_concurrency
thread_concurrency = 4
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
replicate_ignore_db=mysql
replicate_ignore_db=information_schema
expire-logs-days=10
#skip-slave-start
skip-name-resolve
lower_case_table_names=1
log_bin_trust_function_creators=1
# InnoDB
innodb_data_home_dir=/home/mysql/data
innodb_log_group_home_dir=/home/mysql/logs
innodb_data_file_path=ibdata1:128M:autoextend
innodb_buffer_pool_size=2G
innodb_log_file_size=10M
innodb_log_buffer_size=8M
innodb_lock_wait_timeout=50
innodb_file_per_table
innodb_flush_log_at_trx_commit=1
#sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
sql_mode=STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_AUTO_VALUE_ON_ZERO
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 256K
sort_buffer_size = 256K
read_buffer = 256K
write_buffer = 256K
[mysqlhotcopy]
interactive-timeout
6、SSH登录到主数据库:
(1)在主数据库上创建用于主从复制的账户(192.168.100.3换成你的从数据库IP):
mysql -uroot -p
mysql>
GRANT REPLICATION SLAVE ON *.* TO ‘repl‘@‘192.168.100.3‘ IDENTIFIED BY ‘repl‘;
(2)主数据库锁表(禁止再插入数据以获取主数据库的的二进制日志坐标):
mysql>
FLUSH TABLES WITH READ LOCK;
(3)然后克隆一个SSH会话窗口,在这个窗口打开MySQL命令行:
mysql -uroot -p
mysql>
SHOW MASTER STATUS;
+------------------------+----------+--------------+------------------+-------------------+
|
File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------------+----------+--------------+------------------+-------------------+
|
mysqlmaster-bin.000001 | 332 | | | |
+------------------------+----------+--------------+------------------+-------------------+
row in set (0.00 sec)
mysql>
exit;
在这个例子中,二进制日志文件是mysqlmaster-bin.000001,位置是332,记录下这两个值,稍后要用到。
(4)在主数据库上使用mysqldump命令创建一个数据快照:
mysqldump -uroot -p -h127.0.0.1 -P3306 --all-databases --triggers --routines --events >all.sql
接下来会提示你输入mysql数据库的root密码,输入完成后,如果当前数据库不大,很快就能导出完成。
(5)解锁第(2)步主数据的锁表操作:
mysql>
UNLOCK TABLES;
7、SSH登录到从数据库:
(1)通过FTP、SFTP或其他方式,将上一步备份的主数据库快照all.sql上传到从数据库某个路径,例如我放在了/home/yimiju/目录下;
(2)从导入主的快照:
cd /home/yimiju
mysql -uroot -p -h127.0.0.1 -P3306 < all.sql
接下来会提示你输入mysql数据库的root密码,输入完成后,如果当前数据库不大,很快就能导入完成。
(3)给从数据库设置复制的主数据库信息(注意修改MASTER_LOG_FILE和MASTER_LOG_POS的值):
mysql -uroot -p
mysql>
CHANGE MASTER TO MASTER_HOST=‘192.168.100.2‘,MASTER_USER=‘repl‘,MASTER_PASSWORD=‘repl‘,MASTER_LOG_FILE=‘mysqlmaster-bin.000001‘,MASTER_LOG_POS=332;
#
然后启动从数据库的复制线程:
mysql>
START slave;
接着查询数据库的slave状态:
mysql>
SHOW slave STATUS \G
如果下面两个参数都是Yes,则说明主从配置成功!
Slave_IO_Running:
Yes
Slave_SQL_Running:
Yes
(4)接下来你可以在主数据库上创建数据库、表、插入数据,然后看从数据库是否同步了这些操作。
#########################CentOS 6.3下MySQL主主互备架构配置#############################
MySQL主主互备结构是基于mysql增量日志基础上的,区别于主从复制结构.
在主主复制结构中,两台服务器的任何一台上面的数据库存发生了改变都会同步到另一台服务器上,这个改变是基于sql语句的改变,如果删除系统数据库源文件或删除后新创建同名MYSQL表实现同步则无效。这样两台服务器互为主从,并且都能向外提供服务,这就比使用主从复制具有更好的性能.
接下来我将使用两个相同的环境来实现这个效果:
系统环境:CentOS6.3
数据库: mysql-5.6.10
安装配置mysql(略)
1.主1 mysql配置:(192.168.7.201)
删除之前遗留bin日志
# rm -rf /usr/local/mysql/log/bin*
修改mysql配置文件:
# vi /etc/my.cnf
添加:
-----------------
# Replication Master Server 1
# bin日志路径
log-bin = /usr/local/mysql/log/bin.log
# 服务器ID号
server-id = 1
# 忽略mysql数据库复制
binlog-ignore-db=mysql
# 每次增长2
auto-increment-increment = 2
# 设置自动增长的字段的偏移量,即初始值为2
auto-increment-offset = 1
------------
# mysql -u root -p123456
在主1上为主2添加同步帐号
> grant replication slave on *.* to ‘slave‘@‘192.168.7.249‘ identified by ‘123456‘;
将主1的数据库表全部备份,并发送到主2服务器上。
# /usr/local/mysql/bin/mysqldump -u root -p123456 --opt --skip-lock-tables --flush-logs --all-database > /root/allbak.sql
# cd ~
# scp allbak.sql [email protected]:/root
重启服务
# service mysqld restart
# mysql -u root -p123456;
配置连接到主2服务器(注意这步一定要在主2添加账户后执行)
> stop slave;
> change master to master_host=‘192.168.7.249‘,master_user=‘slave‘,master_password=‘123456‘;
> start slave;
2.主2 mysql配置(192.168.7.249)
删除之前遗留bin日志
# rm -rf /usr/local/mysql/log/bin*
修改mysql配置文件:
# vi /etc/my.cnf
添加:
--------------------
# Replication Master Server 2
# bin日志路径
log-bin = /usr/local/mysql/log/bin.log
server-id=2
# 忽略mysql数据库复制
replicate-ignore-db=mysql
# 每次增长2
auto-increment-increment = 2
# 设置自动增长的字段的偏移量,即初始值为2
auto-increment-offset = 2
---------------------
# mysql -u root -p123456
在主2上为主1添加同步帐号
> grant replication slave on *.* to ‘slave‘@‘192.168.7.201‘ identified by ‘123456‘;
恢复主1的数据库到主2
#/usr/local/mysql/bin/mysql -u root -p123456 < /root/allbak.sql
重启服务
# service mysqld restart
# mysql -u root -p123456;
配置连接到主1服务器
> stop slave;
> change master to master_host=‘192.168.7.201‘,master_user=‘slave‘,master_password=‘123456‘;
> start slave;
最后分别登陆两台服务器mysql后台查看主主备份连接状态
# mysql -u root -p123456;
> show slave status\G;
搜索这三行,如下则主主互备配置成功
Slave_IO_State: Waiting for master to send event
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
当主1的数据库增加,删除,改变数据时,主2也会同步更新。
当主2的数据库增加,删除,改变数据时,主1也会同步更新。
这样就可以配合keepalived实现数据库双机热备+数据同步互备,大大提高了MYSQL的可靠性和安全性。
这里介绍如何配合前者实现Keepalived双机热备
系统环境:CentOS 6.3 x64
MySQL版本:mysql-5.6.10
Keepalived版本:keepalived-1.2.7
MySQL-VIP:192.168.7.253
MySQL-master1:192.168.7.201
MySQL-master2:192.168.7.249
1.在MySQL-master1:192.168.7.201服务器上keepalived安装及配置
编译安装,实际以本机kernel版本为准
# wget http://www.keepalived.org/software/keepalived-1.2.7.tar.gz
# tar zxvf keepalived-1.2.7.tar.gz
# cd keepalived-1.2.7
# ./configure --prefix=/usr/local/keepalived --with-kernel-dir=/usr/src/kernels/2.6.32-
279.el6.x86_64
# make && make install
新建一个配置文件,默认keepalived启动会去/etc/keepalived目录下寻找配置文件
# mkdir /etc/keepalived
# vi /etc/keepalived/keepalived.conf
------------------
global_defs {
notification_email {
[email protected]
}
notification_email_from [email protected]
smtp_server stmp.126.com
smtp_connect_timeout 30
router_id MySQL-ha
}
vrrp_instance VI_1{
# 两台配置此处均是BACKUP
state BACKUP
# 注意网卡接口
interface eth0
virtual_router_id 51
# 优先级,另一台改为90
priority 100
advert_int 1
# 不主动抢占资源
nopreempt
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.7.253
}
}
virtual_server 192.168.7.253 3306 {
# 每个2秒检查一次real_server状态
delay_loop 2
# LVS算法
lb_algo wrr
# LVS模式
lb_kind DR
# 会话保持时间
persistence_timeout 60
protocol TCP
real_server 192.168.7.201 3306 {
weight 3
# 检测到服务down后执行的脚本
notify_down /etc/rc.d/keepalived.sh
TCP_CHECK {
# 连接超时时间
connect_timeout 10
# 重连次数
nb_get_retry 3
# 重连间隔时间
delay_before_retry 3
# 健康检查端口
connect_port 3306
}
}
----------------------
编写检测服务down后所要执行的脚本
# vi /etc/rc.d/keepalived.sh
-------------
#!/bin/sh
pkill keepalived
-------------
# chmod +x /etc/rc.d/keepalived.sh
注:此脚本是上面配置文件notify_down选项所用到的,keepalived使用notify_down选项来检查real_server的服务状态。
当发现real_server服务故障时,便触发此脚本.
我们可以看到,脚本就一个命令:
通过pkill keepalived强制杀死keepalived进程,从而实现了MySQL故障自动转移.
另外,我们不用担心两个MySQL会同时提供数据更新操作,因为每台MySQL上的keepalived的配置里面只有本机MySQL的IP+VIP,而不是两台MySQL的IP+VIP.
启动keepalived
# /usr/local/keepalived/sbin/keepalived -D
查看连接状态
# ps -aux | grep keepalived
返回:
---------------
root 25348 0.0 0.0 36792 720 ? Ss 07:15 0:00
/usr/local/keepalived/sbin/keepalived -D
root 25349 0.5 0.1 40968 2016 ? S 07:15 0:00
/usr/local/keepalived/sbin/keepalived -D
root 25350 0.0 0.1 40968 1340 ? S 07:15 0:00
/usr/local/keepalived/sbin/keepalived -D
--------------------
测试
找一台局域网PC,然后去ping MySQL的VIP,这时候MySQL的VIP是可以ping的通的
停止MySQL服务,看keepalived健康检查程序是否会触发我们编写的脚本,去kill掉keepalived进程
# service mysqld stop
# ps -aux | grep keepalived