纠纷奇闻作文社交美文家庭
聚热点
家庭城市
爱好生活
创业男女
能力餐饮
美文职业
心理周易
母婴奇趣
两性技能
社交传统
新闻范文
工作个人
思考社会
作文职场
家居中考
兴趣安全
解密魅力
奇闻笑话
写作笔记
阅读企业
饮食时事
纠纷案例
初中历史
说说童话
乐趣治疗

面试官MySQL权限表损坏导致无法启动怎么办?

11月19日 先锋客投稿
  一、背景
  近期,公司RDS云产品的MySQLServer版本进行升级,由目前使用的5。7。26版本升级到最新版本5。7。31;升级后测试同学发现:在MySQL创建用户后,5。7。31版本重新启动集群会出现启动失败的现象;而5。7。26版本在相同测试场景下是正常启动的。这到底是为什么呢?
  二、问题复现
  2。1实验环境CentOS7。5MySQL5。7。31
  2。2操作步骤
  按照测试同学的测试步骤,首先创建一个用户:mysqlcreateusertestidentifiedby1234;QueryOK,0rowsaffected(0。01sec)
  然后关闭这里需要介绍一下,我们集群的关闭方式是如下方式:shellkubectldeletepodyuelei57f3b62000nqfusionadmin
  这种方式的内部实现类似于kill9模式。所以我在线下环境使用kill9的方式来复现,操作如下:shellkill9(pidofmysqld)
  然后重启mysqld,操作如下:shellmysqldsafedefaultsfileetcmysqlmy。cnf
  此时问题复现了,mysqld启动失败,我们查看了下error日志,信息如下:。。。20200818T10:13:55。50641508:000〔ERROR〕usrlocalmysqlbinmysqld:Table。mysqluserismarkedascrashedandshouldberepaired20200818T10:13:55。50655308:000〔ERROR〕Fatalerror:Cantopenandlockprivilegetables:Table。mysqluserismarkedascrashedandshouldberepaired20200818T10:13:55。50665808:000〔ERROR〕Fatalerror:FailedtoinitializeACLgranttimezonesstructuresorfailedtoremovetemporarytablefiles。20200818T10:13:55。50678908:000〔ERROR〕Aborting。。。
  根据报错信息可以看出:MySQL的权限系统表发生了损坏,导致了mysqld启动失败;由于在MySQL5。7及其之前版本该表是MyISAM引擎,且该引擎不支持事务,所以在mysqld异常崩溃会导致该类型引擎表的损坏;但在mysqld启动时是有参数控制MyISAM引擎的恢复模式,且该参数在我们产品中也配置到了my。cnf中,如下所示:〔mysqld〕myisamrecoveroptionsBACKUP,FORCE
  2。3参数解析
  对于该参数的官方文档的解释如下:
  设置MyISAM存储引擎恢复模式。选项值是OFF、DEFAULT、BACKUP、FORCE或QUICK的值的任意组合。如果指定多个值,请用逗号分隔。指定不带参数的选项与指定DEFAULT相同,指定显式值将禁用恢复(与OFF值相同)。如果启用了恢复,则mysqld每次打开MyISAM表时,都会检查该表是否标记为已崩溃或未正确关闭。(只有在禁用外部锁定的情况下运行,最后一个选项才起作用。)在这种情况下,mysqld在表上运行检查。如果表已损坏,mysqld将尝试对其进行修复。OFF:Norecovery。DEFAULT:Recoverywithoutbackup,forcing,orquickchecking。BACKUP:Ifthedatafilewaschangedduringrecovery,saveabackupofthetblname。MYDfileastblnamedatetime。BAK。FORCE:Runrecoveryevenifwewouldlosemorethanonerowfromthe。MYDfile。QUICK:Donotchecktherowsinthetableiftherearenotanydeleteblocks。
  服务器自动修复表之前,它将有关修复的注释写到错误日志中。如果您希望能够在无需用户干预的情况下从大多数问题中恢复,则应使用选项BACKUP,FORCE。即使某些行将被删除,这也会强制修复表,但是它将旧的数据文件保留为备份,以便您以后可以检查发生了什么。
  全局变量,只读变量,默认为OFF。
  三、问题修复
  这类MySQL用户表损耗的问题解决方式也是有多种,我这里列举其中一种:
  (1)my。cnf中的〔mysqld〕标签下添加skipgranttables,启动时跳过加载系统字典。〔mysqld〕skipgranttables
  (2)重启mysqld,然后修复mysqlschema下的所有表。shellmysqlcheckurootpxxxmysqlautorepair。。。mysql。userwarning:1clientisusingorhasntclosedthetableproperlystatus:OK
  (3)在〔mysqld〕标签下注释或删除掉skipgranttables,然后重启mysqld。shellmysqldsafedefaultsfileetcmysqlmy。cnf
  此时mysqld是可以正常启动的,无异常。
  四、深入排查
  在产品化中,以上修复方式很不优雅,只是作为临时的解决方案;并且也存在一些令人疑惑的点:通常情况下在my。cnf中设置myisamrecoveroptionsBACKUP,FORCE时,启动时会自动修复MyISAM损坏的表;在上述场景中为什么没有自动修复呢?相同环境下,5。7。26版本mysqld启动是正常的,但是5。7。31版本mysqld启动出现如上述现象;难道是MySQL做了改动吗?
  带着这些疑问,我们继续排查出现该现象的原因;此时Google也没有找到一些有效的信息,那么只能通过MySQL源代码来寻找一些答案。
  首先需要下载mysql5。7。31版本的源代码,并搭建mysqldebug环境;具体步骤可以自动Google搜索一下,本文就不再赘述了。
  在源代码中搜索一下关键词,用于打断点的位置,然后进行调试:确认MySQL版本shellcatVERSIONMYSQLVERSIONMAJOR5MYSQLVERSIONMINOR7MYSQLVERSIONPATCH31MYSQLVERSIONEXTRA搜索一些关键信息shellgreprinitializeACLgranttimemysqltestrgrantdebug。result:PatternFatalerror:FailedtoinitializeACLgranttimezonesstructuresorfailedtoremovetemporarytablefiles。foundmysqltesttgrantdebug。test:letSEARCHPATTERNFatalerror:FailedtoinitializeACLgranttimezonesstructuresorfailedtoremovetemporarytablefiles。;sqlmysqld。cc:sqlprinterror(Fatalerror:FailedtoinitializeACLgranttimezones
  搜索得出的结果很多,我们需要对此进行过滤。mysqltest目录是mysql的测试用例代码,我们可以直接忽略;需要关注的是sqlmysqld。cc的文件,因为mysqld启动时调用mainmysqldmain。。。,而mysqldmain函数是在sqlmysqld。cc目录下,此时我们查看具体的代码(sqlmysqld。cc:4958):if(mysqlrmtmptables()aclinit(optnoacl)mytzinit((THD)0,defaulttzname,optbootstrap)grantinit(optnoacl)){sqlprinterror(Fatalerror:FailedtoinitializeACLgranttimezonesstructuresorfailedtoremovetemporarytablefiles。);deletepidfile(MYF(MYWME));uniregabort(MYSQLDABORTEXIT);}
  定位到相关代码,大概是sqlmysqld。cc的4958行,且存在if条件判断,此时我们开始调试:shellgdbusrlocalmysqlbinmysqld(gdb)bsqlmysqld。cc:4958Breakpoint1at0xe6f8d0:fileoptmysqlserversqlmysqld。cc,line4958。(gdb)rdefaultsfileetcmysqlmy。cnf(gdb)pmysqlrmtmptables()1000(gdb)paclinit(optnoacl)2101(gdb)pmytzinit((THD)0,defaulttzname,optbootstrap)3000(gdb)pgrantinit(optnoacl)4false
  通过以上调试信息,可以判断出aclinit函数返回的值为真;此时我们查看该函数的代码(sqlauthsqlauthcache。cc:1365):Initializestructuresresponsibleforuserdblevelprivilegecheckingandloadprivilegeinformationforthemfromtablesinthemysqldatabase。SYNOPSISaclinit()dontreadacltablesTRUEifwewanttoskiploadingdatafromprivilegetablesanddisableprivilegechecking。NOTESThisfunctionismostlyresponsibleforpreparatorysteps,mainworkoninitializationandgrantsloadingisdoneinaclreload()。RETURNVALUES0ok1Couldnotinitializegrantsmyboolaclinit(booldontreadacltables){THDDBUGENTER(aclinit);。。。
  根据该函数的注释发现:该函数是初始化负责用户数据库级特权检查的结构,并从mysqlschema中的表中为其加载特权信息;且return值为1代表的是初始化权限失败。
  此后开始逐步调试,观察return相关信息,当调试到locktablenames函数时,我们发现在Phase3时return值为true,且根据代码注释发现true代表是F具体代码如下(sqlsqlbase。cc:5549):Acquirestrong(SRO,SNW,SNRW)metadatalocksontablesusedbyLOCKTABLESorbyaDDLstatement。AcquirelockSontablebeingcreatedinCREATETABLEstatement。noteUnderLOCKTABLES,wecanttakenewlocks,souseopentablescheckupgradablemdl()instead。paramthdThreadcontext。paramtablesstartStartoflistoftablesonwhichlocksshouldbeacquired。paramtablesendEndoflistoftables。paramlockwaittimeoutSecondstowaitbeforetimeout。paramflagsBitmapofflagstomodifyhowthetableswillbeopen,seeopentable()descriptionfordetails。retvalfalseSuccess。retvaltrueFailure(e。g。connectionwaskilled)boollocktablenames(THDthd,TABLELISTtablesstart,TABLELISTtablesend,ulonglockwaittimeout,uintflags){MDLTABLELISTMDLHashsetTABLELIST,schemasetgetkeyschemaset(PSIINSTRUMENTME);。。。Phase3:Acquirethelockswhichhavebeenrequestedsofar。if(thdmdlcontext。acquirelocks(mdlrequests,lockwaittimeout))Nowwhenwehaveprotectionagainstconcurrentchangeofreadonlyoptionwecansafelyrecheckitsvalue。SkipthecheckforFLUSHTABLES。。。WITHREADLOCKandFLUSHTABLES。。。FOREXPORTastheyarenotsupposedtobeaffectedbyreadonlymodes。if(needglobalreadlockprotection!(flagsMYSQLOPENSKIPSCOPEDMDLLOCK)!(flagsMYSQLLOCKIGNOREGLOBALREADONLY)checkreadonly(thd,true))。。。
  调试信息如下:(gdb)pflags70(gdb)pneedglobalreadlockprotection8true(gdb)pcheckreadonly(thd,true)9true
  可以看到flags的值为0,而MYSQLOPENSKIPSCOPEDMDLLOCK为宏定义值0x1000,与flags的值做按位与操作,结果自然也是0,当然MYSQLLOCKIGNOREGLOBALREADONLY也是如此;needglobalreadlockprotection是bool类型值,代表是否需要全局读锁的保护,这个值是在tablemdlrequest。type不为MDLSHAREDREADONLY发生改变;checkreadonly函数相关信息下面概述。
  此时也查看了下MySQL5。7。26版本代码作为对比,发现locktablenames函数下的Phase3后的部分代码是在5。7。29版本后新增的。如果是gitclone的MySQL代码可以用gitblame命令查询文件变化的信息:shellgitblameL5637,10sqlsqlbase。cc05824063(NishaGopalakrishnan2019091113:06:4005305637)Nowwhenwehaveprotectionagainstconcurrentchangeofreadonly05824063(NishaGopalakrishnan2019091113:06:4005305638)optionwecansafelyrecheckitsvalue。0405ebee(NishaGopalakrishnan2019091219:24:4505305639)SkipthecheckforFLUSHTABLES。。。WITHREADLOCKand0405ebee(NishaGopalakrishnan2019091219:24:4505305640)FLUSHTABLES。。。FOREXPORTastheyarenotsupposedtobeaffected0405ebee(NishaGopalakrishnan2019091219:24:4505305641)byreadonlymodes。05824063(NishaGopalakrishnan2019091113:06:4005305642)05824063(NishaGopalakrishnan2019091113:06:4005305643)if(needglobalreadlockprotection0405ebee(NishaGopalakrishnan2019091219:24:4505305644)!(flagsMYSQLOPENSKIPSCOPEDMDLLOCK)05824063(NishaGopalakrishnan2019091113:06:4005305645)!(flagsMYSQLLOCKIGNOREGLOBALREADONLY)05824063(NishaGopalakrishnan2019091113:06:4005305646)checkreadonly(thd,true))
  上述展示的信息中,最左侧的列值为commitid为05824063和0405ebee,有兴趣的同学可以详细看下。
  此功能解决的问题是BUG28438114:SETREADONLY1SOMETIMESDOESNTBLOCKCONCURRENTDDL。;当然这个代码的变更功能也在5。7ReleaseNotes中有所体现,如下所示(https:dev。mysql。comdocrelnotesmysql5。7ennews5729。html):Undercertainconditions,enablingthereadonlyorsuperreadonlysystemvariabledidnotblockconcurrentDDLstatementsexecutedbyuserswithouttheSUPERprivilege。(Bug28438114,Bug91852)
  最后我们再查看下checkreadonly函数,该函数是基于readonly和superreadonly状态执行标准化检查,是禁止(TRUE)还是允许(FALSE)操作。代码如下(sqlauthsqlauthorization。cc:489):briefPerformsstandardizedcheckwhethertoprohibit(TRUE)orallow(FALSE)operationsbasedonreadonlyandsuperreadonlystate。paramthdThreadhandlerparamerrifreadonlyBooleanindicatingwhetherornottoaddtheerrortothethreadcontextifreadonlyisviolated。returnsStatuscoderetvalTRUETheoperationshouldbeprohibited。retvalFALSETheoperationshouldbeallowed。boolcheckreadonly(THDthd,boolerrifreadonly){DBUGENTER(checkreadonly);readonlyOFF,donotprohibitoperation:if(!optreadonly)DBUGRETURN(FALSE);。。。
  此时第一反应就是去检查my。cnf中是否包含readonly相关参数,检查之后发现确实是使用了该参数,如下:〔mysqld〕readonly1
  此时注释掉该参数,然后再次启动mysqld,发现MyISAM表可以自动修复,且正常启动;errorlog信息如下:。。。20200818T11:52:26。77555308:000〔ERROR〕usrlocalmysqlbinmysqld:Table。mysqluserismarkedascrashedandshouldberepaired20200818T11:52:26。77621708:000〔Warning〕Checkingtable:。mysqluser20200818T11:52:26。77627308:000〔ERROR〕1clientisusingorhasntclosedthetableproperly20200818T11:52:26。88253708:000〔Note〕Failedtostartslavethreadsforchannel20200818T11:52:26。90601808:000〔Note〕EventScheduler:Loaded0events20200818T11:52:26。90648008:000〔Note〕usrlocalmysqlbinmysqld:readyforconnections。Version:5。7。31debuglogsocket:varlibmysqlsockmysql。sockport:3306Sourcedistribution
  由于docker一些限制,我们在mysqld启动会涉及两次;所以解决该问题的方式为:第一次mysqld的启动时先关闭readonly参数,第二次启动时开启readonly参数。之所以选择默认开启readonly参数,是为了避免在mysqld启动后,选主逻辑未完成时的保护措施;当然选主完成后,会自动对master执行setglobalreadonly0操作。
  五、总结MySQL小版本的升级也会有变化,一定要做好升级前的度测试工作。MySQL源代码量很多,想要全部了解也很困难;此时我们通过对比不同版本之间的现象差异分别进行调试,找出差异点后再深入探索到某些函数,效果事半功倍。
  六、附录
  调试的栈帧信息如下,有兴趣的小伙伴可以研究下:(gdb)bt0checkreadonly(thd0xcde33f0,errifreadonlytrue)atoptmysqlserversqlauthsqlauthorization。cc:49110x0000000001486262inlocktablenames(thd0xcde33f0,tablesstart0xcdc9100,tablesend0x0,lockwaittimeout31536000,flags0)atoptmysqlserversqlsqlbase。cc:564620x0000000001484be5inOpentablecontext::recoverfromfailedopen(this0x7fffffffcad0)atoptmysqlserversqlsqlbase。cc:478930x0000000001486758inopentables(thd0xcde33f0,start0x7fffffffcb90,counter0x7fffffffcbd4,flags2048,prelockingstrategy0x7fffffffcc10)atoptmysqlserversqlsqlbase。cc:589140x0000000001487851inopenandlocktables(thd0xcde33f0,tables0x7fffffffccd0,flags2048,prelockingstrategy0x7fffffffcc10)atoptmysqlserversqlsqlbase。cc:658350x0000000000ea2611inopenandlocktables(thd0xcde33f0,tables0x7fffffffccd0,flags2048)atoptmysqlserversqlsqlbase。h:48660x0000000000e9c2cfinaclreload(thd0xcde33f0)atoptmysqlserversqlauthsqlauthcache。cc:209170x0000000000e9a2fdinaclinit(dontreadacltablesfalse)atoptmysqlserversqlauthsqlauthcache。cc:142980x0000000000e6f8f2inmysqldmain(argc136,argv0x2c136a8)atoptmysqlserversqlmysqld。cc:495890x0000000000e66cddinmain(argc2,argv0x7fffffffe458)atoptmysqlserversqlmain。cc:32
  熟悉MySQL体系结构和innodb存储引擎工作原理;以及MySQL备份恢复、复制、数据迁移等技术;专注于MySQL、MariaDB开源数据库,喜好开源技术。
  原文链接:https:www。heapdump。cnarticles
投诉 评论 转载

英特尔正式官宣,芯片或将再次涨价,国产电脑系统的机会来了原创不易,禁止洗稿,洗稿,违者必究芯片涨价在缺芯的背景下已经屡见不鲜了,台积电多次上调了代工报价,芯片供应商英特尔也跟随成本,物料的上涨进行涨价。根据台积电预测,明年芯片……2020春季时尚衬衫式连衣裙2020快要穿上美美的连衣裙了,是不是还没准备好什么款式的连衣裙呢?今天这里给大家介绍衬衫式连衣裙,在端庄和休闲之间,给你不娇媚的时髦感,一起往下看看。12020春季时尚衬衫式……冬季衬衫怎么搭配4款内搭衬衫甜美又保暖衬衫是一年四季都可以穿的单品,那么冬天衬衫应该怎么搭配呢?今天昕薇网小编给大家推荐4款衬衫内搭,让你甜美又保暖。1、流苏雪纺娃娃领衬衫这款衬衣是力挺的小翻领,视觉上……衬衫时髦穿搭显瘦且青春有活力衬衫时髦搭配,各种穿搭与众不同的时髦感衬衫的衣角通过打结的方式,能够让你不用学习塞衣角,就能轻松提高腰线。衬衫的衣角打结还可以试试把打结的位置换成后背,这样细微的改……衬衫搭配奶奶裤装显2019早秋的时髦穿搭1、复古格纹衬衫遇上藏青色的奶奶裤,衣身和裤子的松垮,穿出随性与不羁。配戴墨镜,更是让整体的造型更加靓丽。再来一双休闲鞋,就能凹出门。2、白色的衬衫向来都是最简洁干净的,……NBA超越之夜!湖人队比赛票价飙涨,单场比赛净赚1。7亿詹姆斯为洛杉矶湖人带来了什么?短短几场比赛之后,勒布朗詹姆斯将会超越贾巴尔,这场比赛的票价多少?在骑士时期,詹姆斯就已经被视为可以不可避免地会超越天勾卡里姆阿卜杜勒贾巴尔……面试官MySQL权限表损坏导致无法启动怎么办?一、背景近期,公司RDS云产品的MySQLServer版本进行升级,由目前使用的5。7。26版本升级到最新版本5。7。31;升级后测试同学发现:在MySQL创建用户后,5……晚报摩托罗拉纵向卷轴屏手机亮相诺基亚近60年来首次换Logo嗨!尾巴们,晚上好,今天是2月27日晚报导读摩托罗拉Rizr纵向卷轴屏手机亮相五菱凯捷混动铂金版上市小米无线AR眼镜探索版官宣消息称苹果头显无需i……你最爱蝴蝶结出现在哪5款蝴蝶结衬衫告诉你(图)蝴蝶结衬衫的存在早已经成一种习以为常。衣服包包鞋子,项链耳环配饰,都可以有蝴蝶结存在的影子。小小姑娘的公主气息到职场女强人的利落干练,甚至更年长一点,都可以拥有蝴蝶结衬衫。那么……凉鞋搭配网纱露肩衬衫打造夏日文艺范儿凉鞋搭配网纱露肩衬衫绝对是夏日的必备穿搭哦,网纱露肩衬衫不管搭配短裙还是短裤,都能拉长腿部线条,更突显名媛范儿。小编推荐几款网纱露肩衬衫和鞋子的搭配,轻松打造夏日文艺范儿。……金喜善因女儿被质疑,粉丝称孩子小没长开近几年来,随着越来越多的网红的走红,越来愈多长相没有特色的网红开始步入演艺圈。在很多影视作品当中,都能够看见一些长相相似的艺人,这些都是经历过整形的网红或者女艺人。现在的……适合春季的衬衫让你轻松拥有高级时髦感(图)适合春季的衬衫,让你轻松拥有高级时髦感。立春一过,天气就开始逐渐回暖了。春天到了,年也过的差不多了,大家该上班的上班,该上学的上学。又是换季的时候了,穿腻了一整个秋冬厚重的搭配……
小白鞋淋雨怎么处理?小白鞋淋雨后保养方法解析华为FreeBudsPro2领先对手的花招,能打的不只有我的2022,有点难过城南旧事沈洁定居日本,生两个孩子,和老公恩爱至今珍珠项链变黄了怎么办珍珠项链变黄怎么清洗牛仔裤染色剂哪种好?牛仔裤染色不均怎么办?这届红博别样红来主题展太空舱,发射一次火箭吧nautica诺帝卡算是几线牌子nautica诺帝卡是什么档婚鞋要准备几双?结婚要几双婚鞋?badgleymischka鞋子怎么样?结婚选它就对了真正厉害的人,都有这三种特质,往往不简单,再穷也只是暂时的转运珠戒指多少钱转运珠戒指在哪买
有关人生哲理的好段子民事申诉书该怎么写?茶马古道的探究基于地方性的民间视角红米K40游戏增强版怎么激活怎么查激活日期若非是大S老公,谁会知道他发型是纹的?谁会在意他发型是纹的?买苹果手机不爱国,请问买日系车算什么呢?swot什么意思swot怎么解释意外!国安外援离队1年身价狂飙14倍,引来众多欧洲豪门球队哄螺旋藻粉可以做面膜吗?螺旋藻粉做面膜的功效菜鸟和配方师姜黄素睡眠面膜怎么样这效果爱了招募小小医护体验活动,等你来哟!爱护骨骼,从小做起堪称最悲催国脚!年初奔着争冠来如今却要去保级,迄今只出场4次

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找美丽时装彩妆资讯历史明星乐活安卓数码常识驾车健康苹果问答网络发型电视车载室内电影游戏科学音乐整形