Skip to content

Conversation

crazycs520
Copy link
Contributor

@crazycs520 crazycs520 commented Oct 17, 2018

What problem does this PR solve?

Add admin restore table by job job_id to restore the deleted table.
related proposal: #7383
related parser PR: pingcap/parser#85, pingcap/parser#172

What is changed ?

Add a new ddl type job: restore table to do restore.
the function of restore table almost as same as create table ddl.
But still a little bit different:

  • restore table don't do split table region.
  • restore table will rebase the table auto id with the original table autoID.

restore table usage

Scenario 1

If you drop table by mistake, you can use admin restore table [table_name] to restore the table.

Eg:

mysql> use test
You are now connected to database "test" as user "root"
mysql> create table t (a int)
mysql> insert into t values (1);
mysql> select a from t;
+---+
| a |
+---+
| 1 |
+---+
mysql> drop table t;
mysql> select a from t;
(1146, u"Table 'test.t' doesn't exist")
mysql> admin restore table test.t;
mysql> select a from t;
+---+
| a |
+---+
| 1 |
+---+
mysql> insert into t values (2);
mysql> select a from t;
+---+
| a |
+---+
| 1 |
| 2 |
+---+

Scenario 2

If you drop table t by mistable, then create a new table t, then drop the new table t, now, if you use admin restore table t, It will restore the new table t, not the ole table t . But how to restore the old table t ? You can use admin restore table by job [drop_table_job_ID] .

Eg:

mysql> use test
You are now connected to database "test" as user "root"
mysql> select * from t;
+---+
| a |
+---+
| 1 |
+---+
mysql> drop table t;
mysql> create table t (a int,b varchar(10));
mysql> insert into t values (1,"new t");
mysql> select * from t;
+---+-------+
| a | b     |
+---+-------+
| 1 | new t |
+---+-------+
mysql> drop table t;
mysql> admin restore table test.t;
mysql> select * from t;
+---+-------+
| a | b     |
+---+-------+
| 1 | new t |
+---+-------+
mysql> admin show ddl jobs;
+--------+---------+------------+---------------+--------------+-----------+----------+-----------+-----------------------------------+--------+
| JOB_ID | DB_NAME | TABLE_NAME | JOB_TYPE      | SCHEMA_STATE | SCHEMA_ID | TABLE_ID | ROW_COUNT | START_TIME                        | STATE  |
+--------+---------+------------+---------------+--------------+-----------+----------+-----------+-----------------------------------+--------+
| 73     | test    | t          | restore table | public       | 1         | 70       | 0         | 2019-01-13 14:55:59.016 +0800 CST | synced |
| 72     | test    | t          | drop table    | none         | 1         | 70       | 0         | 2019-01-13 14:55:54.116 +0800 CST | synced |
| 71     | test    | t          | create table  | public       | 1         | 70       | 0         | 2019-01-13 14:55:17.414 +0800 CST | synced |
| 69     | test    |            | drop table    | none         | 1         | 60       | 0         | 2019-01-13 14:55:03.262 +0800 CST | synced |
| 68     | test    |            | add index     | public       | 1         | 60       | 0         | 2019-01-13 14:54:28.415 +0800 CST | synced |
| 67     | test    |            | add index     | public       | 1         | 60       | 0         | 2019-01-13 14:54:24.563 +0800 CST | synced |
| 66     | test    |            | add index     | public       | 1         | 60       | 0         | 2019-01-13 14:54:20.611 +0800 CST | synced |
| 65     | test    |            | add index     | public       | 1         | 60       | 0         | 2019-01-13 14:54:10.915 +0800 CST | synced |
| 64     | test    |            | add index     | public       | 1         | 60       | 0         | 2019-01-13 14:54:05.511 +0800 CST | synced |
| 63     | test    |            | add index     | public       | 1         | 60       | 0         | 2019-01-13 14:54:01.411 +0800 CST | synced |
+--------+---------+------------+---------------+--------------+-----------+----------+-----------+-----------------------------------+--------+
10 rows in set
mysql> admin restore table by job 69; /* if you not sure which job drop the old table, you can also find this in tidb log file. */
(1050, u"Table 't' already exists")  /* because there is already have a table name `t`, so have to rename the table first. */
mysql> rename table t to t_new;
mysql> admin restore table by job 69;
mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| t              |
| t_new          |
+----------------+
mysql> select * from t;
+---+
| a |
+---+
| 1 |
+---+
mysql> select * from t_new;
+---+-------+
| a | b     |
+---+-------+
| 1 | new t |
+---+-------+

Watch out

If you drop table t multiple time, then use admin recover table by job [ID] with the old drop job ID, there will have some problem when you write.

Eg:

mysql> use test
You are now connected to database "test" as user "root"
mysql> insert into t set b=1;
mysql> select * from t;
+---+---+
| a | b |
+---+---+
| 1 | 1 |
+---+---+
mysql> drop table t;
mysql> admin restore table t;
mysql> insert into t set b=2;
mysql> select * from t;
+-------+---+
| a     | b |
+-------+---+
| 1     | 1 |
| 30001 | 2 |
+-------+---+
mysql> drop table t;
mysql> admin show ddl jobs;
+--------+---------+------------+---------------+--------------+-----------+----------+-----------+-----------------------------------+--------+
| JOB_ID | DB_NAME | TABLE_NAME | JOB_TYPE      | SCHEMA_STATE | SCHEMA_ID | TABLE_ID | ROW_COUNT | START_TIME                        | STATE  |
+--------+---------+------------+---------------+--------------+-----------+----------+-----------+-----------------------------------+--------+
| 106    | test    |            | drop table    | none         | 1         | 94       | 0         | 2019-01-13 15:21:27.016 +0800 CST | synced |
| 105    | test    |            | restore table | public       | 1         | 94       | 0         | 2019-01-13 15:19:37.564 +0800 CST | synced |
| 104    | test    |            | drop table    | none         | 1         | 94       | 0         | 2019-01-13 15:19:29.318 +0800 CST | synced |
| 103    | test    |            | drop index    | none         | 1         | 94       | 0         | 2019-01-13 15:18:56.266 +0800 CST | synced |
| 102    | test    |            | drop index    | none         | 1         | 94       | 0         | 2019-01-13 15:18:50.815 +0800 CST | synced |
| 101    | test    |            | drop index    | none         | 1         | 94       | 0         | 2019-01-13 15:18:47.715 +0800 CST | synced |
| 100    | test    |            | drop index    | none         | 1         | 94       | 0         | 2019-01-13 15:18:45.364 +0800 CST | synced |
| 99     | test    |            | add index     | public       | 1         | 94       | 0         | 2019-01-13 15:18:25.263 +0800 CST | synced |
| 98     | test    |            | add index     | public       | 1         | 94       | 0         | 2019-01-13 15:18:22.063 +0800 CST | synced |
| 97     | test    |            | add index     | public       | 1         | 94       | 0         | 2019-01-13 15:18:10.763 +0800 CST | synced |
+--------+---------+------------+---------------+--------------+-----------+----------+-----------+-----------------------------------+--------+
mysql> admin restore table by job 104;
mysql> select * from t;
+-------+---+
| a     | b |
+-------+---+
| 1     | 1 |
| 30001 | 2 |
+-------+---+
mysql> insert into t set b=3;
mysql> select * from t;
+-------+---+
| a     | b |
+-------+---+
| 1     | 1 |
| 30001 | 3 |  /* Watch out: miss record b=2, This because record b=2 is covered by record b=3.*/
+-------+---+

summary

Normally recommend use admin restore table [table_name] to restore table. admin restore table by job [ID] is only for the Scenario 2.

How it works ?

This is done through the following steps:

  1. Get the history ddl job by job_id.
  2. Use the drop table job's StartTS to get a snapshot infoSchema before drop table.
  3. Find the table meta by table_id in snapshot infoSchema, if not found, return ErrTableIDNotExists.
  4. Using the Found table meta to create table( recover table ). the table_id is still the original table id. Return if encounter any error.
  5. Remove dropped table DDL job from gc_delete_range table by drop table job's id and table_id.

But Change Settings and undo Settings will make the problem more complicated.

Check List

Tests

  • Unit test
  • Manual test

Code changes

  • Has exported function/method change
  • Has exported variable/fields change
  • Has interface methods change

Side effects

  • Increased code complexity

Related changes


This change is Reviewable

@crazycs520
Copy link
Contributor Author

@winkyao @zimulala @ciscoxll PTAL.

@crazycs520
Copy link
Contributor Author

/run-all-tests

@crazycs520
Copy link
Contributor Author

/run-unit-test

@crazycs520
Copy link
Contributor Author

@zimulala @winkyao @ciscoxll PTAL

@crazycs520 crazycs520 changed the title ddl: add recover deleted table ddl: add restore deleted table Dec 15, 2018
@zyguan
Copy link
Contributor

zyguan commented Dec 15, 2018

Hi, @crazycs520 , ActionRestoreTable is undefined. you may need to bump parser first.

@zhouqiang-cl
Copy link
Contributor

/rebuild

@crazycs520 crazycs520 force-pushed the recover-table branch 2 times, most recently from 61e8680 to bb4f1ed Compare December 18, 2018 13:18
@crazycs520
Copy link
Contributor Author

db_partition_test

@crazycs520
Copy link
Contributor Author

/run-all-tests

@crazycs520
Copy link
Contributor Author

/run-all-tests

@ciscoxll
Copy link
Contributor

LGTM.

@ciscoxll ciscoxll added the status/LGT2 Indicates that a PR has LGTM 2. label Jan 15, 2019
@crazycs520
Copy link
Contributor Author

/run-all-tests

1 similar comment
@crazycs520
Copy link
Contributor Author

/run-all-tests

@crazycs520
Copy link
Contributor Author

@zimulala PTAL again.

@crazycs520
Copy link
Contributor Author

/run-all-tests

@crazycs520
Copy link
Contributor Author

/run-unit-test

Copy link
Contributor

@zimulala zimulala left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to consider ServerStatusInTrans like other DDLs?

Copy link
Contributor

@zimulala zimulala left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@crazycs520
Copy link
Contributor Author

/run-all-tests

@crazycs520
Copy link
Contributor Author

/run-unit-test

@crazycs520 crazycs520 merged commit 365264c into pingcap:master Jan 16, 2019
@you06 you06 added the sig/sql-infra SIG: SQL Infra label Mar 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
sig/sql-infra SIG: SQL Infra status/LGT2 Indicates that a PR has LGTM 2.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants