當(dāng)前運(yùn)行的所有事務(wù)
專業(yè)從事網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè),高端網(wǎng)站制作設(shè)計(jì),成都微信小程序,網(wǎng)站推廣的成都做網(wǎng)站的公司。優(yōu)秀技術(shù)團(tuán)隊(duì)竭力真誠(chéng)服務(wù),采用html5+CSS3前端渲染技術(shù),成都響應(yīng)式網(wǎng)站建設(shè)公司,讓網(wǎng)站在手機(jī)、平板、PC、微信下都能呈現(xiàn)。建站過(guò)程建立專項(xiàng)小組,與您實(shí)時(shí)在線互動(dòng),隨時(shí)提供解決方案,暢聊想法和感受。
select * from information_schema.innodb_trx
當(dāng)前出現(xiàn)的鎖
select * from information_schema.innodb_locks
鎖等待的對(duì)應(yīng)關(guān)系
select * from information_schema.innodb_lock_waits
通過(guò)找到線程id號(hào),進(jìn)行kill
通過(guò) select * from information_schema.innodb_trx 查詢 trx_mysql_thread_id然后執(zhí)行 kill 線程ID
一、背景
近期,公司RDS云產(chǎn)品的MySQL Server版本進(jìn)行升級(jí),由目前使用的5.7.26版本升級(jí)到最新版本5.7.31;升級(jí)后測(cè)試同學(xué)發(fā)現(xiàn):在MySQL創(chuàng)建用戶后,5.7.31版本重新啟動(dòng)集群會(huì)出現(xiàn)啟動(dòng)失敗的現(xiàn)象;而5.7.26版本在相同測(cè)試場(chǎng)景下是正常啟動(dòng)的。這到底是為什么呢?
二、問(wèn)題復(fù)現(xiàn)
2.1 實(shí)驗(yàn)環(huán)境
2.2 操作步驟
按照測(cè)試同學(xué)的測(cè)試步驟,首先創(chuàng)建一個(gè)用戶:
然后關(guān)閉mysqld;這里需要介紹一下,我們集群的關(guān)閉方式是如下方式:
這種方式的內(nèi)部實(shí)現(xiàn)類似于kill -9模式。所以我在線下環(huán)境使用kill -9的方式來(lái)復(fù)現(xiàn),操作如下:
然后重啟mysqld,操作如下:
此時(shí)問(wèn)題復(fù)現(xiàn)了,mysqld啟動(dòng)失敗,我們查看了下error日志,信息如下:
根據(jù)報(bào)錯(cuò)信息可以看出:MySQL的權(quán)限系統(tǒng)表發(fā)生了損壞,導(dǎo)致了mysqld啟動(dòng)失敗;由于在MySQL 5.7及其之前版本該表是MyISAM引擎,且該引擎不支持事務(wù),所以在mysqld異常崩潰會(huì)導(dǎo)致該類型引擎表的損壞;但在mysqld啟動(dòng)時(shí)是有參數(shù)控制MyISAM引擎的恢復(fù)模式,且該參數(shù)在我們產(chǎn)品中也配置到了my.cnf中,如下所示:
2.3 參數(shù)解析
對(duì)于該參數(shù)的官方文檔的解釋如下:
設(shè)置MyISAM存儲(chǔ)引擎恢復(fù)模式。選項(xiàng)值是OFF、DEFAULT、BACKUP、FORCE或QUICK的值的任意組合。如果指定多個(gè)值,請(qǐng)用逗號(hào)分隔。指定不帶參數(shù)的選項(xiàng)與指定DEFAULT相同,指定顯式值" "將禁用恢復(fù)(與OFF值相同)。如果啟用了恢復(fù),則mysqld每次打開MyISAM表時(shí),都會(huì)檢查該表是否標(biāo)記為已崩潰或未正確關(guān)閉。(只有在禁用外部鎖定的情況下運(yùn)行,最后一個(gè)選項(xiàng)才起作用。)在這種情況下,mysqld在表上運(yùn)行檢查。如果表已損壞,mysqld將嘗試對(duì)其進(jìn)行修復(fù)。
服務(wù)器自動(dòng)修復(fù)表之前,它將有關(guān)修復(fù)的注釋寫到錯(cuò)誤日志中。如果您希望能夠在無(wú)需用戶干預(yù)的情況下從大多數(shù)問(wèn)題中恢復(fù),則應(yīng)使用選項(xiàng)BACKUP,F(xiàn)ORCE。即使某些行將被刪除,這也會(huì)強(qiáng)制修復(fù)表,但是它將舊的數(shù)據(jù)文件保留為備份,以便您以后可以檢查發(fā)生了什么。
全局變量,只讀變量,默認(rèn)為OFF。
三、問(wèn)題修復(fù)
這類MySQL用戶表?yè)p耗的問(wèn)題解決方式也是有多種,我這里列舉其中一種:
(1)my.cnf中的[mysqld]標(biāo)簽下添加skip_grant_tables,啟動(dòng)時(shí)跳過(guò)加載系統(tǒng)字典。
(2)重啟mysqld,然后修復(fù)mysql schema下的所有表。
(3)在[mysqld]標(biāo)簽下注釋或刪除掉skip_grant_tables,然后重啟mysqld。
此時(shí)mysqld是可以正常啟動(dòng)的,無(wú)異常。
四、深入排查
在產(chǎn)品化中,以上修復(fù)方式很不優(yōu)雅,只是作為臨時(shí)的解決方案;并且也存在一些令人疑惑的點(diǎn):
帶著這些疑問(wèn),我們繼續(xù)排查出現(xiàn)該現(xiàn)象的原因;此時(shí)Google也沒(méi)有找到一些有效的信息,那么只能通過(guò)MySQL源代碼來(lái)尋找一些答案。
首先需要下載mysql 5.7.31版本的源代碼,并搭建mysql debug環(huán)境;具體步驟可以自動(dòng)Google搜索一下,本文就不再贅述了。
在源代碼中搜索一下關(guān)鍵詞,用于打斷點(diǎn)的位置,然后進(jìn)行調(diào)試:
定位到相關(guān)代碼,大概是sql/mysqld.cc的4958行,且存在if條件判斷,此時(shí)我們開始調(diào)試:
通過(guò)以上調(diào)試信息,可以判斷出acl_init函數(shù)返回的值為真;此時(shí)我們查看該函數(shù)的代碼 (sql/auth/sql_auth_cache.cc:1365):
根據(jù)該函數(shù)的注釋發(fā)現(xiàn):該函數(shù)是初始化負(fù)責(zé)用戶/數(shù)據(jù)庫(kù)級(jí)特權(quán)檢查的結(jié)構(gòu),并從mysql schema中的表中為其加載特權(quán)信息;且return值為1代表的是初始化權(quán)限失敗。
此后開始逐步調(diào)試,觀察return相關(guān)信息,當(dāng)調(diào)試到lock_table_names函數(shù)時(shí),我們發(fā)現(xiàn)在Phase 3時(shí)return值為true,且根據(jù)代碼注釋發(fā)現(xiàn)true代表是Failure;具體代碼如下(sql/sql_base.cc:5549):
調(diào)試信息如下:
可以看到flags的值為0,而MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK為宏定義值0x1000,與flags的值 做按位與操作,結(jié)果自然也是0,當(dāng)然MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY也是如此;need_global_read_lock_protection是bool類型值,代表是否需要全局讀鎖的保護(hù),這個(gè)值是在table- mdl_request.type不為MDL_SHARED_READ_ONLY發(fā)生改變;check_readonly函數(shù)相關(guān)信息 下面概述。
此時(shí)也查看了下MySQL 5.7.26版本代碼作為對(duì)比,發(fā)現(xiàn)lock_table_names函數(shù)下的Phase 3后的部分代 碼是在5.7.29版本后新增的。如果是git clone的MySQL代碼可以用git blame命令查詢文件變化的信息:
上述展示的信息中,最左側(cè)的列值為commit id為05824063和0405ebee,有興趣的同學(xué)可以詳細(xì)看下。
此功能解決的問(wèn)題是 BUG#28438114: SET READ_ONLY=1 SOMETIMES DOESN'T BLOCK CONCURRENT DDL.;當(dāng)然這個(gè)代碼的變更功能也在5.7 Release Notes中有所體現(xiàn),如下所示( m/doc/relnotes/mysql/5.7/en/news-5-7-29.html ):
最后我們?cè)俨榭聪耤heck_readonly函數(shù),該函數(shù)是基于read_only和super_read_only狀態(tài)執(zhí)行標(biāo)準(zhǔn)化檢查,是禁止(TRUE)還是允許(FALSE)操作。代碼如下(sql/auth/sql_authorization.cc:489):
此時(shí)第一反應(yīng)就是去檢查my.cnf中是否包含read_only相關(guān)參數(shù),檢查之后發(fā)現(xiàn)確實(shí)是使用了該參數(shù), 如下:
此時(shí)注釋掉該參數(shù),然后再次啟動(dòng)mysqld,發(fā)現(xiàn)MyISAM表可以自動(dòng)修復(fù),且正常啟動(dòng);error log信息如下:
由于docker一些限制,我們?cè)趍ysqld啟動(dòng)會(huì)涉及兩次;所以解決該問(wèn)題的方式為:第一次mysqld的啟動(dòng)時(shí)先關(guān)閉read_only參數(shù),第二次啟動(dòng)時(shí)開啟read_only參數(shù)。之所以選擇默認(rèn)開啟read_only參數(shù), 是為了避免在mysqld啟動(dòng)后,選主邏輯未完成時(shí)的保護(hù)措施;當(dāng)然選主完成后,會(huì)自動(dòng)對(duì)master執(zhí)行 set global read_only=0 操作。
五、總結(jié)
六、附錄
調(diào)試的棧幀信息如下,有興趣的小伙伴可以研究下:
熟悉MySQL體系結(jié)構(gòu)和innodb存儲(chǔ)引擎工作原理;以及MySQL備份恢復(fù)、復(fù)制、數(shù)據(jù)遷移等技術(shù);專注于MySQL、MariaDB開源數(shù)據(jù)庫(kù),喜好開源技術(shù)。
原文鏈接:
如果不是root密碼:
連root的密碼也忘記了嗎?
沒(méi)有的話,用root進(jìn)去,修改mysql數(shù)據(jù)庫(kù)user表咯。
如果是root密碼:
方法一:
MySQL提供跳過(guò)訪問(wèn)控制的命令行參數(shù),通過(guò)在命令行以此命令啟動(dòng)MySQL服務(wù)器:
safe_mysqld --skip-grant-tables
即可跳過(guò)MySQL的訪問(wèn)控制,任何人都可以在控制臺(tái)以管理員的身份進(jìn)入MySQL數(shù)據(jù)庫(kù)。
需要注意的是在修改完密碼以后要把MySQL服務(wù)器停掉重新啟動(dòng)才會(huì)生效
方法二:
可以進(jìn)行如下的步驟重新設(shè)置MySQL的root密碼:
1.首先確認(rèn)服務(wù)器出于安全的狀態(tài),也就是沒(méi)有人能夠任意地連接MySQL數(shù)據(jù)庫(kù)。
因?yàn)樵谥匦略O(shè)置MySQL的root密碼的期間,MySQL數(shù)據(jù)庫(kù)完全出于沒(méi)有密碼保護(hù)的
狀態(tài)下,其他的用戶也可以任意地登錄和修改MySQL的信息??梢圆捎脤ySQL對(duì)
外的端口封閉,并且停止Apache以及所有的用戶進(jìn)程的方法實(shí)現(xiàn)服務(wù)器的準(zhǔn)安全
狀態(tài)。最安全的狀態(tài)是到服務(wù)器的Console上面操作,并且拔掉網(wǎng)線。
2.修改MySQL的登錄設(shè)置:
# vi /etc/my.cnf
在[mysqld]的段中加上一句:skip-grant-tables
例如:
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
skip-name-resolve
skip-grant-tables
保存并且退出vi。
3.重新啟動(dòng)mysqld
# /etc/init.d/mysqld restart
Stopping MySQL: [ OK ]
Starting MySQL: [ OK ]
4.登錄并修改MySQL的root密碼
# /usr/bin/mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3 to server version: 3.23.56
Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the buffer.
mysql USE mysql ;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql UPDATE user SET Password = password ( ‘new-password’ ) WHERE User = ‘root’ ;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 2 Changed: 0 Warnings: 0
mysql flush privileges ;
Query OK, 0 rows affected (0.01 sec)
mysql quit
Bye
5.將MySQL的登錄設(shè)置修改回來(lái)
# vi /etc/my.cnf
將剛才在[mysqld]的段中加上的skip-grant-tables刪除
保存并且退出vi。
6.重新啟動(dòng)mysqld
# /etc/init.d/mysqld restart
Stopping MySQL: [ OK ]
Starting MySQL: [ OK ]
windows
1.以系統(tǒng)管理員身份登陸系統(tǒng)。
2.打開cmd—–net start 查看mysql是否啟動(dòng)。啟動(dòng)的話就停止net stop mysql.
3.我的mysql安裝在d:\usr\local\mysql4\bin下。
4.跳過(guò)權(quán)限檢查啟動(dòng)mysql.
d:\usr\local\mysql4\bin\mysqld-nt –skip-grant-tables
5.重新打開cmd。進(jìn)到d:\usr\local\mysql4\bin下:
d:\usr\local\mysql4\bin\mysqladmin -uroot flush-privileges password “newpassword”
d:\usr\local\mysql4\bin\mysqladmin -u root -p shutdown 這句提示你重新輸密碼。
6.在cmd里net start mysql
7.搞定了。
2,MySQL4.1以上版本一種密碼錯(cuò)誤問(wèn)題的解決方法
1 # SET PASSWORD FOR ’some_user’@’some_host’ = OLD_PASSWORD(‘newpwd’);
2 # FLUSH PRIVILEGES;
3,Mysql數(shù)據(jù)庫(kù)修復(fù)
myisamchk -r -q d:\mysql\data\latin1\*
r代表修復(fù)
q代表快速
d:\mysql\data\latin1\*數(shù)據(jù)庫(kù)里面 *代表里面的所有的文件
方法三:
如果你忘記了你的MYSQL的root口令的話,你可以通過(guò)下面的過(guò)程恢復(fù)。
1. 向mysqld server 發(fā)送kill命令關(guān)掉mysqld server(不是 kill -9),存放進(jìn)程ID的文件通常在MYSQL的數(shù)據(jù)庫(kù)所在的目錄中。
kill `cat /mysql-data-directory/hostname.pid`
你必須是UNIX的root用戶或者是你所運(yùn)行的SERVER上的同等用戶,才能執(zhí)行這個(gè)操作。
2. 使用`--skip-grant-tables' 參數(shù)來(lái)啟動(dòng) mysqld。
3. 使用`mysql -h hostname mysql'命令登錄到mysqld server ,用grant命令改變口令。你也可以這樣做:`mysqladmin -h hostname -u user password 'new password''。
(其實(shí)也可以用use mysql; update user set password =password('yourpass') where user='root' 來(lái)做到。)
4. 載入權(quán)限表: `mysqladmin -h hostname flush-privileges' ,或者使用 SQL 命令`FLUSH PRIVILEGES'。(當(dāng)然,在這里,你也可以重啟mysqld。)
方法四:(一定要先備份)
1,重新在另一臺(tái)電腦上安裝相同版本的MySQL
2,刪除忘記密碼的電腦中MySQL安裝目錄中\(zhòng)data\mysql的全部?jī)?nèi)容(要先停止MySQL服務(wù))
3,Copy新裝的電腦上MySQL安裝目錄中\(zhòng)data\mysql的全部?jī)?nèi)容 to 剛剛刪除的目錄中
4,啟動(dòng)MySQL服務(wù)
這樣就只有一個(gè)root用戶了,密碼為空……
解決辦法:
1、檢查下出問(wèn)題之前安裝的程序
2、重裝MYSQL!
你在計(jì)算機(jī)上右鍵屬性然后切換到高級(jí)選項(xiàng)卡之后選擇性能那里的設(shè)置,然后出來(lái)的窗口第三個(gè)選項(xiàng)是數(shù)據(jù)執(zhí)行保護(hù),你看下是不是勾選的除所選之外,為所有應(yīng)用程序和服務(wù)執(zhí)行數(shù)據(jù)保護(hù),如果是,就選擇只為關(guān)鍵Windows應(yīng)用程序執(zhí)行數(shù)據(jù)保護(hù),確定之后然后重啟電腦再看,估計(jì)是這里的問(wèn)題,這個(gè)選項(xiàng)的選擇會(huì)導(dǎo)致很多兼容性的問(wèn)題的,服務(wù)器操作系統(tǒng)主要是為了服務(wù)器而生,所以設(shè)置相比之下比桌面系統(tǒng)更加考慮的安全一點(diǎn),作為桌面系統(tǒng)來(lái)用需要優(yōu)化之后才適合。當(dāng)然如果作為服務(wù)器的話就建議不要去亂優(yōu)化成什么桌面系統(tǒng)了。
mysql system locked 怎么解決
mysql 有 skip locked 功能 1. 注釋/etc/my.cnf里的skip-federated注釋掉即#skip-federated; 2. my.cnf文件配置過(guò)高,重新定義其中的參數(shù)(根據(jù)服務(wù)器情況定義); 3. 殺掉mysql_safe和mysqld進(jìn)程,然后再重啟;