Mysql

從 MySQL 數據庫修復/恢復數據

  • January 31, 2022

我對儲存在我的樹莓派(InnoDB 引擎)上的 MySQL 數據庫有一個大問題。我不是這個領域的專家,但我會盡力向你解釋這個問題。

每次我嘗試啟動 MySQL 時都會崩潰,我需要恢復儲存在數據庫中的數據。錯誤是:

error: 'Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock'

我只是嘗試使用從 1 到 6 的 innodb_force_recovery 標誌啟動 MySQL,但它仍然崩潰。從日誌中我了解到問題是某些表中的損壞。

我試圖用https://recovery.twindb.com/檢查我的數據庫文件,它顯示“mysql”數據庫中的一些表需要恢復,“生產”數據庫(我的)中的表是好的,確實我可以在這個網站上看到我所有的數據。如何輕鬆恢復我的數據?我可以使用一些免費的工具或腳本嗎?我的所有文件都是 ibdata01、.frm、.ibd

更新#1:

/etc/mysql/my.cnf

   #
# The MySQL database server configuration file.
#
# You can copy this to one of:
# - "/etc/mysql/my.cnf" to set global options,
# - "~/.my.cnf" to set user-specific options.
# 
# One can use all long options that the program supports.
# Run program with --help to get a list of available options and with
# --print-defaults to see which it would actually understand and use.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html

#
# * IMPORTANT: Additional settings that can override those from this file!
#   The files must end with '.cnf', otherwise they'll be ignored.
#

!includedir /etc/mysql/conf.d/
!includedir /etc/mysql/mysql.conf.d/

/etc/mysql/mysql.conf.d/mysqld.cnf

#
# The MySQL database server configuration file.
#
# You can copy this to one of:
# - "/etc/mysql/my.cnf" to set global options,
# - "~/.my.cnf" to set user-specific options.
# 
# One can use all long options that the program supports.
# Run program with --help to get a list of available options and with
# --print-defaults to see which it would actually understand and use.
#
# For explanations see
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html

# This will be passed to all mysql clients
# It has been reported that passwords should be enclosed with ticks/quotes
# escpecially if they contain "#" chars...
# Remember to edit /etc/mysql/debian.cnf when changing the socket location.

# Here is entries for some specific programs
# The following values assume you have at least 32M ram

[mysqld_safe]
socket      = /var/run/mysqld/mysqld.sock
nice        = 0

[mysqld]
#
# * Basic Settings
#
user        = mysql
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
port        = 3306
basedir     = /usr
datadir     = /var/lib/mysql
tmpdir      = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
#
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address        = 127.0.0.1
#
# * Fine Tuning
#
key_buffer_size     = 16M
max_allowed_packet  = 16M
thread_stack        = 192K
thread_cache_size       = 8
# This replaces the startup script and checks MyISAM tables if needed
# the first time they are touched
myisam-recover-options  = BACKUP
#max_connections        = 100
#table_open_cache       = 64
#thread_concurrency     = 10
#
# * Query Cache Configuration
#
query_cache_limit   = 1M
query_cache_size        = 16M
#
# * Logging and Replication
#
# Both location gets rotated by the cronjob.
# Be aware that this log type is a performance killer.
# As of 5.1 you can enable the log at runtime!
#general_log_file        = /var/log/mysql/mysql.log
#general_log             = 1
#
# Error log - should be very few entries.
#
log_error = /var/log/mysql/error.log
#
# Here you can see queries with especially long duration
#slow_query_log     = 1
#slow_query_log_file    = /var/log/mysql/mysql-slow.log
#long_query_time = 2
#log-queries-not-using-indexes
#
# The following can be used as easy to replay backup logs or for replication.
# note: if you are setting up a replication slave, see README.Debian about
#       other settings you may need to change.
#server-id      = 1
#log_bin            = /var/log/mysql/mysql-bin.log
expire_logs_days    = 10
max_binlog_size   = 100M
#binlog_do_db       = include_database_name
#binlog_ignore_db   = include_database_name
#
# * InnoDB
#
# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.
# Read the manual for more InnoDB related options. There are many!
#
# * Security Features
#
# Read the manual, too, if you want chroot!
# chroot = /var/lib/mysql/
#
# For generating SSL certificates I recommend the OpenSSL GUI "tinyca".
#
# ssl-ca=/etc/mysql/cacert.pem
# ssl-cert=/etc/mysql/server-cert.pem
# ssl-key=/etc/mysql/server-key.pem

如果我嘗試在沒有 innodb_force_recovery 標誌的情況下啟動 mysql,結果如下:

pc@pc-hp:/$ sudo service mysql start
Job for mysql.service failed because the control process exited with error code.
See "systemctl status mysql.service" and "journalctl -xe" for details.

這是error.loghttps ://pastebin.com/eeSuMxBT

您可以使用Undrop for InnoDB,這是 recovery.twindb.com 背後的工具。要恢復損壞的數據庫,您需要按照https://twindb.com/recover-corrupt-mysql-database/中的步驟操作

解析ibd文件:

# ./stream_parser -f /var/lib/mysql/sakila/actor.ibd

PRIMARY 索引中的轉儲記錄:

# ./c_parser -6f pages-actor.ibd/FIL_PAGE_INDEX/0000000000000015.page \
   -t sakila/actor.sql \
   > dumps/default/actor 2>&1 dumps/default/actor_load.sql

然後載入轉儲:

# mysql --local-infile sakila < dumps/default/actor_load.sql

*解決方案 1(如果 .ibd 文件很好):

  • 備份所有數據的 /var/lib/MySQL 文件夾
  • 刪除 /var/lib/MySQL 並使用mysql_install_db命令初始化數據文件夾,以免錯過 *.cnf 文件

或全新安裝 mysql

  • 創建新數據庫作為要恢復的數據庫
  • 使用正確的模式創建所有表(您可以使用每個表的 *.frm 文件來恢復它們,線上有一些工具)
  • 刪除 mysql 中的所有表空間ALTER TABLE "tableName" DISCARD TABLESPACE; (您可以使用簡單的 bash 腳本為每個表執行此操作)
  • 將所有備份的 *.idb 文件複製到 /var/lib/mysql/yourdb 文件夾
  • 您可能必須使用 sudo 為文件設置正確的權限chown -R mysql:mysql /var/lib/mysql
  • 導入mysql中的所有表空間ALTER TABLE "tableName" IMPORT TABLESPACE;

在此過程之後,您將在數據庫中恢復所有數據。

*解決方案 2(如果 .idb 可能已損壞):

  • 下載 undrop-for-innodb 並編譯
  • 執行./stream_parser -f /var/lib/mysql/ibdata1
  • 對每個 *.ibd 文件執行./stream_parser -f /var/lib/mysql/yourdatabase/your_ibd.ibd
  • 在 YOUR_DB/YOUR_TABLE.sql 中創建每個表的 CREATE TABLE 語句
  • 執行./c_parser -6f pages-YOUR_TABLE.ibd/FIL_PAGE_INDEX/FIRST_FILE_OF_FOLDER.page \-t YOUR_DB/YOUR_TABLE.sql \ > dumps/default/YOUR_TABLE 2> dumps/default/YOUR_TABLE_load.sql
  • 初始化一個新的空數據庫並使用正確的模式創建所有表(您可以使用 YOUR_DB/YOUR_TABLE.sql 文件)
  • 使用 /dumps/default/YOUR_TABLE_load.sql 文件導入所有數據

引用自:https://dba.stackexchange.com/questions/217352