mysql读写分离原理及配置( 三 )

行2为处理slave的I/O线程的连接 。
在slave服务器上运行该语句:
mysql> show processlist G*************************** 1. row *************************** Id: 1 User: system user Host: db: NULLCommand: Connect Time: 2291 State: Waiting for master to send event Info: NULL*************************** 2. row *************************** Id: 2 User: system user Host: db: NULLCommand: Connect Time: 1852 State: Has read all relay log; waiting for the slave I/O thread to update it Info: NULL*************************** 3. row *************************** Id: 5 User: root Host: localhost:2152 db: testCommand: Query Time: 0 State: NULL Info: show processlist3 rows in set (0.00 sec)行1为I/O线程状态,行2为SQL线程状态 。
2.5、添加新slave服务器
假如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)
如果你仅使用MyISAM表,你可以使用mysqlhotcopy拷贝,即使服务器正在运行 。
(3) 使用mysqldump
使用mysqldump来得到一个数据快照可分为以下几步:
<1>锁表:如果你还没有锁表,你应该对表加锁,防止其它连接修改数据库,否则,你得到的数据可以是不一致的 。如下:
mysql> FLUSH TABLES WITH READ LOCK;
< 2>在另一个连接用mysqldump创建一个你想进行复制的数据库的转储:
shell> mysqldump --all-databases --lock-all-tables >dbdump.db
< 3>对表释放锁 。
mysql> UNLOCK TABLES;
3、深入了解复制已经讨论了关于复制的一些基本东西,下面深入讨论一下复制 。
3.1、基于语句的复制(Statement-Based Replication)
MySQL 5.0及之前的版本仅支持基于语句的复制(也叫做逻辑复制,logical replication),这在数据库并不常见 。master记录下改变数据的查询,然后,slave从中继日志中读取事件,并执行它,这些SQL语句与master执行的语句一样 。
这种方式的优点就是实现简单 。此外,基于语句的复制的二进制日志可以很好的进行压缩,而且日志的数据量也较小,占用带宽少——例如,一个更新GB的数据的查询仅需要几十个字节的二进制日志 。而mysqlbinlog对于基于语句的日志处理十分方便 。
但是,基于语句的复制并不是像它看起来那么简单,因为一些查询语句依赖于master的特定条件,例如,master与slave可能有不同的时间 。所以,MySQL的二进制日志的格式不仅仅是查询语句,还包括一些元数据信息,例如,当前的时间戳 。即使如此,还是有一些语句,比如,CURRENT USER函数,不能正确的进行复制 。此外,存储过程和触发器也是一个问题 。
另外一个问题就是基于语句的复制必须是串行化的 。这要求大量特殊的代码,配置,例如InnoDB的next-key锁等 。并不是所有的存储引擎都支持基于语句的复制 。
3.2、基于记录的复制(Row-Based Replication)
MySQL增加基于记录的复制,在二进制日志中记录下实际数据的改变,这与其它一些DBMS的实现方式类似 。这种方式有优点,也有缺点 。优点就是可以对任何语句都能正确工作,一些语句的效率更高 。主要的缺点就是二进制日志可能会很大,而且不直观,所以,你不能使用mysqlbinlog来查看二进制日志 。
对于一些语句,基于记录的复制能够更有效的工作,如:
mysql> INSERT INTO summary_table(col1, col2, sum_col3)
-> SELECT col1, col2, sum(col3)
-> FROM enormous_table
-> GROUP BY col1, col2;
假设,只有三种唯一的col1和col2的组合,但是,该查询会扫描原表的许多行,却仅返回三条记录 。此时,基于记录的复制效率更高 。
另一方面,下面的语句,基于语句的复制更有效:
mysql> UPDATE enormous_table SET col1 = 0;
此时使用基于记录的复制代价会非常高 。由于两种方式不能对所有情况都能很好的处理,所以,MySQL 5.1支持在基于语句的复制和基于记录的复制之前动态交换 。你可以通过设置session变量binlog_format来进行控制 。


推荐阅读