Is there a way to flush ib_logfile0 and ib_logfile1 without dumping the tables to a .sql file, deleting, then re-inserting? Somebody entered a couple plain text credit card numbers into the customer notes table. It came up in my PCI scan and I removed them from the table but they still exist in the log files 🙁
MySQL – How to Flush/Clean ib_logfile0 and ib_logfile1
innodblogsMySQL
Related Solutions
I have very bad news for you.
You should not have deleted the ibdata1 file. Here is why:
ibdata1 contains four type of information:
- table metadata
- MVCC data
- data pages (with innodb_file_per_table enabled)
- index pages (with innodb_file_per_table enabled)
Each InnoDB table created has a numercial id assigned to it via some auto increment metadata feature to each ibd file. That internal tablespace id (ITSID) is embedded in the .ibd file. That number is checked against the list of ITSIDs maintained, guess where, ... ibdata1.
I also have very good news for you along with some bad news.
It is possible to reconstruct ibdata1 to have the correct ITSIDs but it takes work to do it. While I personally have not done procedure alone, I assisted a client at my employer's web hosting to do this. We figured this out together but since the client hosed ibdata1, I let him do most of the work (30 InnoDB tables).
To cut right to the chase, here is the article explaining what to do with reference to ITSID and how to massage ibdata1 into acknowledging the presence of the ITSID contained within the .ibd file.
I am sorry there is no quick-and-dirty method for recovering the .ibd file other than playing games with ITSIDs.
UPDATE 2011-10-17 06:19 EDT
Here is your original innodb configuration from your question:
innodb_file_per_table=1
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G
innodb_data_file_path=ibdata1:10M:autoextend
innodb_buffer_pool_size = 384M
innodb_log_file_size=5M
innodb_lock_wait_timeout = 18000
Please notice that innodb_log_file_size is there twice. Look carefully...
innodb_file_per_table=1
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G <----
innodb_buffer_pool_size=4G
innodb_data_file_path=ibdata1:10M:autoextend
innodb_buffer_pool_size = 384M
innodb_log_file_size=5M <----
innodb_lock_wait_timeout = 18000
The last setting of innodb_log_file_size takes precedence. MySQL expected to start up with the log files being 5M. Your ib_logfile0 and ib_logfile1 were 1G when you tried to start up mysqld. It saw a size conflict and took the path of least resistance, which was to disable InnoDB. That's why InnoDB was missing from show engines;
. Mystery solved !!!
UPDATE 2011-10-17 11:07 EDT
The error message was deceptive because innodb_log_file_size was smaller than the log files (ib_logfile0 and ib_logfile1), which were 1G at the time. What's interesting is this: Corruption was reported because the file was expected to be 5M and the files were bigger. If the situation were reversed and the innodb log files were smaller than the declared size in my.cnf you should get something like this in the error log:
110216 9:48:41 InnoDB: Initializing buffer pool, size = 128.0M
110216 9:48:41 InnoDB: Completed initialization of buffer pool
InnoDB: Error: log file ./ib_logfile0 is of different size 0 5242880 bytes
InnoDB: than specified in the .cnf file 0 33554432 bytes!
110216 9:48:41 [ERROR] Plugin 'InnoDB' init function returned error.
110216 9:48:41 [ERROR] Plugin 'InnoDB' registration as a STORAGE ENGINE failed.
In this example, the log files were already existing as 5M and the setting for innodb_log_file_size was bigger (in this case, 32M).
For this particular question, I blame MySQL (eh Oracle [still hate saying it]) for the inconsistent error message protocol.
Andreas got this answer first in terms of what to do. +1 for Andreas !!!
I would like clarify why that answer is the only way and how to do it.
By default ibdata1 normally houses four types of information
- Table Data
- Table Indexes
- MVCC (Multiversioning Concurrency Control) Data
- Table Metadata
Running OPTIMIZE TABLE against an InnoDB table stored ibdata1 will make things worse because here is what it does:
- Makes the table's data and indexes contiguous inside ibdata1
- It makes ibdata1 grow because the contiguous data is appended to ibdata1
You can segregate Table Data and Table Indexes from ibdata1 and manage them independently using innodb_file_per_table. That way, only MVCC and Table MetaData would reside in ibdata1.
If you already use it, then you must have a high-write environment that stores lots of MVCC to support transaction isolation. Once the transactions holding the MVCC is done, the space is simply abandoned for re-use.
To shrink ibdata1 once and for all you must do the following:
STEP 01) MySQLDump all databases into a SQL text file (call it SQLData.sql)
STEP 02) Drop all databases (except mysql schema)
STEP 03) service mysql stop
STEP 04) Add the following lines to /etc/my.cnf
[mysqld]
innodb_file_per_table
innodb_flush_method=O_DIRECT
innodb_log_file_size=1G
innodb_buffer_pool_size=4G
Sidenote: Whatever your set for innodb_buffer_pool_size, make sure innodb_log_file_size is 25% of innodb_buffer_pool_size.
STEP 05) rm -f /var/lib/mysql/ibdata1 /var/lib/mysql/ib_logfile
At this point, there should only be the mysql schema in /var/lib/mysql
STEP 06) service mysql start
This will recreate ibdata1 at 10MB, ib_logfile0 and ib_logfile1 at 1G each
STEP 07) Reload SQLData.sql into mysql
ibdata1 will grow but only contain table metadata
Each InnoDB table will exist outside of ibdata1
Suppose you have an InnoDB table named mydb.mytable. If you go into /var/lib/mysql/mydb, you will see two files representing the table
- mytable.frm (Storage Engine Header)
- mytable.ibd (Home of Table Data and Table Indexes for mydb.mytable)
ibdata1 will never contain InnoDB data and Indexes anymore.
With the innodb_file_per_table option in /etc/my.cnf, you can run OPTIMIZE TABLE mydb.mytable;
and the file /var/lib/mysql/mydb/mytable.ibd will actually shrink.
I would like to suggest a formula for you to query on sizing your InnoDB Buffer Pool from my post on What are the main differences between InnoDB and MyISAM?
Related Question
- MySQL – Issue After Moving ib_logfile1 and ib_logfile0 Files
- Mysql backup from ibdata1, ib_logfile1, ib_logfile0
- Mysql – ib_logfile0 and ib_logfile1 got deleted
- MySQL 5.6 – How to Resolve MySQL Instance Stalling on SYNC Index
- Mysql – Recover innodb thesql 5.6 database WITH ib_logfile0,ib_logfile1, and ibdata1 but WITHOUT .idb files
- MYSQL 5.6 : Database Loss After Several Power Outttage
- Mysql – XAMPP – Error: MySQL shutdown unexpectedly
- MySQL ON DUPLICATE KEY UPDATE monitoring
Best Answer
There are two ways
Stop MySQL gracefully. Check the error log and make sure it was a normal shutdown.
Move ib_logfile0 and ib_logfile1 out of the datadir (Save them just in case you need to roll back)
Start MySQL. InnoDB will notice there are no REDO log files and will create empty ones.