MySQL主从复制
理论基础
主从复制的作用
分摊负载,scale out
备份方便(停掉一台从库,直接进行备份即可),冷备份,可保证数据的一致性
主服务器宕机后,可将从服务器提升为主服务器(由只读+relay log变为 可读写+binlog)
完全同步
异地容灾
mysql复制
在主数据库MASTER上,每次执行sql引起数据库的变化,会将sql写到数据文件里,同时也会写到二进制日志中保存为一个事件,主数据库服务器将二进制日志中的事件,实时通过服务器将事件传给[从服务器SLAVE],保存为二进制日志文件(中继日志-relay log),每次从日志文件中读取一个事件,执行一次,将结果保存在数据库中
其中涉及到从服务器的两个线程:
IO_Thread:负责向主服务器二进制日志中按顺序读取事件,并将时间写到从服务器的中继日志(relay log)中
SQL_Thread:从中继日志中按顺序读取事件并将其写到从数据库中
复制模式:
异步(默认模式):
半同步
同步:完全实时同步
- mysql日志类型
日志类型:
二进制日志:前端对数据库的操作,每次可能引起数据库的变化的操作或语句,存到二进制日志中作为一个事件
数据目录
mysql-bin-xxxxxx
滚动:达到最大上线、flush logs、服务器重启
清除二进制日志:mysql>purge binary logs to 'mysql-bin.000011'
记录:二进制event事件,
格式:
根据语句:statement
根据行:row
混合:mixed
mysql-bin-index:二进制文件索引文件
mysql>show master status
mysql>show binary logs 查看二进制文件列表
mysql>show binlog events in "file"
event:
timestamp
position,offset,serverID
即时点还原:
mysql:事务可以并行,但二进制文件只有一个,事件串行写入二进制日志中,次序可能不相同
事务日志
错误日志
一般查询日志
中继日志
慢查询日志
mysql隔离级别
READ-UNCOMMITTED+row
READ-COMMITTED
REPEATABLE-READ(默认)+statement可能会导致二进制日志与原数据不一致SERIALIZABLE
lamp:PHP
[架构中,不使用mysql代理,如何让主负责写,从负责读?]
双主:无法减轻写操作
容易数据混乱(同时修改一行数据的不同字段)
tid增长不一致:
1、3、5、7
2、4
scale out:
垂直拆分:分库:按表拆分(没有关系的表),垂直拆分
水平拆分:分表,将表中的数据按tid拆分
读写分离:
mysql proxy
amoeba(java)
数据拆分:
cobar(java)
scale on:
一主多从
1—N
一从只能属于一个主
- 配置mysql复制基本步骤
master
启用二进制日志
log-bin = master-bin
log-bin-index = master-bin.index
选择一个唯一的serverID
server-id = {0-2^32}
创建具有复制权限的用户
REPLICATION SLAVE
REPLICATION CLIENT
salve
启用中继日志
relay-log = relay-log
relay-log-index =
选择一个唯一的serverID
server-id = {0-2^32}
连接至主服务器,并开始复制数据:
mysql>change master to master_host='',master_port=',master_log_file=',master_log_file_pos='',master_user='',master_password=''
mysql>start slave;(同时启动 IO/SQL)
mysql>start slave IO_Thread
mysql>start slave SQL_Thread
复制线程:
master:dump
slave:IO_Thread,SQL_thread
半同步:设置超时时间
- 具体部署方式
部署完成mysql后,均需创建mysql用户mysql组,数据目录:/data/mysql
chown -R mysql.mysql /data/mysql/
主:
编辑配置文件:/etc/my.conf
[mysqld]
datadir=/data/mysql
log-bin=master-bin
log-bin-index=master-bin.index
binlog_format=mixed
server-id:1-2^32-1
innodb_file_per_table = 1
编辑/etc/profiel.d/mysql.sh
export PATH=$PATH:/usr/local/mysql/bin
mysql>grant REPLICATION SLAVE ON *.* TO 'REPLUSER'@'192.168.25.%' IDENTIFOED BY 'PASSWORD';
mysql>flush privileges;
mysql>show master status;
从:
编辑配置文件:/etc/my.conf
无需启动log-bin
[mysqld]
relay-log = relay-log
relay-log-index = relay-log.index
server-id =
read-only = ON 从服务器设置只读 但不限定具有super权限的用户
编辑/etc/profiel.d/mysql.sh
export PATH=$PATH:/usr/local/mysql/bin
执行 ./etc/profiel.d/mysql.sh
mysql>change master to master_host='192.168.25.144',master_user='slave',master_password='slave',master_log_file='master.000005',master_log_pos=154;
此后重启服务,slave仍旧会自动启动
mysql>show slave status\G
mysql>start slave;
或
mysql>start slave IO_Thread
mysql>start slave SQL_Thread
mysql>show GLOABLE VARIABLES LIKE 'read%'';
存储master信息
/etc/mysql/master.info
二进制日志包含缓存区,当二进制日志缓存区未保存到二进制日志,主崩溃,此时,需要配置主服务器同步二进制日志,
主服务器设定:
sync-binlog
用于事务安全,当其值为N是,即表示,在执行N次事务后才会与硬盘同步,N=1时,意味着 没执行一次,就与硬盘同步一次,此时即使主服务器故障,从服务器与主服务器只差一次事务;当N=0时,即使将是否同步的选择权交给文件系统,此时当binlog_cache满了之后才会同步,这样就比较危险,当文件系统或住服务故障时,从服务器与主服务器相比丢失了大量数据。主服务器可以将此项设置为1(为保证数据安全),从服务器则可以将此项设置为0(为尽可能降低主从延时)
innodb_flush_log_at_trx_commit
默认值1的意思是每一次事务提交或事务外的指令都需要把日志写入(flush)硬盘,这是很费时的。特别是使用电池供电缓存(Battery backed up cache)时。设成2对于很多运用,特别是从MyISAM表转过来的是可以的,它的意思是不写入硬盘而是写入系统缓存。日志仍然会每秒flush到硬 盘,所以你一般不会丢失超过1-2秒的更新。设成0会更快一点,但安全方面比较差,即使MySQL挂了也可能会丢失事务的数据。而值2只会在整个操作系统 挂了时才可能丢数据。
从服务器:
当主服务器执行了某些错误操作但从服务器不需要同步此信息,此时,从服务器复制线程不需要立即启动
- skip-slave-start=1
或者临时切换 master.info 到其他目录
从服务器的信息 记录在 /data/mysql/的错误日志
[error]
在进行从服务器启动主从配置是,一定要先看 master的二进制文件、POS
mysql> show master status;
+——————-+———-+————–+——————+——————-+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+——————-+———-+————–+——————+——————-+
| master-bin.000005 | 313 | | | |
+——————-+———-+————–+——————+——————-+
1 row in set (0.00 sec)
然后在从库执行
mysql>change master to master_host='192.168.25.144', master_user='slave',master_password='slave',master_log_file='master-bin.000005',master_log_pos=313;
半同步复制:
主:
安装插件:/usr/local/mysql/lib/plugins/ rpl_semi_sync_master
mysql>INSTALL PLUGIN rpl_semi_sync_master SONMAE 'semisync_master.so';
mysql>show gloable variables like '%rpl%';
mysql>set GLOABLE rpl_semi_sync_master_enabled=1
从:
安装插件:/usr/local/mysql/lib/plugins/ rpl_semi_sync_slave
mysql>INSTALL PLUGIN rpl_semi_sync_slave SONMAE 'semisync_master.so';
mysql>show gloable variables like '%rpl%';
mysql>set GLOABLE rpl_semi_sync_slave_enabled=1
需要重新链接从服务器 IO_tHread:
mysql>stop IO_tHread;
mysql>start IO_tHread;
mysql> SHOW slave STATUS\G
主从延时判断工具
原因:
1、网络问题
2、主从服务器性能不一致
3、从服务器的SQL_Thread与其上的读命令争用资源导致lock
4、主服务器负载过高,IO_Thread读取二进制日志太慢,而SQL_Thread与IO_Thread执行速度一致
判断方法:
Seconds_behind_master:
(有可能不准确,如遇到以上4)
优化方式:
sync-binlog参数调整
mk-heatbeat:
原理:当主从服务器使用同一时区,在主从服务区中创建一个数据表,带时间戳,按一定时间向表中插入一条数据,每条数据都有时间戳,通过对比主从中此表上的时间戳即可得出主从延时时间。