mysql断线重连_mysql断线重连报错

原本 dispatch_by_order 循环中,socket.block 方法是挂起协程阻塞的,当客户端socket主动断开的时候,socket 协程被唤醒发现 connected 为 false,继续执行了 close_channel_socket(self) 和 wakeup_all(self),进而调用 socket.close 关闭了 socket 。所以,channel:request 中的_block_connect_ 方法 check_connection 返回false,执行了相关的重连逻辑。更新版本后,dispatch_by_order 循环中不处理客户端 socket 主动关闭,从而 channel:request 中_block_connect_ 方法 check_connection 返回true,重连逻辑没有被执行,直接在已经断开的 socket 上执行 write 方法报错,报错之后 socket 关闭标识会被更新,所以在下一次执行_channel:request_ 的时候,重连逻辑会被触发运行。

我的处理比较粗暴,如果请求失败,执行一次SELECT 1, 这时重连是成功的,然后再执行之前的失败请求

@LokerLi 提供的方法,SELECT 1,会触发socketchannel报错并更新_socket.__closed_标识,再执行正式的请求就会重连返回正确的消息了。 我们现在采取的方式是pcall调用数据库查询方法,如果报错再执行一遍。

local CMD = {}

local pool = {}

local size = 10

local index = 1

local function getdb()

local db = pool[index]

index = index + 1

if index > size then

index = 1

end

return db

end

function CMD.query(sql)

local db = getdb()

local ok, result = pcall(db.query, db, sql)

print(ok, result)

if not ok then

result = db:query(sql)

end

print(dump(result))

return result

end

可是项目遇到的问题是,更新skynet版本后,每天早上mysql的query方法都会报错,并且一直没有重连成功。因为处于测试阶段,所以晚上并没有活动的数据库连接,wait_timeout的超时时间过了后,数据库连接就断开了。我猜测是这个样子,但是为什么不能重连成功呢?

后来确认是mysql断开确实是因为wait_timeout默认为8小时,项目开发阶段晚上并没有活动的数据库连接,所以早上上班测试的发现连接已经断开。一直没有被发现的原因,是因为以前sockectchannel自动重连。又因为采用了100大小的连接池,所以错认为一直重连不成功,只是没有在一个连接中重复请求罢了。

经测试,redis断开之后,也是第二次才能重连成功。

@cloudwu 云大,不清楚当初那个patch [bugfix: socketchannel order mode may blocked. (used by redis driver)] 的修改初衷是为了什么,难道现在重连必须二次才能成功吗?还是我的理解有错误,希望你能指点一二。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值