MySQL 主从服务器的一些技巧

来源:互联网 发布:精华复读学校 网络 编辑:程序博客网 时间:2024/06/01 10:18

问题:主从服务器表类型的选择

一般的共识是主服务器使用innodb,事务,行锁等功能是myisam 所没有的,对
修改操作而言,它更高效;从服务器使用myisam,全文检索功能是innodb 所没有的,
对查询操作而言,它更高效。这样就可以各尽其能。

问题:主从服务器字段类型的选择

字段类型对于分页等操作有很大影响。主服务器一般是innodb,因为不涉及查询,
所以可以使用varchar 等来存储字符串来节省空间,从服务器一般是myisam,因为涉
及查询,所以必须在char 和varchar 之间仔细权衡,没有varchar、text、blob 字段的
表是静态表,反之是动态表,静态表的检索效率要比动态表好若干倍,一般来说,所
有涉及大结果集的查询都应该尽可能保证在静态表上完成,这里说一个例子:比如说
常见的articles 表有title(varchar),body(text)等字段,在做文章列表的时候,因为不是
静态表,所以查询不会很快,下面开始重构解决方案:把原来的articles 表拆分成
subjects 表和contents 表,title 字段设置为一个足够的char 类型放在subjects 表里,body
字段还保持是text 类型放到contents 表里,subjects 和contents 表之间的关系是一对多,
这样,顺带着也方便的实现了多页文章的功能,而且更重要的是在查询文章列表的时
候,操作都是在subjects 静态表里完成,效率肯定会比前一种方案提升很多。
强调:MyISAM 里静态表和动态表的区别对性能影响极大,但我敢说很大一部分
使用者并没有注意过这一点!如果你就是其中之一,那么我强烈建议你再次体会一下
前面说的articles 分解为subjects/contents 的过程,相信你熟悉了以后,下一个应用的
速度会有质的提升。

问题:主从服务器NOW()函数造成数据不一致

假设在主服务器上执行一条INSERT….VALUES(…,NOW()),那么在从服务器上
也会同样执行一条的SQL 语句,但是主从服务器各自的时间设置可能不一致(比如
说时区不同),NOW()在两台服务器上的结果就可能不一致。在MySQL5.1 里,将支
持行复制,那时候就不存在这个问题了。不过不管怎么说,都不应该在程序里使用
NOW(),时间的计算在应用程序里完成。这里介绍一个额外的小技巧:获得时间戳,
和time()相比,$_SERVER[‘REQUEST_TIME’]少做了一次系统调用,不过是否合
适要视客观情况而定。

问题:主从服务器读写分离时读操作失败

先重现一下问题:比如说添加一条新数据,添加成功后根据last_insert_id 跳转到
新添加数据的浏览页面。在此过程中添加新数据的操作是在主服务器上完成的,浏览
新数据的操作实在从服务器上完成的,不过由于主从服务器间SQL 同步存在延迟,
所以当使用last_insert_id 在从服务器上查询的时候,从服务器很可能还没有还没来得
及同步到此记录,所以读操作失败。解决思路也不复杂,在代码里加入一个缓存层(可
以使用memcached),新添加的数据都顺手放到缓存层里一份,新数据的读操作也先
查询缓存层,这样就不会再有读操作失败的问题了,当然删除或者更新数据的时候也
要顺带着处理好缓存数据,可以使用观察者模式来搞定。不过这样缓存方案只限于读

取单一的记录,对于读取列表的记录的情况,则是无效的。

问题:主从服务器索引是否有必要保持一致
一般都是利用主从服务器完成读写分离,从服务器上进行读操作,主服务器进行
写操作,这样的话,主服务器上仅保留主键,外键,唯一索引等必要的索引即可,以
便保持数据合法性,而对于那些原本用于优化SELECT 操作的索引,可以全部删除,
如此的话主服务器的写操作效率会提升很多。

原创粉丝点击