Converting MyISAM tables to InnoDB can significantly enhance database performance and reliability. Although MyISAM has its unique advantages, InnoDB offers incredible benefits that often make it the preferred choice for production environments.

Why is it Required?

MyISAM had been the default storage engine in MySQL prior to version 5.5. However, with the release of MySQL 5.5, InnoDB replaced MyISAM as the default storage engine. This shift occurred because InnoDB offers a host of features that make it indispensable for modern database applications.

FeaturesMyISAMInnoDB
Transaction SupportNot SupportInnoDB supports ACID-compliant transactions, ensuring data integrity
Foreign Key ConstraintsNot Support InnoDB supports foreign key constraints, ensuring that relationships between tables
Locking MechanismTable-level Locking: MyISAM locks entire tables during read/write operations, which can cause contentionRow-level Locking: InnoDB locks rows during transactions, allowing for higher concurrency
MVCC (Multi-Version Concurrency Control)Not SupportSupport:Provides consistent reads without locking
Clustered IndexesNot SupportSupport
Compressed dataSupport :Compressed MyISAM tables are supported only when using the compressed row format. Tables using the compressed row format with MyISAM are read only.Support
CachesIndex caching onlyData and index caching
Crash RecoveryLimited: MyISAM has basic crash recovery capabilities, mainly through repair operations that may result in data loss.Robust: InnoDB uses transactional logs and automatic crash recovery to maintain data integrity and minimize data loss.
MyISAM vs InnoDB

So It is time to switch to InnoDB. We recently undertook this conversion process and encountered a few challenges. We want to share our experience and provide a detailed, step-by-step guide to help you navigate this task effectively.

Summary of Steps

  • Backup Your Databases
  • Identify MyISAM Tables
  • Generate ALTER TABLE Statements
  • Execute ALTER TABLE Statements
  • Verify the Conversion

Step 1: Backup Your Databases

Before starting any major changes, it is crucial to back up your databases to ensure data safety. This step protects your data in case anything goes wrong during the conversion process.

Step 2: Identify MyISAM Tables

To identify the tables using the MyISAM engine, use the following query:

mysql> SELECT table_schema,table_name,ROUND((data_length + index_length) / 1024 / 1024, 2) AS table_size_mb FROM information_schema.tables WHERE engine = 'MyISAM' 
AND table_schema NOT IN ('information_schema', 'mysql', 'performance_schema', 'sys');

This query provides the schema name, table name, and table size. Checking the table size is crucial as it impacts storage and the time taken to execute the ALTER statement. Ensure sufficient storage space is available and consider the impact on production before proceeding.

Step 3: Generate ALTER TABLE Statements

To convert the engine to InnoDB, you can use the following query:

mysql> ALTER TABLE your_schema.your_table ENGINE=InnoDB;

Writing this query manually is manageable for a few tables, but if you need to convert hundreds of tables, it can be time-consuming. Use this query to generate the ALTER statements for all MyISAM tables:

mysql> SELECT CONCAT('ALTER TABLE ', table_schema, '.', table_name, ' ENGINE=InnoDB;') AS 
       alter_statement FROM information_schema.tables WHERE engine = 'MyISAM';

Step 4: Execute the Statements

You can execute the statements one by one or use scripting, depending on what is more convenient for you.During our execution, everything was going smoothly until we encountered two types of errors:

mysql> ALTER TABLE your_schema.your_table ENGINE=InnoDB;
ERROR 1709 (HY000): Index column size too large. The maximum column size is 767 bytes

mysql> ALTER TABLE your_schema.your_table ENGINE=InnoDB;
ERROR 1118 (42000): Row size too large (> 8126). Changing some columns to TEXT or BLOB or using ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED may help. In the current row format, BLOB prefix of 768 bytes is stored inline.

Let’s see how we fixed these errors. First, we need to understand the errors and their causes.

Error 1: Index Column Size Too Large

The error ERROR 1709 (HY000): Index column size too large. The maximum column size is 767 bytes occurs because InnoDB has a stricter limit on the maximum index key length compared to MyISAM. Specifically, InnoDB limits the length of index keys to 767 bytes for the utf8mb3 character set, which uses up to 3 bytes per character. For utf8mb4, which uses up to 4 bytes per character, the limit is 767 bytes.

First, identify which indexes are causing the issue. Likely problematic indexes are those on large VARCHAR columns. To resolve this, you can use prefix indexes:

Drop Problematic Indexes:

mysql> ALTER TABLE your_table DROP INDEX index_name1, DROP INDEX index_name2;

Add New Indexes with Prefix Lengths:

mysql> ALTER TABLE your_table
    ADD INDEX index_name1 (column_name1(255)),
    ADD INDEX index_name2 (column_name2(255));

By specifying a prefix length (e.g., 255), you index only the first 255 characters of the column, reducing the total index size. This allows you to convert the table to InnoDB successfully:

mysql> ALTER TABLE your_table ENGINE=InnoDB;

Error 2: Row Size Too Large

The error ERROR 1118 (42000): Row size too large (> 8126) indicates that the total row size exceeds the maximum row size allowed by the InnoDB storage engine. This is common with multiple large VARCHAR columns, as the storage engine attempts to keep most data inline with the row.

To resolve this, you can convert large VARCHAR columns to TEXT and use ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED.

Why the Error Occurs

MySQL stores table data in pages, typically 16KB in size. The maximum row size is often around 8KB for the InnoDB engine, including all column data stored inline with the row. When the combined size of the row exceeds this limit, you encounter the error.

How ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED Helps

MySQL’s InnoDB storage engine supports different row formats, which determine how data is stored internally. The key formats are COMPACT, REDUNDANT, DYNAMIC, and COMPRESSED. The COMPACT and REDUNDANT formats store data differently compared to DYNAMIC and COMPRESSED.

These DYNAMIC and COMPRESSED formats were introduced to handle large columns more efficiently. In these formats, large VARCHAR, TEXT, and BLOB columns primarily store their data off-page, with only a small pointer (typically 20 bytes) stored inline within the row. This helps in reducing the row size significantly

How Converting to TEXT Helps

VARCHAR columns store data inline up to their maximum length. When you have multiple large VARCHAR columns, the row size can easily exceed the limit. TEXT columns inherently store data off-page, which aligns well with the storage mechanisms of DYNAMIC and COMPRESSED row formats.

Converting large VARCHAR columns to TEXT reduces the inline row size significantly because only a small pointer is stored inline, pointing to the actual data stored off-page.

Change Row Format to DYNAMIC:

mysql> ALTER TABLE your_table ROW_FORMAT=DYNAMIC;

Convert Large VARCHAR Columns to TEXT:

Identify and convert large VARCHAR columns to TEXT:

mysql> ALTER TABLE your_table MODIFY column_name1 TEXT,MODIFY column_name2 TEXT;

Step 5: Verify the Conversion

After executing the ALTER statements, it is essential to verify that all tables have been successfully converted to InnoDB. Use the following query to check the table engine:

mysql> SHOW TABLE STATUS LIKE 'your_table'\G

Sample Output:
*************************** 1. row ***************************
           Name: employees
         Engine: InnoDB
        Version: 10
     Row_format: Dynamic
           Rows: 1000
 Avg_row_length: 100
    Data_length: 102400
Max_data_length: 0
   Index_length: 20480
      Data_free: 4096
 Auto_increment: 1001
    Create_time: 2023-06-27 12:34:56
    Update_time: 2024-06-27 12:34:56
     Check_time: NULL
      Collation: utf8mb4_general_ci
       Checksum: NULL
 Create_options:
        Comment:

This query will provide the engine type for the specified table. Ensure that the Engine column shows InnoDB for all converted tables.

Conclusion

Converting MyISAM tables to InnoDB can significantly enhance database performance and reliability. By carefully following the steps outlined above and addressing common errors, you can ensure a smooth and efficient conversion process. This not only optimizes storage but also ensures your database can handle large text data without exceeding row size limits. Embracing InnoDB will bring your database to a new level of performance and stability, making it well-suited for modern production environments.

Our Recent Posts

Discover more from Genexdbs

Subscribe now to keep reading and get access to the full archive.

Continue reading