注意问题:
1、mysql复制的基础:binary log (bin log)
2、bin_log中记录了所有的无论是明确的或隐示的引起数据库发生改变的语句
3、中继日志:slave保存的从master上传过来的日志
4、如果主服务上的二进制日志足够可靠而且从服务器上不用再拖一个从服务器,可以取消从服务器的bin_log,以获得更好性能!
5、mysql replication是异步传输(async),传送者并不等待接收者确认的这种传送方式!比如一个命令mkdir 目录后,整个过程都是在内存中完成的,mkdir并不等待其要在磁盘上建立好目录。由于主服务器不等待从服务器确认,由此可能导致主从服务器上的处理进程不一致,这称为从服务器的延迟(delay).
6、mysql replication中的三个线程:主服务器上的dump线程,负责将主服务器二进制日志发送给从服务器的I/O 线程(thread),I/O线程负责接收主服务器发送过的二进制日志并写入到中继日志里(relay log),当中继日志中有了新的内容,从服务器会启动一个SQL线程,负责从中继日志中读出日志并执行一次日志。
7、replication配置:1.配置主服务器bin-log,从服务器的relay-log. 2.配置主从服务器不同的身份标识server-id. 3.在主服务器上建立复制帐号,然后在从服务器上使用这个帐号用于复制 4.如果是跨互联网的复制还得在主从服务器上建立CA,使用SSL复制。
8、--master-data参数,当从服务器建立于主服务器之后很久,先在主服务器备份之前的一些日志,用逻辑传输的方式(比如SCP)传输到从服务器应用,然后从服务器复制需要知道的主服务器备份日志开始的下一刻的那个位置position。这个position用此参数指定。
9、DB复制中,从服务器的版本可以比主服务器的版高或者一样,但不能低。
10、mysql初始化,./scripts/mysql_install_db --user=mysql --datadir=.....
11、其中在mysqlhotcopy备份过程中,他会自动锁表和释放锁!但为了查看日志文件以及快照生成的时候的字节偏移量,在mysqlhotcopy和mysqldump备份中都先手动锁表,查出日志文件和字节偏移量,再备份复制,再释放锁!mysqldump 是采用SQL级别的备份机制,它将数据表导成 SQL 脚本文件,数据库大时,占用系统资源较多,支持常用的MyISAM,innodb
mysqlhotcopy只是简单的缓存写入和文件复制的过程,占用资源和备份速度比mysqldump快很多很多。特别适合大的数据库,但需要注意的是:mysqlhotcopy只支持MyISAM 引擎
12.在mysqldump备份后的文件中也可以查看master开始备份时的master_log_file和master_log_pos参数值。mysqldump备份的时候使用--master-data参数,mysqldump --master-data=1 test>test.sql,则在生成的备份文件里会有change master to master_log_file。。。。等语句,用此参数备份的备份文件用来建立一个slave replication的时候应该可以不用手动指定master日志和日志偏移量
13.在备份以及恢复时,如果备份时使用的--all-databases选项,代表全部数据库,包括mysql权限管理库,则在slave端恢复时要记得使用master那端的管理密码。
flush master,flush slave可以重置所有数据库的信息,包括二进制日志和中继日志!
flush logs 关闭当前二进制日志,并生成一个新的!日志序号加1
注意点:
1.如何阻止从服务器写操作?
show alobal variables like 'read_only' 全局变量,在命令行执行不会永久执行,在my.cnf [mysqld]段中设置read-only = 1.但其只能阻止普通用户写。(不阻止sql thread线程写,不能阻止super权限写)
mysql> flush tables with read lock;阻止任何用户写操作
2.一个主服务器可否多从?可以,一从是否多主?不行
3.主——从:异步,mysql 5.5 google补丁,可以让mysql架构实现半同步(semisync) ,即在一个一主多从架构下,可以等待至少其中一台从服务器从入成功。另外也需定义同步超时时间,一般设置为1秒即可,以防半同步在指定时间无法完成时,自动降级为异步模式,以免影响主服务器性能。5.5也可以检测mysql 心跳信息(heart)
半同步启动需要主从两端都需要加载安装各自对应的semi模块,从库端支持半同步功能的数量至少一台;主库端当一个事务成功提交后,并不及时反馈给前端用
户,该线程会被临时block,等待由从库端返回确认该条事务也同时成功写入到relay
log中的receipt(回执确认),这时主库线程才返回给当前session告知操作完成,半同步复制并不关心在从库一端该事务是否都被执行并被提交完成
4.设置半同步模式,在master和slave在mysql命令行运行如下代码:
#on master
mysql>install plugin rpl_semi_sync_master
soname 'semisync_master.so';
mysql>set global rpl_semi_sync_master_enabled = 1;
mysql>set global rpl_semi_sync_master_timeout = 1000;
#on slave
mysql>install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
mysql>set global rpl_semi_sync_slave_enabled = 1;
mysql>stop slave io_thread;
mysql>start slave io_thread;
或stop slave
start slave
可以使用show plugins 查看已装载插件,查看服务器上semi_sync是否开启,show global status like 'rpl_semi%';
取消加载插件:uninstall pluginrpl_semi_sync_master;
在master和slave的my.cnf中编辑:
#on master
[mysqld]
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000 #1 second
#on slave
[mysqld]
rpl_semi_sync_slave_enabled =1
5.如何实现从服务器的mysql服务在启动时不要启动从服务器线程mysql thread
master.info
relay-log.info
在从服务器上:
[myysqld]
skip-slave-start=1
6.数据库复制过滤(仅复制某些数据库而不是全部数据库)
主服务器
[myslqd]
binlog-do-db=magedu(白名单)
binlog-ignore-db=mysql(黑名单)谁的范围小谁生效
在主服务器过滤:任何不涉及到数据库相关的写操作都不会被记录到二进制日志中,所以一般都是在从服务器上做过滤
从服务器:
replicate_do_db=
replicate_ignore_db=
replicate_do_table=
replicate_ingore_table=(精确到表)
replicate_wild_do_table=mageedu.tb%
replicate_wild_ignore_table=
这些参数只要开启了其中一个,便会只复制或只忽略手动指定的那个库,所以一旦开启了其它一个参数,便需要把要复制要忽略的都指定好!!
使用replicate_do_db和replicate_ignore_db时有一个隐患,跨库更新时会出错
如设置 replicate_do_db=test
use mysql;
update test.table1 set ......
第二句将不会被执行
如设置 replicate_ignore_db=mysql
use mysql;
update test.table1 set ......
第二句会被忽略执行
原因是设置replicate_do_db或replicate_ignore_db后,MySQL执行sql前检查的是当前默认数据库,所以跨库更新语句被忽略。
可以使用replicate_wild_do_table和replicate_wild_ignore_table来代替
replicate_wild_do_table=test.%
或
replicate_wild_ignore_table=mysql.%
这样就可以避免出现上述问题了
7.主服务器崩溃,事务已经提交,但还未写入二进制日志,
在主从架构上建议使用的配置:
主服务器:
[mysqld]
sync_binlog=1
表示mysql每次在提交事务前会将二进制日志同步到磁盘。表示每次写缓存的时候并同步写磁盘日志。sync_binlog=N,N表示每写缓存多少次就同步到磁盘。如果N=1,表示采用同步写磁盘的方式来写二进制日志。表示每写一次缓存就同步写一次磁盘!也就是每次事务提交前,二进制日志就已经写入磁盘了。
当使用事务表存储引擎的时候,所有未提交的二进制日志会被记录到一个缓存中(binlog_cache_size),等该事务提交时,才直接将缓冲中的二进制日志写入二进制日志文件。
当二进制日志已经写入磁盘,但当down机时,事务还没来的及提交,所以下次开机时需要回滚,但二进制日志已经有此事务记录了,便不能回滚!此时需将参数innodb_support_xa=1与sync_binlog=1一起使用.用来保证二进制日志与innodb存储引擎数据文件的同步
innodb_flush_logs_at_trx_commit=1 事务提交立即写到磁盘
0:当提交事务时,并不将事务的的重做日志文件缓冲写入磁盘上的重做日志文件,而是等待主线程每秒的刷新。
1:commit时,将重做日志文件缓冲同步写到磁盘。
2:重做日志异步写到磁盘,即不能保证commit时肯定会写入磁盘文件,可能会由于操作系统的缓存调度等原因在稍后才会写入磁盘。只是有这个刷新到磁盘的动作命令。
8.设置读写分离:
mysql分层,mysql代理做前端处理(读写分离器,由它管理后面谁负责读,谁负责写)后面跟mysql集群
mysql proxy mysql官方项目
amoeba淘宝开源项目
9.mysql主主架构:
1.server_id 不一样
2.双方设置复制帐号
3.双方开启二进制和中继日志
4.启动之前明确双方二进制日志和偏移位置
master推荐配置:
log-bin=/usr/local/mysql/data/mysql-bin
sync_binlog=1
innodb_flush_log_at_trx_commit=1
innodb_support_xa=1
#innodb_safe_binlog
slave推荐配置:
relay_log=mysql-relay-bin
log_slave_updates=1 表示salve将复制事件写进自己的二进制日志文件,与salve上的log-bin配合
read_only=1
skip_slave_start 阻止备库崩溃启动后自动启动复制。
下面三项用来保证备库master.inof和中继日志文件崩溃安全
sync_master_info=1
sync_relay_log=1
sync_relay_log_info=1
配置步骤:
1.配置主从服务器server-id=1,二者不能一样
2.配置主服务器log-bin=mysql-bin,从服务器看需求是否需要启动log-bin
3.配置从服务器relay-log=relay-bin与relay-log-index=relay-bin-index
show global variables like 'relay%';查看中继日志参数
4.主服务器上建立复制帐号,grant replication slave,replication client on *.* TO repl@'192.168.3.%' identified by '123456';
flush privileges刷新用户表,使用用户生效
5.启动从服务器上的从服务器线程,change master to master_host='192.168.3.25',
master_user='repl',
master_password='123456'
master_log_file='mysql-bin.000001'
master_log_pos='245';
6.start slave;此命令明确说明启动slave。
stop slave;
show slave status,查看从服务器状态,主要查看slave_sql_running,slave_io_running是否为YES启动。
show processlist,
前面讨论的假设你是新安装的master和slave,所以,slave与master有相同的数据。但是,大多数情况却不是这样的,例如,你的master可能已经运行很久了,而你想对新安装的slave进行数据同步,甚至它没有master的数据。此时,有几种方法可以使slave从另一个服务开始,例如,从master拷贝数据,从另一个slave克隆,从最近的备份开始一个slave。Slave与master同步时,需要三样东西:
(1)master的某个时刻的数据快照;
(2)master当前的日志文件、以及生成快照时的字节偏移。这两个值可以叫做日志文件坐标(log file coordinate),因为它们确定了一个二进制日志的位置,你可以用SHOW MASTER STATUS命令找到日志文件的坐标;
(3)master的二进制日志文件。
可以通过以下几中方法来克隆一个slave:
(1) 冷拷贝(cold copy)
停止master,将master的文件拷贝到slave;然后重启master。缺点很明显。
(2) 热拷贝(warm copy)
mysqlhotcopy -u root -p 123 testdb /root/dbbak/
如果你仅使用MyISAM表,你可以使用mysqlhotcopy拷贝,即使服务器正在运行。
(3) 使用mysqldump(可以在myisam和inoddb引擎下使用)
使用mysqldump来得到一个数据快照可分为以下几步:
<1>锁表:如果你还没有锁表,你应该对表加锁,防止其它连接修改数据库,否则,你得到的数据可以是不一致的。如下:
mysql> FLUSH TABLES WITH READ LOCK;
<2>在另一个连接用mysqldump创建一个你想进行复制的数据库的转储:
备份:shell> mysqldump --all-databases --lock-all-tables >dbdump.db
恢复:mysql -uroot -p db <dbdump.db
source dbdump.db
<3>对表释放锁。
mysql> UNLOCK TABLES;