刚接收一个内容服务下载网站,整体代码格局比较老,管理也比较混乱。最近遇到一个问题刚解决,记录下。
[简述]
mysql数据库服务器的搭建还是经典的master-slave方式,mater用来写操作,slave用来读操作。
网站有个服务器A,功能是 管理页面和cron程序。
cron的程序中有个减去过期积分的程序,每天运行几次。
原理也很简单。
1. 在数据库中查找过期积分。
2. 在数据库中查询用户现保有积分,如果现保有积分大于过期积分,那么就在该基础上减去;
如果现保有积分小于过期积分,那么就将现保有积分归零。
近期问题出现,用户现保有积分被大量减少至负数,例如-10000等数值。
从php程序中几乎找不到问题所在,php程序中都有相应的判断,按程序逻辑不应该出现负值。
[问题追踪]
slave服务器的连接被设计为随机调用。
比如5台服务器,使用rand()函数,随机抽取其中一台来访问查询数据。
master-slave模式的服务器结构,最应当考虑的问题就是,slave不能够及时同步master数据时,
会产生哪些问题。很明显原网站设计者,根本没有考虑过该问题。
所以可以演绎错误是怎样发生的,服务器A查询用户现保有积分时随机访问slave服务器,但是有台服务器
的数据没有与master同步,显示保有积分为500,实际上在master服务器的保有积分为0。而在写操作是在
master服务器上操作,这就导致了最终结果是保有积分为-500的状况出现。
[问题解决]
1. cron程序的所有操作,包括读取,写入,更新,都应该只在主服务器上进行。
2. 表中field的属性应当更加严谨,不能为负数的值应当由int改为unsinged。
[总结]
1. master-slave模式的数据库服务器结构,在构造时,应当更加严谨,充分考虑slave不能与master及时同步时可能产生的问题。
2. 数据库连接的部分一般封装为固定函数方便调用,所以程序员在编写时为了方便拿来就用。在使用这种函数时应当多考虑一步master-slave可能产生的什么样的影响。