InnoDB vs. MyISAM: Differences That Still Matter
AI generated
InnoDB
SQL
MySQL · Storage Engines · Architecture
InnoDB vs. MyISAM
Differences That Still Matter

InnoDB replaced MyISAM as the default storage engine back in MySQL 5.5, yet MyISAM still turns up in grown systems, often unnoticed. Anyone who doesn't understand the transaction behavior, locking granularity and crash safety of the two engines risks data loss during migrations and legacy maintenance. This article explains the differences in detail and shows what a clean migration to InnoDB looks like.

17 min read Transactions · Locking · Crash Safety MySQL 8.0 · MariaDB 10.x

1. Why the comparison still matters today

Since MySQL 5.5, InnoDB has been the default storage engine, and in new projects MyISAM is practically never used anymore. Still, you regularly encounter MyISAM tables in grown systems: old Magento 1 installations, migrated WordPress databases, home-built reporting tools from the 2000s, or simply tables that were created years ago with CREATE TABLE ... ENGINE=MyISAM and never migrated. The comparison of InnoDB vs. MyISAM is therefore not a historical topic but a practical necessity for anyone working with legacy databases.

The differences between the two engines are not cosmetic, they concern fundamental properties: whether a database supports transactions, how granular locks are set, and whether a system crash leads to data loss. Anyone who overlooks a MyISAM table in production can be badly surprised by these properties, for example when a single slow write blocks the entire table for every other request. The following sections work through the differences between InnoDB and MyISAM systematically.

2. Transactions and ACID: the fundamental difference

InnoDB is a fully transactional storage engine and satisfies the ACID properties: atomicity, consistency, isolation, durability. Several related changes can be bundled into one transaction and either committed entirely or rolled back entirely. MyISAM does not know this concept at all. A ROLLBACK on a MyISAM table has no effect, because MyISAM keeps no undo information. Every single SQL statement is applied immediately and permanently, regardless of whether a following statement fails.

For applications that execute several related write operations, for example creating an order and reducing stock at the same time, this is a substantial risk. If the second operation fails on MyISAM, the first one remains in place, and the database ends up in an inconsistent state that must be corrected manually. With InnoDB, the transaction prevents exactly this scenario, because COMMIT confirms both changes together, or ROLLBACK discards both together.


-- InnoDB: transaction guarantees atomicity across multiple statements
START TRANSACTION;
UPDATE inventory SET stock = stock - 1 WHERE product_id = 4711;
INSERT INTO orders (product_id, customer_id, status) VALUES (4711, 88, 'new');
COMMIT;
-- If either statement fails, ROLLBACK undoes both changes cleanly

-- MyISAM: no transaction support, ROLLBACK has no effect
-- START TRANSACTION; ... ROLLBACK;  -- silently ignored on MyISAM tables

-- Check which engine a table actually uses
SELECT table_name, engine
FROM information_schema.tables
WHERE table_schema = 'shop_db' AND table_name = 'inventory';

3. Locking granularity: row-level vs. table-level

The second fundamental difference lies in lock granularity. InnoDB uses row-level locks, locking only the rows actually affected by a table. Two transactions can change different rows in the same table at the same time without blocking each other. MyISAM, on the other hand, only knows table-level locks. As soon as a write access hits a MyISAM table, the entire table is locked, even for reads, until the write finishes.

In practice this means: under high concurrency with many simultaneous writes, MyISAM scales much worse than InnoDB. An online shop with thousands of concurrent orders would, with MyISAM tables for orders or stock, end up with a queue of blocked writes, because every order locks the whole table. InnoDB avoids this problem through row-level locking combined with MVCC, multiversion concurrency control, which even allows reads to proceed completely without locks.


-- Inspect current locks held by InnoDB transactions
SELECT
    engine_transaction_id,
    object_schema,
    object_name,
    lock_type,
    lock_mode,
    lock_status
FROM performance_schema.data_locks
WHERE object_schema = 'shop_db';

-- MyISAM: no row-level lock info exists, only table-level lock status
SHOW OPEN TABLES WHERE In_use > 0;

-- Demonstrate the blocking effect: a write on MyISAM blocks all readers
-- Session A: LOCK TABLES legacy_stats WRITE;
-- Session B: SELECT * FROM legacy_stats;  -- blocks until Session A unlocks

4. Crash safety and data integrity

Crash safety is where InnoDB and MyISAM differ massively. InnoDB uses write-ahead logging via the redo log: every change is first persisted to the redo log before it lands in the actual data pages. If the server crashes, InnoDB automatically replays the redo log on the next start and restores a consistent state without manual intervention. This property makes InnoDB the only sensible choice for practically any production use.

MyISAM offers no comparable mechanism. A system crash during a write can leave a MyISAM table in a corrupted state that often can only be fixed with REPAIR TABLE or the external tool myisamchk, and not always without data loss. On large tables this repair process can also take a long time, during which the table is unavailable for production use. This property alone disqualifies MyISAM for any application where data loss is not acceptable.


-- Check and repair a MyISAM table after a suspected crash
CHECK TABLE legacy_reports;
REPAIR TABLE legacy_reports;

-- InnoDB requires no manual repair: crash recovery runs automatically
-- at startup by replaying the redo log up to the last checkpoint.
-- Verify recovery happened cleanly via the error log:
-- grep "InnoDB: Starting crash recovery" /var/log/mysql/error.log

5. Full-text search: from MyISAM to InnoDB FULLTEXT

For a long time, full-text search was one of the few domains where MyISAM had a clear technical advantage over InnoDB. Until MySQL 5.5, only MyISAM supported FULLTEXT indexes, which is why many older applications deliberately used MyISAM for search tables, even when the rest of the database already ran on InnoDB. Since MySQL 5.6, InnoDB also supports full-featured FULLTEXT indexes, which has practically eliminated this reason for MyISAM.

Modern InnoDB FULLTEXT indexes offer the same core functionality as their MyISAM counterparts, including boolean-mode search and relevance ranking via MATCH ... AGAINST, combined with the benefits of transactions and row-level locking. For new projects there is no longer any technical reason to fall back on MyISAM for full-text search, even though specialized search solutions like Elasticsearch remain the better choice for more complex requirements.


-- InnoDB fulltext index, no need to fall back to MyISAM anymore
CREATE TABLE articles (
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255) NOT NULL,
    body TEXT NOT NULL,
    FULLTEXT KEY ft_title_body (title, body)
) ENGINE=InnoDB;

-- Boolean mode search with relevance ranking
SELECT id, title,
       MATCH(title, body) AGAINST('+mysql +performance' IN BOOLEAN MODE) AS relevance
FROM articles
WHERE MATCH(title, body) AGAINST('+mysql +performance' IN BOOLEAN MODE)
ORDER BY relevance DESC;

6. Storage overhead and performance characteristics

In pure read benchmarks without concurrency, MyISAM was historically sometimes faster than InnoDB, because MyISAM has to do less internal bookkeeping and keeps no undo logs for MVCC. This advantage has largely disappeared in modern MySQL versions, since InnoDB has been heavily optimized over the years and the buffer pool works more efficiently than MyISAM's simpler key cache. Under realistic workloads with mixed reads and writes, InnoDB is now faster in almost every scenario.

The engines also differ in storage footprint: MyISAM stores data and index files separately and compresses indexes by default, which can mean less space for pure read-only tables. InnoDB tends to need more storage due to its clustered index structure, where the table is physically sorted by the primary key, and due to additional structures like undo logs, but it wins this disadvantage back through faster primary key lookups, since no separate lookup operation is needed.

7. Where MyISAM still shows up today

Despite all its downsides, you still encounter MyISAM in practice in several places. System tables of older MySQL versions historically ran partly on MyISAM, though modern MySQL 8 installations have largely eliminated this. In legacy applications from the 2000s and early 2010s, such as old content management systems or home-built internal tools, MyISAM tables are often still found unchanged, because a migration was never prioritized. Data imports from old backups or migrations from third-party systems can also introduce MyISAM unnoticed into an otherwise modern InnoDB database.

Another often overlooked case is internal statistics or log tables deliberately left on MyISAM because developers in the past assumed transaction safety was dispensable for non-critical data. This can become problematic in practice once these tables are actually used for business-critical reporting. A regular audit of the storage engines in use is therefore part of any solid database maintenance.


-- Find every non-InnoDB table across all schemas, common audit query
SELECT
    table_schema,
    table_name,
    engine,
    ROUND((data_length + index_length) / 1024 / 1024, 2) AS size_mb
FROM information_schema.tables
WHERE engine IS NOT NULL
  AND engine != 'InnoDB'
  AND table_schema NOT IN ('mysql', 'information_schema', 'performance_schema', 'sys')
ORDER BY size_mb DESC;

8. Migrating from MyISAM to InnoDB

Migrating a MyISAM table to InnoDB is, in the simplest case, a single ALTER TABLE command, but in practice there are several pitfalls. If the table lacks a sensible primary key, which is not uncommon on old MyISAM tables, one should be added before migrating, since InnoDB always needs a primary key internally as a clustered index and otherwise creates a hidden one that slows down access. On large tables, ALTER TABLE ... ENGINE=InnoDB can also take considerable time and temporary storage, since the table is completely rebuilt internally.

For production systems with little maintenance window, using online DDL tools like pt-online-schema-change from the Percona Toolkit or gh-ost is recommended, as they perform the migration without a lengthy table lock. Before any migration it should also be checked whether the application explicitly uses LOCK TABLES syntax with MyISAM-specific behavior, since locking behavior changes fundamentally after migration.


-- Simple migration for small tables
ALTER TABLE legacy_reports ENGINE=InnoDB;

-- Verify the primary key exists before migrating large tables
SHOW KEYS FROM legacy_reports WHERE Key_name = 'PRIMARY';

-- For large production tables, prefer online schema change tools:
-- pt-online-schema-change --alter "ENGINE=InnoDB" \
--   D=shop_db,t=legacy_reports --execute

9. Feature matrix compared directly

The following table summarizes the most important differences between InnoDB and MyISAM compactly.

Property InnoDB MyISAM
Transactions Full, ACID compliant Not supported
Locking Row-level Table-level
Crash recovery Automatic via redo log Manual with myisamchk
Foreign keys Supported Not supported
Full-text search Full featured since 5.6 Historically strong
Storage for pure read tables Higher due to clustered index Tends to be more compact

For practically every modern use case, InnoDB is the right choice. MyISAM remains relevant only in a few niches, for example purely read-only, non-critical reporting tables without any concurrency, and even there the benefits of a unified engine strategy now outweigh it.

Mironsoft

Database audits and storage engine migration

Still got MyISAM tables in your production database?

We find hidden MyISAM tables, assess the risk, and migrate them to InnoDB using online schema change tools, without long production downtime.

Engine audit

Check every table for storage engine and crash risk

Migration plan

Order and tooling for a low-risk MyISAM to InnoDB migration

Zero downtime

Migration with pt-online-schema-change without long table locks

10. Summary

The comparison of InnoDB vs. MyISAM shows clearly why InnoDB has been the default choice for over a decade: full transaction support, row-level locking for high concurrency, and automatic crash recovery via the redo log make InnoDB the only sensible engine for practically every production use case. MyISAM lacks all these properties, which is why it no longer plays a supporting role in modern architectures.

Still, knowing the differences pays off, because MyISAM tables regularly show up in legacy systems, often unnoticed inside an otherwise modern InnoDB database. A regular audit via information_schema.tables reliably uncovers such legacy remnants, and a migration with online schema change tools can be carried out even in production environments without significant downtime.

InnoDB vs. MyISAM, the essentials at a glance

Transactions

Only InnoDB supports COMMIT and ROLLBACK across multiple statements.

Locking

InnoDB locks individual rows, MyISAM locks the entire table on writes.

Crash safety

InnoDB recovers automatically after a crash, MyISAM needs manual repair.

Migration

ALTER TABLE ENGINE=InnoDB for small tables, online tools for large production tables.

11. FAQ: InnoDB vs. MyISAM

1Is MyISAM still sensible today?
Practically never for new projects. InnoDB offers transactions, row-level locking and crash recovery, all properties MyISAM lacks.
2ROLLBACK on MyISAM?
No effect. MyISAM does not support transactions, every statement is applied immediately and permanently.
3Why is row-level locking important?
Allows concurrent changes to different rows. Table-level locking blocks the whole table on every write.
4Detecting MyISAM tables?
Query against information_schema.tables filtered on the engine column. Regular audit reveals hidden cases.
5Full-text search with InnoDB?
Yes, full featured since MySQL 5.6 with FULLTEXT indexes, boolean mode and relevance ranking via MATCH AGAINST.
6Migrating MyISAM to InnoDB?
ALTER TABLE ENGINE=InnoDB for small tables, pt-online-schema-change or gh-ost for large production tables.
7Crash on a MyISAM table?
Can become corrupted without automatic recovery. CHECK TABLE and REPAIR TABLE needed, sometimes with data loss.
8Foreign keys on MyISAM?
Not supported. FOREIGN KEY definitions are silently ignored, the application must enforce referential integrity itself.
9Primary key mandatory on InnoDB?
Not strictly, but strongly recommended. Without an explicit key InnoDB creates a hidden one that slows down access.
10InnoDB slower on reads?
Practically not anymore. The historical MyISAM advantage has largely disappeared through years of InnoDB optimization.