MySQL 資料修復 (Force InnoDB Recovery)

前言 在日常維運中,MySQL 的數據庫可能因各種原因遭到損壞,例如硬碟故障、斷電等。最近工作上就遇到客戶環境出現異常的現象,資料庫疑似寫入壞資料導致 MySQL 不斷跳出此錯誤 Operation cannot be performed. The table 'xxx' is missing, corrupt or contains bad data. 當下處理時還一頭霧水,因為根本無法查詢資料,SELECT 資料時,該資料表都會跳出此錯誤訊息,連資料都無法 query,又該怎麼知道哪裡有壞資料呢? Forcing InnoDB Recovery 針對這種棘手的情況 MySQL 提供了 InnoDB 強制恢復模式(InnoDB Force Recovery) 來協助修復損壞數據。此模式允許管理人員在無法啟動的情況下訪問資料並嘗試進行修復。 MySQL 設定檔 以下是用 MySQL 5.7.30 的環境 具體操作如下: 首先,要先找到 MySQL 的設定檔 (my.cnf),通常會位於底下幾種路徑 (Docker container 也是一樣) /etc/my.cnf /etc/mysql/my.cnf $MYSQL_HOME/my.cnf [datadir]/my.cnf ~/.my.cnf 如果都找不到的話,可以執行 mysql --help,從輸出的 log 中去找 my.cnf 可能的檔案路徑 Default options are read from the following files in the given order: /etc/my....

<span title='2024-10-20 19:49:13 +0800 +0800'>October 20, 2024</span>&nbsp;·&nbsp;2 min&nbsp;·&nbsp;219 words&nbsp;·&nbsp;Madi

MySQL 備份筆記

前言 最近工作的專案是使用 Java SpringBoot 搭配 MySQL 資料庫做數據儲存與管理,部署在客戶環境時需要備份資料,為了有效地完成備份工作,使用 MySQL 常見的備份工具 - mysqldump,但過程中牽涉到很多參數的用途,所以有了這篇文章做紀錄,以供未來參考 什麼是 mysqldump? mysqldump 是 MySQL 提供的一個命令行工具,用於備份資料庫。它可以生成 SQL 語句,這些語句可以用於重建資料庫的結構和數據。這使得 mysqldump 成為一個非常靈活且易於使用的備份解決方案 基本語法 mysqldump [options] database [tables] database 是你要備份的資料庫名稱 tables 是可選的,表示你可以指定要備份的特定表 常用用途 備份整個資料庫 要備份整個資料庫,可以使用以下指令: mysqldump -u username -p database_name > backup.sql -u: 用於指定用戶名 -p: 會提示輸入密碼 backup.sql: 是你要生成的備份文件名 備份特定表 如果只想備份特定的表,可以這樣做: mysqldump -u username -p database_name table1 table2 > backup.sql 這將備份 table1 和 table2 兩個表 常用參數 (Options) 底下列出在實際備份時,個人有使用到的一些參數,如果要了解全部的參數意義,可參考 官方文件 需格外注意的是 MySQL 有區分幾種 engine,最常見的就是 MyISAM 和 InnoDB,前者是 non-transactional,後者才是 transactional,這會影響到備份時是否需要鎖表,以及帶來的效能影響與資料一致性的差異...

<span title='2024-09-10 19:49:13 +0800 +0800'>September 10, 2024</span>&nbsp;·&nbsp;2 min&nbsp;·&nbsp;241 words&nbsp;·&nbsp;Madi

初探傳統關聯式資料庫如何處理高併發情境

前言 近年來隨著網路發展愈來愈快,高併發的場景愈來愈常見,高併發性能是指系統能夠有效地處理大量同時訪問和操作數據的能力,這在網路應用、金融系統、電子商務等領域愈來愈重要.隨著數據量的不斷增長和用戶需求的不斷擴展,我們需要確保我們的資料庫系統能夠承受高負載、高併發的壓力,同時保持良好的性能和穩定性。在這樣的背景下,優化資料庫的設計和架構、實施有效的併發控制策略成為至關重要的任務。 本篇是研究了一般 RDBMs 如何處理高併發問題的常見解法 Lock 機制 我們都知道寫程式的時候,如果有兩個 process/thread 要對同筆資料進行操作,為了避免資料的不一致,我們常會加上鎖的機制,臨時將該資源上鎖,僅允許一次只能被一個 process/thread 更動.同樣的,RDBMs 也有相同的機制來處理這種情形,這也是傳統資料庫處理高併發的最基本原理 SELECT … FOR UPDATE 為了避免兩個 transaction 同時對同筆資料進行操作,造成資料不一致的問題,一般常見的 RDBMs 都有提供底下這個 SQL 語法 BEGIN SELECT ... FOR UPDATE <各式針對該資料的操作, ex: UPDATE, DELETE...> COMMIT 一旦開啟新的 transaction 並執行這段 SQL 語法,在還沒 COMMIT 以前,資料庫將會替當前這筆資料加上鎖,鎖住這些即將要被更動的資料,因為資料庫悲觀的認為他們隨時有可能被修正(悲觀鎖),一旦上鎖後,下一個 tx 要進行操作時,都需要等待該鎖釋放後才能進行 至於這個鎖是行級鎖還是表級鎖,以及這個排他鎖會鎖哪些操作(SELECT? INSERT? UPDATE? DELETE?),則因各種資料庫背後的機制而不同 以 MySQL(InnoDB)為例,如果 SELECT 的對象加上 WHERE 條件是主鍵或有加上索引,則僅會加上行級鎖,鎖住當前查詢到的資料.但如果 WHERE 條件不是主鍵或非索引,則整個資料表都會被鎖住.正因如此,一旦 SELECT ... FOR UPDATE 沒寫好,MySQL 是有可能把整個資料表都鎖住,造成其他 transaction 需要等待鎖釋放才能進行操作,進而增加 latency 而影響使用者體驗.(以上前提要是 MySQL 的 InnoDB 作為 storage engine,因為 MyISAM 預設都是表級鎖)...

<span title='2024-05-05 00:49:13 +0800 +0800'>May 5, 2024</span>&nbsp;·&nbsp;3 min&nbsp;·&nbsp;611 words&nbsp;·&nbsp;Madi