資料庫核心月報-2015/09-MySQL·捉蟲動態·建表過程中crash造成重建表失敗
問題描述
主庫的create table
語句傳到備庫,備庫SQL執行緒執行過程中報錯:
Error `Can`t create table `XXX.XX` (errno: -1)` on query. Default database: `XXX`. Query: `CREATE TABLE XX ( column_a char(32) NOT NULL, column_b int(10) DEFAULT NULL, column_c int(10) DEFAULT NULL, PRIMARY KEY (column_a), KEY expiry (column_b)) ENGINE=HEAP DEFAULT CHARSET=gbk`
備庫 error log:
InnoDB: Error number 17 means `File exists`.
InnoDB: Some operating system error numbers are described at
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/operating-system-error- codes.html
InnoDB: The file already exists though the corresponding table did not
InnoDB: exist in the InnoDB data dictionary. Have you moved InnoDB
InnoDB: .ibd files around without using the SQL commands
InnoDB: DISCARD TABLESPACE and IMPORT TABLESPACE, or did
InnoDB: mysqld crash in the middle of CREATE TABLE?You can
!!!InnoDB: resolve the problem by removing the file `...`
InnoDB: under the `datadir` of MySQL.
從error log中可以看出,資料目錄中已存在 .ibd 檔案,推測是在建表過程中發生 crash。
資料目錄下存在 .ibd,不存在 .frm,建立.ibd 檔案的時間:
-rw-rw---- 1 mysql mysql 65536 Sep 5 14:41 XXX.ibd
.ibd 檔案建立時間 150905 14:41,對應時間的 error log:
150905 14:41:58 mysqld_safe Number of processes running now: 0
150905 14:41:58 mysqld_safe mysqld restarted
之後也出現了和該建立失敗的表相關的錯誤記錄:
150905 14:59:45 InnoDB: Error: table `XXX`.`XX` does not exist in the InnoDB internal
問題分析
執行如下語句,模擬建表
create table test.t3 (id int);
create table
時,由函式mysql_create_frm
建立 .frm 檔案,mysql_create_frm
呼叫棧如下:
#0 mysql_create_frm
#1 rea_create_table
#2 mysql_create_table_no_lock
#3 mysql_create_table
#4 mysql_execute_command
#5 mysql_parse
t3.frm 檔案生成後,例項 crash(函式mysql_create_frm
執行完畢後kill mysqld
),在資料庫中show tables
可以看到 test.t3,但是無法插入,資料目錄下 t3.frm 檔案依然存在。
drop table
報錯
ERROR 1051 (42S02): Unknown table `test.t3`
之後資料目錄下的t3.frm不存在,show tables 無法看到t3表,可以重新建立t3表。
.ibd 檔案由函式fil_create_new_single_table_tablespace
建立,fil_create_new_single_table_tablespace
呼叫棧如下:
#0 fil_create_new_single_table_tablespace
#1 dict_build_table_def_step
#2 dict_create_table_step
#3 que_thr_step
#4 que_run_threads_low
#5 que_run_threads
#6 row_create_table_for_mysql
#7 create_table_def
#8 ha_innobase::create
#9 handler::ha_create
#10 ha_create_table
#11 rea_create_table
#12 create_table_impl
#13 mysql_create_table_no_lock
#14 mysql_create_table
#15 mysql_execute_command
#16 mysql_parse
t3.ibd 檔案生成後,例項 crash(函式fil_create_new_single_table_tablespace
執行完畢後kill mysqld
),在資料庫中show tables
可以看到 test.t3,無法插入資料,在資料目錄下存在檔案 t3.frm 和 t3.ibd。
drop table
依然可以移除 t3.frm 並使show tables
無法看到 t3 表。但無法移除 t3.ibd,並在重建 t3 表時報錯:
ERROR 1813 (HY000): Tablespace for table ``test`.`t3`` exists. Please DISCARD the tablespace before IMPORT.
在資料目錄中刪除 t3.ibd ,可以正常重建 t3 表。
這個 bug 的主要原因是 MySQL 的建表過程不是原子操作。如果建表過程正在進行的時候例項 crash,可能會造成一些在例項重啟後無法自動恢復的問題。就像這個問題當中的檔案殘留,無法通過 MySQL 客戶端中的操作解決,只能手動刪除檔案。如果使用者是遠端連線資料庫,又沒有登入伺服器運算元據檔案的許可權,就會影響資料庫的可用性。
MySQL 5.7 的實驗室版本正在設計和實現新版本的資料字典來解決這一問題。這個版本主要由以下幾個特性:
- 資料字典將實現事務儲存,首先利用 InnoDB 儲存,其他儲存引擎可能會跟進開發;
- 把分散式系統中的字典資訊統一成一個整體;
- 使用統一的規則儲存字典資訊,給字典物件定義統一的API;
- 避免檔案系統特性帶來的問題。
詳細資訊參見MySQL Server Blog
問題解決
通過問題分析,判斷備庫無法建表是由於在執行create table
語句時備庫例項crash,且crash時.ibd 檔案已存在。使用者發現表建立失敗,企圖重建表依然失敗,之後執行了drop table
語句,移除了.frm檔案,但.ibd檔案依然存在,無法重建表。
將資料目錄下的.ibd檔案移到其他資料夾作為備份,在備庫start slave
後建表成功,主備複製正常。
相關文章
- MySQL核心月報2014.10-MySQL· 捉蟲動態·binlog重放失敗MySql
- MySQL核心月報2015.03-MySQL·捉蟲動態·pidfile丟失問題分析MySql
- beego自動建表失敗Go
- openGauss核心分析(九):資料庫表的建立過程資料庫
- ORACLE 資料庫分析,重新編譯失敗過程Oracle資料庫編譯
- 【SQL】Oracle資料庫通過job定期重建同步表資料SQLOracle資料庫
- 資料庫建表-表中列的性質資料庫
- informix資料庫啟動失敗ORM資料庫
- 用儲存過程動態建立表儲存過程
- 資料庫核心月報-2015/07-MySQL·社群動態·MySQL記憶體分配支援NUMA資料庫MySql記憶體
- 故障分析 | DROP 大表造成資料庫假死資料庫
- GreatSQL資料庫DROP表後無法重建SQL資料庫
- Mysql 資料庫水平分表 儲存過程MySql資料庫儲存過程
- 刪除資料泵備份失敗的表
- sql server資料庫連線失敗/無法附加解決過程SQLServer資料庫
- Sqlite嵌入式資料庫的安裝、建庫、建表、更新表結構以及資料匯入匯出等等詳細過程記錄SQLite資料庫
- 使用AnalyticDB MySQL建立資料庫及表過程MySql資料庫
- 報表從資料庫中採集相關資料生成報表,資料太少怎麼辦?資料庫
- 資料庫分庫,原來 SQL 和儲存過程寫的報表咋辦?資料庫SQL儲存過程
- 動態sql 報表SQL
- ActiveReports 報表應用教程 (8)---互動式報表之動態過濾
- RestCloud ETL抽取動態庫表資料實踐RESTCloud
- 資料庫-單表結構-建表語句資料庫
- 報表資料庫4031資料庫
- 怎樣報表資料庫資料庫
- 報表怎麼動態選擇資料來源
- 在資料庫設計中,狀態欄位(如status)用0代表成功還是失敗,有所謂嗎?資料庫
- 資料庫擴充套件表設計過程記錄資料庫套件
- 資料庫建表效率為王資料庫
- mysql對資料庫表建索引MySql資料庫索引
- MySQL·捉蟲動態·唯一鍵約束失效MySql
- 複雜報表設計之動態報表
- 惡意程式造成資料庫啟動報錯資料庫
- 資料庫啟動過程資料庫
- 資料庫核心月報-2015/11-MySQL·特性分析·StatementDigest資料庫MySql
- RAC建庫失敗了
- MySQL超大表刪除資料過程MySql
- 使用Huge Pages後資料庫啟動失敗資料庫