运维系统无法登陆的问题排查
这是学习笔记的第 1923 篇文章
今天刚上班的时候同事给我反馈,说运维系统访问不了了,现在运维系统用不了,还是很影响业务需求处理的。于是登陆系统验证了下,发现我也登陆不了了,看来确实中招了。
看看报错信息,错误是“(-1, 'error totally whack')”
这个错误让我没有任何思路,网上有一些讨论说是访问数据库出错了。
但是我查看运维系统后台的日志,API访问依旧正常,再试了一个备用账号,发现也能够正常登陆,我就怀疑是不是就我们两个登陆不了了,看看登陆记录的信息,其他人都是正常的。我就纳闷了,看来这个问题的原因很扑朔迷离啊。
我的第一个思路是想Django的项目里面会自动维护一个django_session我的印象中这个表有百万条记录了,会不会是因为检查的时候回调写入这个表的时候有问题导致的。
这个文件有1.6G左右,算是比较大的了。
-rw-r----- 1 mysql mysql 8664 Feb 22 13:25 django_session.frm
-rw-r----- 1 mysql mysql 1690304512 Mar 19 09:40 django_session.ibd
清理会话信息Django提供了一个方法clearsessions
python manage.py clearsessions
(0.000) SET SQL_AUTO_IS_NULL = 0; args=None
(0.000) SET SQL_AUTO_IS_NULL = 0; args=None
(430.746) DELETE FROM `django_session` WHERE `django_session`.`expire_date` < '2019-03-19 09:46:23.752256'; args=(u'2019-03-19 09:46:23.752256',)
这个过程持续了6分钟,从后端的日志来看前端业务没有任何影响。
当然delete是不彻底的,表还是1.6G左右,这个时候我们使用一点小技巧来转移一下数据,这个过程持续时间较短,大概有几秒钟。
整体的思路就是移形换位。
create table devopsdb_arch.django_session like devopsdb.django_session;
insert into devopsdb_arch.django_session select *from devopsdb.django_session where ;
alter table devopsdb.django_session rename to devopsdb_arch.django_session_bak;
alter table devopsdb_arch.django_session rename to devopsdb.django_session;
清理完之后,空间立马收缩到了几十兆,但是登录的时候依然报错,所以这个时候我开始重新审视这个问题,问题不在django_session表上面。
看后端的日志调用,是在检查用户名密码之后,会写入django_session数据之后回调写入auth_user表,把last_login字段修改为当前时间。
但是根据报错在这个阶段失败了,所以我就尝试手工修改一下这个部分,结果发现了问题:
update auth_user set last_login='2019-03-19 09:15:38' where username='root';
ERROR 3101 (HY000): Plugin instructed the server to rollback the current transaction.
看到这个问题,我已经基本排除了应用层面的问题,很可能是数据库导致的了。这个数据库是一套MGR多主的环境,和另外一套环境是跨机房的多活架构。
对于这个问题的修复,排查了sys schema下面和锁相关的数据字典,没有得到任何信息。
带着试试看的态度,因为节点2目前没有业务写入,对节点二的环境重启了Group replication,重启后,尝试update竟然成功了。
>>update auth_user set last_login='2019-03-19 09:15:38' where id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
但是我重新登录页面的时候还是报错了。
重新进行验证发现还是同样的问题,我怀疑是django_session写入的事务失败导致,所以再一次清理了会话表,这一次很快就完成了,但是登录依旧失败。
所以这个时候耐下心来看看GTID的配置和日志的信息,发现有一个事务的日志没有应用过去。
这个问题的一种补救方式就是关闭流控flowcontrol,然后重启Group replication,我先停止了节点2的GR,然后停止节点1的GR,然后启动,接着启动节点2的GR.
再次测试就正常了。
这个问题虽然解决了,但是因为限于环境和恢复业务的需要,没有做更多的分析。 从表现来看和另外一个bug有些类似。
https://bugs.mysql.com/bug.php?id=84901
对于多主环境的问题还需要持续关注,从目前来看还算是比较稳定的。