标签:art inotify list 个数 send ash 定位 授权 允许
一、普通文件的数据同步
NFS网络文件共享可以同步存储数据(挂载到新服务器);
samba共享数据 (http://taokey.blog.51cto.com/4633273/1203553);
定时任务或守护进程结合rsync,scp;
inotify(sersync)+rsync触发式实时数据同步;
ftp 数据同步;
ssh key+scp/rsync;
数据库同步方案:
自身同步机制——mysql replication,mysql主从复制(逻辑的SQL从写);oracle dataguard(物理的磁盘块,逻辑的SQL语句从写)
第三方drbd,参考http://oldboy.blog.51cto.com/2561410/1240412
两个服务器同时写数据,就是一种复制机制。
二、mysql主从复制架构
主从同步(一主一从,一主两从。。)
主主同步
线性级联单项双主同步(主-主-从)
环状级联单向多主同步
环状级联单向多主多从同步(主主构成环状,每个主再附加从)
mysql主从同步都是异步同步的方式。
主从可能存在不一致,可以采取以下方法尽量保证一致:
1)找一台从库只做备份用,主库能起来,把主库的binlog拉到从库,把宕机一瞬间主库上的写能恢复到从库
2)双写可以相对保证数据一致
3)通过应用程序写一个短时间的日志,只记录宕机一瞬间发生的事放在内存里
4)把异步同步换成实时同步,mysql有个Google开发的半同步的插件,要求如果在主上写,主成功,且某一个半同步的从成功,才算真正的成功
三、主从同步作用
主从服务器互为备份(实时备份)
主从服务器读写分离分担网站压力(主库写,从库读,对于读多写少的,再把从库横向扩展,推荐用程序实现读写分离,小公司会用proxy、Amoeba实现,门户网站会开发dbproxy实现)
分布式dbproxy(读写分离,hash负载均衡,健康检查) ——有难度!
根据服务器拆分业务,独立分担压力
四、mysql主从同步的原理
主库由一个线程完成主从同步——IO线程;
从库由两个线程完成主从同步——SQL线程和IO线程;
要实现主从同步,主库必须开启binlog;
当用户执行增删改的请求时,数据会写到数据文件中,把更新的结果写到binlog中;
主从同步是从库找主库,在change master的点之前,需把主库的数据都给到从库,从库中change master去配置连到主库:包括master_host,master_user,master_password,master_port,master_log_file,master_log_pos等(# change master to master_log_file=‘mysql-bin.000020‘,master_log_pos=1191;);
配置完成后,需创建同步的账号,需在从库上打开start slave的开关,开启同步;
开启同步后,从库向主库的mysql主进程发出请求,主库通过验证用户名、IP地址、端口、密码等判断是否允许连接,然后交给主库的IO处理,主库IO收到从哪个位置点同步,给从库发binlog,从库收到log日志后将其写入relay-log,称为中继日志,并把最后得到的日志及位置点记录master info,这样再次向主库提取log时,接着上次的位置点向主库索要,以便告诉master服务器从哪个文件开始读。IO把binlog放入中继日志之后就不管了,由从库的SQL实时的读中继日志,然后及时的把log文件中的内容解析成在master端曾经执行的SQL语句的内容,并在自身slave服务器上按语句的顺序执行应用这些SQL语句,存放在数据文件中,应用完毕后清理应用过的日志,因此这个主从同步是异步的。
官方版图:
五、实战
可以选择一个服务器上两个mysql实例来模拟:
主库 master 3306
从库 slave 3307
1)确保主库的log-bin,server-id开启,log-bin可指定路径,如:/data/3306/mysql-bin
上述两个参数要放在my.cnf的【mysqld】模块下,否则会出错;
从库的log-bin可开可不开,server-id主从要不一样!
(补充:从库需要开启binlog的情况:
1.当前从库作为其他从库的主库,即级联同步;
2.把从库作为数据库备份服务器时;
在从库的my.cnf中做以下步骤:
1.打开log-bin
2.添加参数:log-slave-updates
3.expire_logs_days=7 #binlog保留时间设置)
确认log-bin开启,一是可以ll /data/3306/看是否有mysql-bin文件,二是可以进库查看:mysql -uroot -p456 -S /data/3306/mysql.sock -e "show variables like ‘log_bin‘ ;"
2)在主库上建立用于从库复制的账号rep
mysql> grant replication slave on *. * to ‘rep‘@‘10.0.0.%‘ indentified by ‘oldboy123‘;
mysql> flush privileges;
3)在主库上做备份
mysql> flush table with read lock;
mysql> show master status; #拿到备份的位置点(这里为333)
重新开一个窗口备份数据,保持当前窗口不断
mysqldump -uroot -p456 -S /data/3306/mysql.sock -A -B --events|gzip >/opt/rep.sql.gz
或mysqldump -uroot -p456 -S /data/3306/mysql.sock -A -B --events --master-data=2 >/opt/rep.sql.gz #也能拿到备份的起始位置点
再回到原来窗口,看看bin-log有没有变,确保主库是锁住了的
mysql> show master logs;
mysql> show master status;
mysql> unlock tables;
将主库备份同步到从库:
mysql -uroot -p456 -S /data/3307/mysql.sock </opt/rep.sql.gz
4)建立主从复制:
登录到从库:
mysql -uroot -p456 -S /data/3307/mysql.sock
mysql> CHANGE MASTER TO
MASTER_HOST=‘主库IP‘,
MASTER_PORT=3306,
MASTER_USER=‘rep‘,
MASTER_PASSWORD=‘oldboy123‘,
MASTER_LOG_FILE=‘mysql-bin.000003‘,
MASTER_LOG_POS=333;
#如果master-data指定=1,则上述最后两步可省略,自动找到位置,相当于利用mysqldump在半夜做一次全备数据并恢复到从库
上面的内容会放在从库的master.info里,可以查看:cd /data/3307/ cd data cat master.info
mysql> start slave;
mysql> show slave status\G #看IO,SQL两个线程是否都正常工作
5)验证主从同步:
在主库上建立一个新的database:
mysql> show databases;
mysql> create database oldboy;
mysql> show databases;
换从库:
mysql> show databases;
在relay-log中查看是否有‘create database oldboy’,应该是有的
relay-bin.index记录了relay-log更新到哪了
relay-log.info记录了SQL读到relay-log的位置,和IO取log即master,info中截止的位置
至此,模拟一次主从同步完成了。
六、mysql主从复制常见问题
1)show master status时没有位置点
查看bin-log有没有打开;
2)Last_IO_Error:Got fatal errror 1236 from master when reading data from binary log:‘Counld not find first log file name in binary log index file‘
查看change master 配置时,MASTER_LOG_FILE指定的文件是否多了空格;
3)flush tables with read lock无法锁表
5.1的锁表是tables,5.5是table,mysql不同版本不一样;
另外,锁表命令的时间会受到两个参数的控制,如果超过设置时间不操作会自动解锁:interactive_timeout = 60、wait_timeout = 60;
show variables like ‘%timeout%‘;
4)服务无法正常启动故障
mysql意外关闭,杀了mysql进程后,启动mysql仍然显示mysql is running
ps -ef|grep mysqld
killall mysqld
chkconfig mysqld off
ps -ef|grep mysqld
/data/3306/mysql start >>>>显示mysql is running...
这是由于启动脚本中的相应配置导致,此时需将之前启动产生的文件删除:rm -f /data/3306/mysql.sock /data/3306/*.pid
/data/3306/mysql start >>>>显示Starting mysql...
5)由于切换binlog导致show master status位置变化无影响;
6)从库IO同步正常,但SQL同步异常显示为NO
比如在从库先创建个数据库butongbu,然后再在主库上创建个butongbu,这时看从库会发现报错
解决方法1:stop slave; set global sql_slave_skip_counter=1; start slave;即让slave跳过一步。
解决方法2:根据错误号跳过指定的错误,每个错误号都有不同的含义。在配置文件中添加slave-skip-errors=1032,1062,1007;一般由于入库重复的失败就可以忽略。
七、主从复制原理总结
异步方式同步;
逻辑同步模式,多种模式,默认是通过SQL语句执行(主从不能保证完全一致);
主库通过记录binlog实现对从库的同步,binlog记录数据库的更新语句;
主库1个IO线程,从库由1个IO线程和1个SQL线程完成的;
从库关键文件master info,relay-log,relay-info等的功能;
如果从库还想级联从库,需要打开从库的log-bin和log-slave-updates参数。
八、查看复制线程状态
show processlists可以分别在主库、从库上查看主从复制线程状态,从而判断数据库同步是否完成。
主服务器的常见状态:
sending binlog event to slave
finished reading one binlog, switching to next binlog
has sent all binlog to slave, waiting for binlog to be updated
waiting to finalize termination #线程停止时发生的一个很简单的状态
从I/O状态:
connecting to master
checking master version
registering slave on master
repquesting binlog dump
waiting to reconnect after a failed binlog dump request
reconnecting after a failed binlog dump request
waiting for master to send event
queneing master event to the relay log
waiting to reconnect after a failed master event read
从SQL线程状态:
reading event from the relay log
has read all relay log ,waiting for the salve I/O thread to update it
waiting for slave mutex on exit #线程停止时发生的一个很简单的状态
九、生产场景主从读写分离
实现从库只能读的方式:
1)生产权限方案1-主库不能再更改了
主库:web oldboy123 10.0.0.1 3306 (select insert delete update)
从库:主库的web用户同步到从库,然后回收insert delete update 权限。
开发只需知道10.0.0.1是主,10.0.0.2 是从。运维则需要回收从的权限
不收回从库权限的话,在从库设置read-only参数防止从库写的操作
# read-only设置方式-在从库的my.cnf中的【mysqld】下添加一行read-only,并重启mysql,但是对于具有super或all privilege权限的用户不生效,可以尝试创建一个只有增删改查询权限的用户。
2) 生产权限方案2
主库:web_w oldboy123 10.0.0.1 3306 (select insert delete update)
从库:web_r oldboy456 10.0.0.2 3306 (select)
风险:web_w连接从库!可能把主库同步到从库了,因此也可设read-only保证从库只读
开发多套用户密码相对不专业
3) 生产权限方案3
mysql库不同步(在配置文件等随便修改一点点参数):主从库分别进行如下授权
主库:web oldboy123 10.0.0.1 3306 (select insert delete update)
从库:web oldboy123 10.0.0.2 3306 (select)
缺陷:当从库切换主库时,连接用户权限问题。因此可借鉴百度的做法,保留一个从库专门接替主(或者只做简单的备份)。
十、忽略授权表,限制哪些同步,哪些不同步
主库执行:
vi /data/3306/my.cnf
配置-
replicate-ignore-db = mysql
binlog-ignore-db = mysql
binlog-ignore-db = performance_schema
binlog-ignore-db = information_schema
(补充:
master端:
binlog-do-db 二进制记录的数据库,多个数据库用逗号分隔
binlog-ignore-db 二进制忽略的数据库,多个数据库用逗号分隔
slave端:
replication-do-db 设定需要复制的数据库,多个数据库用逗号分隔
replication-ignore-db 设定忽略复制的数据库,多个数据库用逗号分隔
replication-do-table 设定需要复制的表,多个表用逗号分隔
replication-ignore-table 设定忽略复制的表,多个表用逗号分隔
replication-wild-do-table 设定要复制的表,但是可以加通配符
replication-wild-ignore-table 设定忽略复制的表,但可以加通配符)
/data/3306/mysql stop
/data/3306/mysql start
mysql> select user.host from mysql.user;
mysql> flush privileges;
mysql> create user oldgirl@localhost identified by ‘old123‘;
从库查看是否有相同的用户创建出来:
mysql> show slave status\G #从库依旧两个yes,同步
mysql> select user.host from mysql.user; #从库没有相应的用户,即忽略了授权表
十一、主库master宕机(数据库/服务器)-假设一主多从
登录从库:
show processlist\G #查看复制状态
cat /data/3307/data/master.info #分别查看从库的master.info,其中mysql-bin对应序号及下面位置号更大的从库,代表其同步性越高,丢失的数据相对少,将此从库作为新的主库
#如果主库还可以拉起来,则可以把主库的binlog拉取到从库中,再拉起从库为主库
#或者利用半同步功能,直接选择了实时同步的这个从库(半同步待了解)
1.确保所有relay log全部更新完毕
在每个从库上执行stop slave io_thread; show processlist;
直到查看到has read all relay log表示从库更新都执行完毕
2.登录新的主库-如果该从库配置过授权表,read-only等,都需要注销掉
如:mysql -uroot -p456 -S /data/3307/mysql.sock
stop slave;
retset master;
quit;
3.进到数据库数据目录,删除master.info和relay-log.info
cd /data/3307/data
rm -f master.info relay-log.info
4.3307 提升该从库为主库
vi /data/3307/my,cnf
开启log-bin = /data/3307/mysql-bin
重启数据库:/data/3307/mysql restart
5.其他从库操作
已检查(同步user rep均存在)
登录从库:
stop slave;
change master to master_host = ‘192.168.1.32‘; #如果之前在master上设定过VIP,则此步骤可以省略,VIP可以自动漂浮;如果不同步,可以指定位置点进行同步
start slave;
show slave status\G
6.修改程序配置文件从主库指向从库(新的主库)-开发层面对
7.修理损坏的主库,作为从库使用
补充:如果不是宕机,而是有计划的切换主从
1)主库锁表
2)登录所有的库查看同步状态是否完成
其他与前面一样。change master
十二、从库slave宕机(数据库/服务器)-假设一主多从
从做slave
stop slave;
gzip -d oldboy_data_5.sql.gz
mysql -uroot -p456 -S /data/3307/mysql.sock < oldboy_data_5.sql & //直接灌入数据
change master to master_host=‘192.168.1.35‘ , master_user=‘repl‘ , master_password=‘slavepass‘ , master_log_file=‘mysql-bin.000004‘, master_log_pos=333;
start slave;
show slave status\G
十三、双主-假设原来3306是主,3307是从
解决表的主键自增长变量冲突【mysqld】:
Master1:
auto_increment_increment = 2 #自增ID的间隔,如 1 3 5间隔为2
auto_increment_offset = 1 #ID的初始位置
Master2:
auto_increment_increment = 2 #自增ID的间隔,如 2 4 6间隔为2
auto_increment_offset = 2 #ID的初始位置
生成序列为: 1 3 5 6 8 10 11 13 这种,ID可能会不连续
//或者通过程序控制主键自增形式
互为主从参数:
log-slave-updates #开启从库binlog日志
log-bin=/data/330X/XXX
如果不同步,则需要通过MySQLdump -master-data=1 -x 双向做一下同步;
在3306上:
mysql> CHANGE MASTER TO
MASTER_HOST=‘3307的IP‘,
MASTER_PORT=3307,
MASTER_USER=‘rep‘,
MASTER_PASSWORD=‘oldboy123‘;
然后查看3306作为3307的从库的状态正常即可 show slave status,需重启slave。
标签:art inotify list 个数 send ash 定位 授权 允许
原文地址:https://www.cnblogs.com/wangke2017/p/9737123.html