DBA和运维同学的大救星来了
Posted 数据库开发者
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DBA和运维同学的大救星来了相关的知识,希望对你有一定的参考价值。
为了防止误删库表,有一种做法是专门准备一个备机,这个备机与主机故意保持一定的复制时间差,比如一个小时,这样只要1个小时之内能够发现误删错误,那么在备机上面还是能够找到库表的,但是这个备机也需要追上近1个小时的relay log然后才能作为主节点继续使用,在此期间业务也是无法运行的,经济损失仍可能很大,而且每个集群多一个备节点,业务多了的话还是不小的成本开销。
为了帮助广大DBA和运维同学免除后顾之忧,我最近开发了这样一个大救星功能 ---对删除的库表,在一定时间内能够一秒找回,并且原库表中的数据不会有任何损失。Drop database/table后,TDSQL的percona/mariadb内核会把这些库表用特殊技术手段隐藏了起来,在db实例中再无法读写访问或者看到这些隐藏的库表;使用新增的特殊命令可以看到隐藏的库表,以及瞬间1秒找回隐藏的库表。在一定时间(可设置,默认48小时)后mysqld会自动删除这些隐藏的库表,用户也可以手动强制删除隐藏的库表。用户还可以直接强制删除库表而不做隐藏,不过这样搞,做错的话,神仙也帮不了你了。 有了这些功能,DBA和运维同学就可以在误操作后,一定时间内,一秒中内找回库表,最大程度缩短库表不可用的时间窗口,最大程度降低误删库表导致的业务损失和经济损失。在下一个版本的TDSQL内核中,这个功能就与大家见面了。下面我就举例介绍这个功能。
mysql> create database test;
Query OK, 1 row affected (0.00 sec)
mysql> use test;
Database changed
mysql> create table t1(a int) engine=innodb;
Query OK, 0 rows affected (0.04 sec)
mysql> insert into t1 values(1),(2);
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> drop table t1; -- 删除表t1,t1会被隐藏,对于mysql来说已经不存在了,但是可以被找回
Query OK, 0 rows affected (0.01 sec)
mysql> select*from t1; -- 无法访问隐藏的表t1,读写都不行,t1对于mysql来说已经相当于不存在了
ERROR 1146 (42S02): Table 'test.t1' doesn't exist
mysql> insert into t1 values(1),(2);
ERROR 1146 (42S02): Table 'test.t1' doesn't exist
mysql> show tables; -- 看不到t1了,t1对于mysql来说已经相当于不存在了
Empty set (0.00 sec)
mysql> show hidden tables; -- 该语句来查看隐藏的表,t1被隐藏了
+----------------+
| Tables_in_test |
+----------------+
| t1 |
+----------------+
1 row in set (0.00 sec)
mysql> show hidden tables; -- 过了一会儿,表被自动删除了。这个隐藏时长在debug build下默认48秒,release build下默认48小时
Empty set (0.00 sec)
mysql> show variables like '%hidden%';
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| keep_hidden_hrs | 48 |
+-----------------+-------+
1 row in set (0.01 sec)
mysql> set global keep_hidden_hrs=300; -- 修改隐藏时长为300秒。注意这里使用的是debug build的mysqld。
Query OK, 0 rows affected (0.00 sec)
mysql> create table t1(a int) engine=innodb;
Query OK, 0 rows affected (0.01 sec)
mysql> insert into t1 values(1),(2);
Query OK, 2 rows affected (0.00 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> drop table if exists t1;
Query OK, 0 rows affected (0.00 sec)
mysql> drop table if exists t1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> drop table t; -- t不存在,报错
ERROR 1051 (42S02): Unknown table 'test.t'
mysql> drop table t1; -- t1已经被隐藏,因而再次删除就出错了。
ERROR 1146 (42S02): Table 'test.t1' doesn't exist
mysql> show tables;
Empty set (0.00 sec)
mysql> show hidden tables; -- t1被隐藏了
+----------------+
| Tables_in_test |
+----------------+
| t1 |
+----------------+
1 row in set (0.00 sec)
mysql> expose table t1; -- 找回隐藏的t1表
Query OK, 0 rows affected (0.01 sec)
mysql> show tables; -- 可以看到t1成为正常的表了
+----------------+
| Tables_in_test |
+----------------+
| t1 |
+----------------+
1 row in set (0.00 sec)
mysql> show hidden tables; -- t1不再是隐藏的表了。
Empty set (0.00 sec)
mysql> select*from t1; insert into t1 values(3),(4); -- 可以看到t1之前的数据完好无损,并且可以插入更多数据。
+------+
| a |
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.00 sec)
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select*from t1;
+------+
| a |
+------+
| 1 |
| 2 |
| 3 |
| 4 |
+------+
4 rows in set (0.00 sec)
mysql> drop table t1 immediate; -- 立刻强制删除t1,这样做将无法找回t1。
Query OK, 0 rows affected (0.01 sec)
mysql> select*from t1;
ERROR 1146 (42S02): Table 'test.t1' doesn't exist
mysql> show tables;
Empty set (0.00 sec)
mysql> show hidden tables; -- t1不是隐藏的
Empty set (0.00 sec)
mysql> drop table t1; -- t1完全不存在了
ERROR 1051 (42S02): Unknown table 'test.t1'
mysql> expose table t1; -- 也无法找回了。
ERROR 1017 (HY000): Can't find file: './test/t1.frm' (errno: 2 - No such file or directory)
mysql>
mysql> drop hidden table t1; -- t1不是隐藏的
ERROR 1051 (42S02): Unknown table 'test.t1'
mysql> create database test7;
Query OK, 1 row affected (0.02 sec)
mysql> use test7;
Database changed
mysql> create table t1(a int) engine=innodb;
Query OK, 0 rows affected (0.05 sec)
mysql>
mysql> insert into t1 values(1),(2);
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> drop database test7;
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> show databases; -- 看不到test7了。
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
| test1 |
| test2 |
+--------------------+
7 rows in set (0.01 sec)
mysql>
mysql> select*from test7.t1; -- test7库 里面的表无法使用
ERROR 1146 (42S02): Table 'test7.t1' doesn't exist
mysql>
mysql> insert into test7.t1 values(3);
ERROR 1146 (42S02): Table 'test7.t1' doesn't exist
mysql>
mysql> drop table test7.t1;
ERROR 1051 (42S02): Unknown table 'test7.t1'
mysql> expose database test7; -- 回退刚才的drop database test7;操作,找回数据库 test7。做了误操作的运维和DBA同学得救了!
Query OK, 0 rows affected (0.01 sec)
mysql> select*from test7.t1; -- test7的表可以读写了, 表的数据完好无损。
+------+
| a |
+------+
| 1 |
| 2 |
+------+
2 rows in set (0.00 sec)
mysql> insert into test7.t1 values(3);
Query OK, 1 row affected (0.01 sec)
mysql> select*from test7.t1;
+------+
| a |
+------+
| 1 |
| 2 |
| 3 |
+------+
3 rows in set (0.00 sec)
mysql> drop database test7 hidden; -- test7已经被恢复了,不是隐藏的了
ERROR 10006 (HY000): Hidden database for database name test7 does not exist.
mysql> drop database if exists test7 hidden;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> drop database test7; -- 再次删除test7,test7再次被隐藏
Query OK, 1 row affected (0.01 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
7 rows in set (0.00 sec)
mysql> show databases hidden; -- 查看隐藏的db test7
+----------+
| Database |
+----------+
| test7 |
+----------+
1 row in set (0.00 sec)
mysql>
mysql>
mysql>
mysql> create database test7; -- test7仍然隐藏,禁止创建同名的db
ERROR 10005 (HY000): Hidden database exists for database name test7, drop it for real first.
mysql>
mysql> create database if not exists test7;
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql>
mysql> show warnings;
+-------+-------+-----------------------------------------------------------------------------------------------------------------+
| Level | Code | Message |
+-------+-------+-----------------------------------------------------------------------------------------------------------------+
| Note | 10005 | Hidden database exists for database name test7, drop it for real first. |
+-------+-------+-----------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql>
mysql> drop database test7; -- test7仍然处于隐藏状态,无法删除
ERROR 1008 (HY000): Can't drop database 'test7'; database doesn't exist
mysql>
mysql> drop database test7 immediate; -- test7仍然处于隐藏状态,无法删除
ERROR 1008 (HY000): Can't drop database 'test7'; database doesn't exist
mysql>
mysql> drop database test7 hidden; -- 删除处于隐藏状态的test7,这个操作无法回退
Query OK, 0 rows affected (0.03 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
7 rows in set (0.00 sec)
mysql> show databases hidden; -- 隐藏的db test7被彻底删除了
Empty set (0.00 sec)
mysql>
mysql>
mysql> expose database test7; -- 无法找回test7了
ERROR 10006 (HY000): Hidden database for database name test7 does not exist.
mysql>
mysql> create database test7; -- 现在可以创建名为test7的db了
Query OK, 1 row affected (0.01 sec)
mysql> drop database test7;
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> drop database test7; -- test7 已经隐藏了
ERROR 1008 (HY000): Can't drop database 'test7'; database doesn't exist
mysql> expose database test7; -- 找回test7
Query OK, 0 rows affected (0.01 sec)
mysql> show databases; -- 可以看到 test7已经被找回了
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test7 |
+--------------------+
8 rows in set (0.00 sec)
mysql> show databases hidden; -- test7不再是隐藏的了,所以不能做下面针对隐藏的db的ddl操作
Empty set (0.00 sec)
mysql>
mysql> drop database test7 hidden immediate;
ERROR 10006 (HY000): Hidden database for database name test7 does not exist.
mysql> drop database test7 immediate; -- 立刻强制删除test7
Query OK, 0 rows affected (0.01 sec)
mysql> drop database if exists test7 immediate;
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql>
mysql> expose database test7; -- 无法找回test7了,因为test7被强制立刻删除了,也就无法做下面的针对隐藏的db的操作。
ERROR 10006 (HY000): Hidden database for database name test7 does not exist.
mysql>
mysql> drop database test7 hidden;
ERROR 10006 (HY000): Hidden database for database name test7 does not exist.
mysql> drop database if exists test7 hidden;
Query OK, 0 rows affected, 1 warning (0.01 sec)
本文封面和摘要中的小熊图片来源于网络,版权归原作者所有。
以上是关于DBA和运维同学的大救星来了的主要内容,如果未能解决你的问题,请参考以下文章