pt-online-schema change does this trick when it copies rows from the original table to the new one. It creates three triggers: on insert, on update and on delete.
Actually, pt-online-schema can even create a copy table and leave it in that state.
pt-online-schema-change \
--no-drop-triggers \
--new-table-name actor_copy \
--no-drop-new-table \
--no-swap-tables \
--alter "ENGINE InnoDB" \
--execute D=sakila,t=actor
After this command the original table:
mysql> desc actor;
+-------------+----------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------------------+------+-----+-------------------+-----------------------------+
| actor_id | smallint(5) unsigned | NO | PRI | NULL | auto_increment |
| first_name | varchar(45) | NO | | NULL | |
| last_name | varchar(45) | NO | MUL | NULL | |
| last_update | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------------+----------------------+------+-----+-------------------+-----------------------------+
4 rows in set (0.00 sec)
A copy of the original table:
mysql> desc actor_copy;
+-------------+----------------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+----------------------+------+-----+-------------------+-----------------------------+
| actor_id | smallint(5) unsigned | NO | PRI | NULL | auto_increment |
| first_name | varchar(45) | NO | | NULL | |
| last_name | varchar(45) | NO | MUL | NULL | |
| last_update | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+-------------+----------------------+------+-----+-------------------+-----------------------------+
4 rows in set (0.00 sec)
Now, changes to the original tables are reflected in the copy:
mysql> select * from actor where actor_id = 200;
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update |
+----------+------------+-----------+---------------------+
| 200 | THORA | TEMPLE | 2006-02-15 04:34:33 |
+----------+------------+-----------+---------------------+
1 row in set (0.00 sec)
mysql> select * from actor_copy where actor_id = 200;
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update |
+----------+------------+-----------+---------------------+
| 200 | THORA | TEMPLE | 2006-02-15 04:34:33 |
+----------+------------+-----------+---------------------+
1 row in set (0.00 sec)
mysql> delete from actor where actor_id = 200;
Query OK, 1 row affected (0.01 sec)
mysql> select * from actor_copy where actor_id = 200;
Empty set (0.00 sec)
mysql> INSERT INTO actor VALUES (200, 'THORA', 'TEMPLE', '2006-02-15 04:34:33');
Query OK, 1 row affected (0.00 sec)
mysql> select * from actor where actor_id = 200;
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update |
+----------+------------+-----------+---------------------+
| 200 | THORA | TEMPLE | 2006-02-15 04:34:33 |
+----------+------------+-----------+---------------------+
1 row in set (0.00 sec)
mysql> select * from actor_copy where actor_id = 200;
+----------+------------+-----------+---------------------+
| actor_id | first_name | last_name | last_update |
+----------+------------+-----------+---------------------+
| 200 | THORA | TEMPLE | 2006-02-15 04:34:33 |
+----------+------------+-----------+---------------------+
1 row in set (0.01 sec)