由邮件系统 引发的mysql 排序问题

前边我们介绍了游戏中的邮件系统-----游戏服务器---邮件系统_zhangdell的专栏-CSDN博客

一:问题发现

        最近客户端更换引擎,所有的功能都得重新对接,在对接邮件功能时客户端反馈了一些异常问题,当时第一感觉是客户端自己的问题,因为这些功能已经在生产环境跑了2年的时间了,而且邮件这套逻辑 已经在另外一个项目当中跑了8年了,如果有问题应该早就出了。具体问题如下:

CREATE TABLE `msg`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `ruid` int(11) NOT NULL,
  `msgtype` tinyint(3) UNSIGNED NOT NULL,
  `title` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `content` tinytext CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `got` tinyint(3) UNSIGNED NULL DEFAULT 0,
  `sendtime` datetime(0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `index_ruid`(`ruid`, `got`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 53176 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
CREATE TABLE `msg_attachment`  (
  `msgid` int(10) UNSIGNED NOT NULL,
  `valueitems` varchar(128) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `got` tinyint(3) UNSIGNED NULL DEFAULT 0,
  `gottime` datetime(0) NULL DEFAULT NULL,
  PRIMARY KEY (`msgid`) USING BTREE,
  INDEX `INDEX_gottime`(`gottime`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

SET FOREIGN_KEY_CHECKS = 1;

 服务器调用p_msg_query2存储过程,拉取玩家的未读 or 未领取附件的 邮件

CREATE DEFINER=`root`@`%` PROCEDURE `p_msg_query2`(puid int unsigned,
	plastgotid int unsigned,
	plimit int unsigned)
BEGIN
	select id,
           msgtype,
           title,
           content,
           sendtime,
           valueitems,
           msg_attachment.got
    from msg left join msg_attachment on (msg_attachment.msgid=msg.id)
    where ruid=puid and (msg.got=0 or msg_attachment.got=0) and id>plastgotid limit plimit;
END

客户端 ruid=120114 每次拉取5封邮件,第一次发来的 plastgotid = 0,拉取了id为 53145 53152 49325 49329 49361 这5封邮件,第二次来拉的时候  plastgotid = 53152,服务器发现没有新邮件了,这样客户端只显示了5封邮件,这肯定是不正常的,因为数据库中ruid=120114这个用户 未读or未领取的邮件 有好多封,绝对不止这5封邮件。客户端重新捋了一遍逻辑说他那边没问题,这个时候我心里就犯了嘀咕,线上的老功能 咋会出现这么低级的错误尼,我开始查数据库里边的数据,果真颠覆了我的认知。。

执行存储过程得到的结果

 从数据库的数据+服务器逻辑来看,客户端确实只会收到 53145 53152 49325 49329 49361这5封邮件,这就引起了我的注意了,为啥select 出来的结果 id 顺序是乱的,为啥线上没有出现这种问题。再次看了一下sql 发现sql中并没有明确的要求顺序是按照id 来排序的,大概知道问题的解决办法了,加上order by id应该就好使。此时我又写了一个简单的测试sql,select id,title,content from msg where ruid = 120114;

 最简答的单表 select 得到的结果就是有问题的,重启mysql后 也没得到解决。修改后 select id,title,content from msg where ruid = 120114 order by id;得到的结果就是正确的。问题是解决了,但是不知道是如何引起的。

二:问题深入

后来查了一些资料,select * from  不加order by 顺序本来就得不到保证,53145,53152 这2条数据在插入时占用了以前删除的表空间,数据落盘了 重启mysql服务也没用。所以select 的时候 先出现了后插入的2条数据。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值