本文目錄一覽:
新手如何調試 MySQL?看這一篇就夠了
前幾天看到姜老師的舊文 用 VSCode 編譯和調試 MySQL,每個 DBA 都應 get 的小技能[1] , 文末留了一個思考題,如何修改源碼,自定義版本,使得 select version() 輸出自定義內容
調試過程參考 macOS VSCode 編譯調試 MySQL 5.7[2]
內部 Item 對象參考 從SQL語句到MySQL內部對象[3]
源碼面前沒有秘密,建義對 DB 感興趣的嘗試 debug 調試。本文環境為 mac + vscode + lldb
vscode 插件:
mysql 源碼:
補丁: MySQL = 8.0.21 需要對 cmake/mysql_version.cmake 文件打補丁 (沒有嚴格測試所有版本)
創建 cmake-build-debug 目錄,後續 mysql 編譯結果,以及啟動後生成的文件都在這裡
在 mysql 工程目錄下面創建 .vscode/settings.json 文件
內容沒啥好說的,都是指定目錄及 boost 配置,其中 WITH_DEBUG 打開 debug 模式,會在 /tmp/debug.trace 生成 debug 信息
View – Command Palette – CMake: Configure 執行後生成 cmake 配置
View – Command Palette – CMake: Build 編譯生成最終 mysql 相關命令
發現老版本編譯很麻煩,各種報錯,mysql 5.7 代碼量遠超過 5.5, 只能硬着頭皮看 5.7
首先初始化 my.cnf 配置,簡單的就可以,共它均默認
初始化數據文件,非安全模式,調試用
由於用 vscode 接管 mysql, 所以需要配置 .vscode/launch.json
然後點擊 run and debug mysqld
mysql 啟動,看到輸出日誌無異常,此時可以用 mysql-client 連接
首先在 sql_parser.cc:5435 處打斷點
mysql_parse 是 sql 處理的入口,至於 tcp connection 連接先可以忽略
執行上述 sql 自動跳轉到斷點處, Step Into , Step Over , Step Out 這些調試熟悉下即可
接下來分別調用主要函數: mysql_execute_command , execute_sqlcom_select , handle_query , select-join-exec() , Query_result_send::send_data , Item::send , Item_string:val_str , Protocol_text::store , net_send_ok
啟動 mysql 時 init_common_variables 會初始化一堆變量,其中會調用 set_server_version 生成版本信息,修改這個就可以
看好條件編譯的是哪塊,修改即可, 重新 CMake: Build 編譯再運行
這裡不做過深分析,簡單講
sql_yacc.cc 函數 PTI_function_call_generic_ident_sys 解析 sql, 識別出 version() 是一個函數調用
find_native_function_builder 查找 hash 表,找到對應 version 函數註冊的單例工廠函數
mysql 啟動時調用 item_create_init 將這些函數 builder 註冊到 hash 表 native_functions_hash
MySQL 代碼太龐大,5.1 大約 100w 行,5.5 130w 行,5.7 以後 330w 行,只能挑重點讀源碼。最近很多群里的人在背八股,沒必要,有那時間學着調試下源碼,讀讀多好
原文出處:
為什麼安裝mysql數據庫報錯
我遇到同樣的錯誤,折騰了好久才摸索出來。網上的解決辦法都試過了,沒有確實可行的。最終總結出來,終於解決了。
我的下載的是mysql-5.7.9綠色版出的問題。最終解決過程供你參考:
1、下載的mysql-5.7.9,出現你的問題。試了各種辦法無法解決。有網友說mysql-5.7.9版本有問題。我改下載了5.6.27版本,嘗試不成功。但報錯變為:無法啟動mysql服務,發生錯誤1067。解決辦法:my.ini 添加 tmpdir = D:\mysql-5.6.27-winx64\data。問題解決。
2、後來我對比了mysql-5.7.9與5.6.27,發現mysql-5.7.9-winx64沒有data目錄,mysql-5.6.27-winx64\data\mysql,存了不少數據文件。原來調試5.7.9的版本時,記得日誌報告一直有mysql.user、mysql.plugin不存在的提示。(原以為這些文件會自動生成)。後來把這個mysql-5.6.27-winx64\data下的mysql文件夾整個複製到5.7.9版本中的同目錄下。問題解決。
mysql啟動錯誤
一、無法訪問系統資源
MySQL 不能訪問啟動需要的資源是造成而 MySQL 無法啟動的一個常見原因,如:文件,端口等。由於 linux 中用於啟動 mysqld 進程的 mysql 用戶通常是不能登陸的,可以使用類似下面的命令檢查文件的訪問權限。
sudo -u mysql touch /var/lib/mysql/b
找出問題後,修改對應文件或目錄的權限或屬主後通常可以解決問題。但有時 mysql 用戶有訪問文件和目錄的權限,但仍然會被拒絕訪問,例如下面這個例子:
mysql system sudo -u mysql touch /home/mysql/data/a
mysql create table t1 (
id int primary key,n varchar(10
) data directory
ERROR 1030 (HY000): Got error 168 from storage engine
測試說明 mysql 用戶有這個目錄的訪問權限,但創建文件還是失敗,這種情況讓很多人困惑,這個時候通常是 mysqld 進程的訪問被 linux 的 selinux 或 apparmor 給阻止了,大家可以看到創建的表不是在 mysql 的默認目錄下面,因此 selinux 或 apparmor 的 policy 裡面沒有包含這個目錄的訪問權限,此時只要對應的修改 policy 就行了,當然把 selinux 或 apparmor 停了也行。
有時雖然對系統資源有訪問的權限,但系統資源已經被佔用:
mysqld –no-defaults –console –user mysql
2020-11-03T03:36:07.519419Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.0.19) starting as process 21171
2020-11-03T03:36:07.740347Z 1 [ERROR] [MY-012574] [InnoDB] Unable to lock ./ibdata1 error: 11
這個故障產生的原因是另外一個 mysqld 進程已經啟動並佔用了對應的文件。
二、參數設置錯誤
參數設置錯誤造成 MySQL 無法啟動的原因也非常常見,此時先要檢查 MySQL 啟動時會調用的參數,下面的命令可以查詢 MySQL 啟動時調用參數文件的順序:
$ mysqld –verbose –help | grep “Default options ” -A 1
Default options are read from the following files in the given order:
/etc/my.cnf /etc/mysql/my.cnf ~/.my.cnf
知道了 MySQL 參數文件的調用順序,我們就可以檢查對應的參數文件,找出其中的錯誤,如果覺得參數文件的可讀性不強,可以使用下面的命令顯示 mysqld 程序將要調用的參數:
$ mysqld –print-defaults
/usr/sbin/mysqld would have been started with the following arguments:
……
注意這個命令顯示完參數後就退出,不會真正運行 mysqld。這個命令和 my_print_defaults mysqld 完全是等價的,只不過後者的顯示方式是一行一個參數。
然後開始對可疑的參數進行調試,我個人喜歡加的參數和順序如下:
1. 在 mysqld 後加上第一個參數 –no-defaults ,這個參數的作用是通知 mysqld 在啟動的時候不要讀任何參數文件;
2. 第二個參數是 –console,這個參數會把錯誤信息輸出到屏幕上,這個參數帶來的一個弊端是所有的信息都輸出到屏幕上,讓屏幕顯得比較亂,但對於我們調試卻是很方便的;
3. 第三個參數是 –log-error-verbosity=3,這個參數會顯示詳細的日誌;
4. 然後再在後面加上有把握的參數,可以一次只加一個參數,然後啟動 mysqld,採用排除法逐步找出錯誤的參數。
如何輕鬆解決MYSQL數據庫連接過多的錯誤
1、MySQL數據庫系統允許的最大可連接數max_connections。這個參數是可以設置的。如果不設置,默認是100。最大是16384。
2、數據庫當前的連接線程數threads_connected。這是動態變化的。
查看max_connections、max_connections的辦法見後。
如果
threads_connected
==
max_connections
時,數據庫系統就不能提供更多的連接數了,這時,如果程序還想新建連接線程,數據庫系統就會拒絕,如果程序沒做太多的錯誤處理,就會出現類似強壇的報錯信息。
因為創建和銷毀數據庫的連接,都會消耗系統的資源。而且為了避免在同一時間同時打開過多的連接線程,現在編程一般都使用所謂數據庫連接池技術。
但數據庫連接池技術,並不能避免程序錯誤導致連接資源消耗殆盡。
這種情況通常發生在程序未能及時釋放數據庫連接資源或其他原因造成數據庫連接資源不能釋放,但強壇系統估計不會發生這種低級的編程錯誤。
該錯誤的簡便的檢查辦法是,在刷新強壇頁面時,不斷監視threads_connected的變化。如果max_connections足夠大,而
threads_connected值不斷增加以至達到max_connections,那麼,就應該檢查程序了。當然,如果採用數據庫連接池技術,
threads_connected增長到數據庫連接池的最大連接線程數時,就不再增長了。
從強壇出錯的情況看,更大的可能性是數據庫系統沒能進行適當地配置。下面提出一點建議。供參考
讓你們的工程師把MySQL的最大允許連接數從默認的100調成32000。這就不會老出現連接過多的問題了。
查看max_connections
進入MySQL,用命令:
show
variables
查看數據庫最大可連接數的變量值:
max_connections
查看threads_connected
進入MySQL,用命令:
show
status
查看當前活動的連接線程變量值:
threads_connected
設置max_connections
設置辦法是在my.cnf文件中,添加下面的最後紅色的一行:
[mysqld]
port=3306
#socket=MySQL
skip-l
如何解決MySQL問題
1、情況一:MySQL的錯誤日誌文件(安裝目錄\MYOA\data5\機器名.err)會記錄如下內容:
InnoDB: Reading tablespace information from the .ibd files…
InnoDB: Error: trying to add tablespace 460 of name ‘.\td_oa\flow_data_35.ibd’
InnoDB: to the tablespace memory cache, but tablespace
InnoDB: 460 of name ‘.\td_oa\exam_data.ibd’ already exists in the tablespace
解決方法:
1)剪切出安裝目錄\MYOA\data5\TD_OA的flow_data_35.ibd和flow_data_35.frm兩個文件;
2)啟動MySQL5_OA服務,使用備份的flow_data_35.sql導入到TD_OA庫中。如果提示flow_data_35表已經存在不能導入,則繼續按後續步驟執行;
3)在data5下手動建立tmp目錄;
4)使用MySQL管理工具或MySQL命令行程序在tmp下建立名稱為flow_data_35的表(包含一個字段即可);
5)將tmp下的flow_data_35.frm和flow_data_35.ibd拷貝到安裝目錄\MYOA\data5\TD_OA目錄下;
6)在MySQL管理工具或MySQL命令行程序中,進入TD_OA庫,使用“drop table flow_data_35;”命令清除公共表空間中殘留的flow_data_35表的相關信息;
7)進入tmp庫,刪掉flow_data_35表;
8)使用備份的flow_data_35.sql導入到TD_OA庫中;
9)如果還有其他表存在該問題,可重複執行4至8步驟。
2、情況二:MySQL的錯誤日誌文件(安裝目錄\MYOA\data5\機器名.err)會記錄如下內容:
130409 15:54:31 [Note] Plugin ‘FEDERATED’ is disabled.
130409 15:54:31 InnoDB: The InnoDB memory heap is disabled
130409 15:54:31 InnoDB: Mutexes and rw_locks use Windows interlocked functions
130409 15:54:31 InnoDB: Compressed tables use zlib 1.2.3
130409 15:54:32 InnoDB: Initializing buffer pool, size = 1023.0M
InnoDB: VirtualAlloc(1086849024 bytes) failed; Windows error 8
130409 15:54:32 InnoDB: Completed initialization of buffer pool
130409 15:54:32 InnoDB: Fatal error: cannot allocate memory for the buffer pool
130409 15:54:32 [ERROR] Plugin ‘InnoDB’ init function returned error.
130409 15:54:32 [ERROR] Plugin ‘InnoDB’ registration as a STORAGE ENGINE failed.
130409 15:54:32 [ERROR] Unknown/unsupported storage engine: Innodb
130409 15:54:32 [ERROR] Aborting
解決方法:
此情況出現的原因是myoa\mysql5\my.ini中innodb_buffer_pool_size的值太大,OA服務器操作系統不支持所致。改小後再啟動mysql5_OA服務即可,一般保持和數據庫大小一致。數據庫大小即是myoa/data5的大小。
3、情況三:mysql服務啟動不了,事件查看器中顯示:The syntax
‘–log-slow-queries’ is deprecated and will be removed in a future
release. Please use ‘–slow-query-log’/’–slow-query-log-file’ instead.
解決方法:安裝目錄\MYOA\data5下的ibdata1、ib_logfile0、ib_logfile1文件屬性被設置為只讀導致,取消只讀控制,重啟mysql5_OA服務即可。
4、情況四:MySQL的錯誤日誌文件(data5\機器名.err)會記錄如下內容:InnoDB: No valid checkpoint found.
解決方法:此問題找不到檢查點,數據庫是無效的,此種情況,只能用熱備份數據恢復。
5、以上四種情況,是2013版OA系統目前比較常見的mysql服務啟動不了的現象和解決辦法,大家可作參考,其他情況的話,再具體分析處理。
6、分析思路總結:遇到mysql5_OA服務啟動不了的情況,首先查看myoa\data5下的錯誤日誌文件,根據日誌中的具體內容進行具體分析。
7、2013版MYSQL服務啟動不了(可以嘗試強制啟動mysql服務)方法如下:
1)打開\MYOA\mysql5\my.ini,去掉innodb_force_recovery=1前邊的注釋。
2)啟動MySQL5_OA服務,此時MySQL處於只讀狀態,可以導出,不可寫入。如果仍不能啟動,可以嘗試將innodb_force_recovery修改為2、3、4、5、6等,直到可以啟動為止。
3)使用MySQL管理工具,將TD_OA等相關的數據庫導出為SQL文件。
4)停止MySQL5_OA服務,刪除TD_OA下的所有文件、ibdata1、ib_logfile0、ib_logfile1等文件。
5)打開\MYOA\mysql5\my.ini,在innodb_force_recovery=1前邊加上#號,將該項注釋掉。
6)啟動MySQL5_OA服務,然後導入此前備份的SQL文件。
7)檢查數據庫,將無法通過該方法恢復的數據表,通過之前自動備份的SQL文件進行恢復。
原創文章,作者:FTF79,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/129369.html