众所周知,数据库备份是数据保护的最后一条生命线,可谓“备份千日、恢复一时”。前期文章我们通过实战案例展示了磐维物理备份功能,这一篇我们还是通过实战案例,来带领大家一起来看看磐维数据库的逻辑备份功能。
背景知识:
磐维数据库提供了gs_dump工具,用户可以自定义导出一个数据库或者其中的对象(模式、表等),与其对应的gs_restore工具用于恢复归档格式的备份数据文件。gs_dump导出文件格式可以是纯文本格式的SQL脚本文件:包含将数据库恢复为其保存时的状态所需的SQL语句,也支持导出归档格式的备份文件,归档格式的备份文件必须使用gs_restore配合使用来恢复数据。
实验环境:
操作系统:BCLinux7.6
数据库:磐维CMDB数据库1.0环境
磐维数据库架构:一主两备高可用
[omm@node1 ~]$ gs_om -t status --detail
[ CMServer State ]
node node_ip instance state
-----------------------------------------------------------------------------
1 node1 x.x.x.75 1 /opt/panweidb/cmdata/cmserver/cm_server Standby
2 node2 x.x.x.76 2 /opt/panweidb/cmdata/cmserver/cm_server Standby
3 node3 x.x.x.77 3 /opt/panweidb/cmdata/cmserver/cm_server Primary
[ Cluster State ]
cluster_state : Normal
redistributing : No
balanced : No
current_az : AZ_ALL
[ Datanode State ]
node node_ip instance state
-------------------------------------------------------------------------
1 node1 x.x.x..75 6001 /opt/panweidb/cmdata/data P Primary Normal
2 node2 x.x.x..76 6002 /opt/panweidb/cmdata/data S Standby Normal
3 node3 x.x.x.77 6003 /opt/panweidb/cmdata/data S Standby Normal
环境准备
1、创建数据库并准备数据
为方便分别测试数据库、模式、表的备份和恢复,我们需要创建数据库并准备测试数据。 首先,使用磐维自带的postgres库做数据库的备份恢复测试,需要在postgres数据库中public模式下创建tb1、tb2表并插入数据,再新建s01模式,在s01模式下新建表tb1、tb2。(生产环境不建议大家在postgres库及public模式下存放数据)。
另外,新建数据库db01做模式、表的备份恢复测试,在db01数据库中创建s02模式并创建tb1、tb2用于模式的备份恢复测试,在db01数据库中public模式下创建tb1、tb2用于表的备份恢复测试。详细创建准备情况如下操作:
[omm@node1 ~]$ gsql -d postgres -p 17700 -r
gsql ((CMDB(openGauss) 1.0.1 build 58ef6fad) compiled at 2022-09-06 16:04:55 commit 0 last mr )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
CMDB=# --创建自定义数据库db01
CMDB=# create database db01;
CREATE DATABASE
CMDB=# --创建自定义模式s01
CMDB=# create schema s01;
CREATE SCHEMA
CMDB=# --postgres库中public模式下创建tb1并插入3条数据
CMDB=# create table public.tb1(c1 int);
CREATE TABLE
CMDB=# insert into public.tb1 values(1),(2),(3);
INSERT 0 3
CMDB=# --postgres库中public模式下创建tb2并插入3条数据
CMDB=# create table public.tb2(c1 int);
CREATE TABLE
CMDB=# insert into public.tb2 values(1),(2),(3);
INSERT 0 3
CMDB=# --postgres库中s01模式下创建tb1并插入3条数据
CMDB=# create table s01.tb1(c1 int);
CREATE TABLE
CMDB=# insert into s01.tb1 values(1),(2),(3);
INSERT 0 3
CMDB=# --postgres库中s01模式下创建tb2并插入3条数据(功能介绍临时创建tb2,生产上不建议在public模式下创建业务表及插入数据)
CMDB=# create table s01.tb2(c1 int);
CREATE TABLE
CMDB=# insert into s01.tb2 values(1),(2),(3);
INSERT 0 3
CMDB=# --切换到数据库db01下
CMDB=# \c db01
Non-SSL connection (SSL connection is recommended when requiring high-security)
You are now connected to database "db01" as user "omm".
db01=# --创建自定义模式s02
db01=# create schema s02;
CREATE SCHEMA
db01=# --db01库中public模式下创建tb1并插入3条数据
db01=# create table public.tb1(c1 int);
CREATE TABLE
db01=# insert into public.tb1 values(1),(2),(3);
INSERT 0 3
db01=# --db01库中public模式下创建tb2并插入3条数据
db01=#create table public.tb2(c1 int);
CREATE TABLE
db01=# insert into public.tb2 values(1),(2),(3);
INSERT 0 3
db01=# --db01库中s02模式下创建tb1并插入3条数据
db01=# create table s02.tb1(c1 int);
CREATE TABLE
db01=# insert into s02.tb1 values(1),(2),(3);
INSERT 0 3
db01=# --db01库 s02模式下创建tb2并插入3条数据
db01=# create table s02.tb2(c1 int);
CREATE TABLE
db01=# insert into s02.tb2 values(1),(2),(3);
INSERT 0 3
db01=#
逻辑备份导出数据
1、压缩格式备份指定数据库下的数据
以压缩格式备份postgres数据库下的所有数据:
[omm@node1 backup]$ pwd
/opt/panweidb/backup
[omm@node1 backup]$ gs_dump -f db_postgres_20230228.tar -p 17700 postgres -F t
gs_dump[port='17700'][postgres][2023-02-28 11:26:59]: The total objects number is 417.
gs_dump[port='17700'][postgres][2023-02-28 11:26:59]: [100.00%] 417 objects have been dumped.
gs_dump[port='17700'][postgres][2023-02-28 11:26:59]: dump database postgres successfully
gs_dump[port='17700'][postgres][2023-02-28 11:26:59]: total time: 1789 ms
[omm@node1 backup]$ ll
total 16
-rw------- 1 omm dbgrp 12800 Feb 28 11:26 db_postgres_20230228.tar
Tips:
-f, –file=FILENAME,将输出发送至指定文件或目录。
-F, –format=c|d|t|p
选择输出格式。格式如下:
p|plain:输出一个文本SQL脚本文件(默认)。
c|custom:输出一个自定义格式的归档,并且以目录形式输出,作为gs_restore输入信息。
d|directory:该格式会创建一个目录,该目录包含两类文件,一类是目录文件,另一类是每个表和blob对象对应的数据文件。
t|tar:输出一个tar格式的归档形式,作为gs_restore输入信息。tar格式不支持压缩且对于单独表有8GB的大小限制。
2、文本格式备份指定模式下的数据
以文本方式备份db01数据库中s02模式下的数据:
[omm@node1 backup]$ gs_dump -f schema_db01_s02_20230228.sql -p17700 db01 -n s02
gs_dump[port='17700'][db01][2023-02-28 11:28:43]: The total objects number is 404.
gs_dump[port='17700'][db01][2023-02-28 11:28:43]: [100.00%] 404 objects have been dumped.
gs_dump[port='17700'][db01][2023-02-28 11:28:43]: dump database db01 successfully
gs_dump[port='17700'][db01][2023-02-28 11:28:43]: total time: 1833 ms
[omm@node1 backup]$ ls
db_postgres_20230228.tar schema_db01_s02_20230228.sql
3、文本格式备份指定表下的数据
以文本格式备份db01数据库中public模式下的tb1、tb2表
[omm@node1 backup]$ gs_dump -f table_db01_tb1_202320228.sql -p17700 db01 -t public.tb1
gs_dump[port='17700'][db01][2023-02-28 11:29:41]: The total objects number is 401.
gs_dump[port='17700'][db01][2023-02-28 11:29:41]: [100.00%] 401 objects have been dumped.
gs_dump[port='17700'][db01][2023-02-28 11:29:41]: dump database db01 successfully
gs_dump[port='17700'][db01][2023-02-28 11:29:41]: total time: 1537 ms
[omm@node1 backup]$ gs_dump -f table_db01_tb2_202320228.sql -p17700 db01 -t public.tb2
gs_dump[port='17700'][db01][2023-02-28 11:29:51]: The total objects number is 401.
gs_dump[port='17700'][db01][2023-02-28 11:29:52]: [100.00%] 401 objects have been dumped.
gs_dump[port='17700'][db01][2023-02-28 11:29:52]: dump database db01 successfully
gs_dump[port='17700'][db01][2023-02-28 11:29:52]: total time: 1603 ms
[omm@node1 backup]$ ll
total 28
-rw------- 1 omm dbgrp 12800 Feb 28 11:26 db_postgres_20230228.tar
-rw------- 1 omm dbgrp 1059 Feb 28 11:28 schema_db01_s02_20230228.sql
-rw------- 1 omm dbgrp 666 Feb 28 11:29 table_db01_tb1_202320228.sql
-rw------- 1 omm dbgrp 666 Feb 28 11:29 table_db01_tb2_202320228.sql
模拟数据丢失
[omm@node1 backup]$ gsql -d postgres -p17700 -r
gsql ((CMDB(openGauss) 1.0.1 build 58ef6fad) compiled at 2022-09-06 16:04:55 commit 0 last mr )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
CMDB=# --删除postgres数据库中public模式下的tb1、tb2
CMDB=# drop table tb1;
DROP TABLE
CMDB=# drop table tb2;
DROP TABLE
CMDB=# --切换到数据库db01
CMDB=# \c db01
Non-SSL connection (SSL connection is recommended when requiring high-security)
You are now connected to database "db01" as user "omm".
db01=# --对db02库中的public模式下的tb1、tb2做truncate操作
db01=# truncate tb1;
TRUNCATE TABLE
db01=# truncate tb2;
TRUNCATE TABLE
db01=# --切换到模式s02
db01=# set current_schema to s02;
SET
db01=# --对db02数据库中s02模式下的tb1、tb2做truncate操作
db01=# truncate tb1;
TRUNCATE TABLE
db01=# truncate tb2;
TRUNCATE TABLE
db01=#
恢复数据
1、恢复postgres库下的数据
[omm@node1 ~]$ cd /opt/panweidb/backup/
[omm@node1 backup]$ gs_restore -d postgres -p 17700 -c db_postgres_20230228.tar
start restore operation ...
table tb1 complete data imported !
table tb2 complete data imported !
table tb1 complete data imported !
table tb2 complete data imported !
Finish reading 16 SQL statements!
end restore operation ...
restore operation successful
total time: 224 ms
在数据库中查看数据恢复情况:
[omm@node1 backup]$ gsql -d postgres -p17700 -r
gsql ((CMDB(openGauss) 1.0.1 build 58ef6fad) compiled at 2022-09-06 16:04:55 commit 0 last mr )
Non-SSL connection (SSL connection is recommended when requiring high-security)
Type "help" for help.
CMDB=# \d tb1
Table "public.tb1"
Column | Type | Modifiers
--------+---------+-----------
c1 | integer |
CMDB=# \d tb2
Table "public.tb2"
Column | Type | Modifiers
--------+---------+-----------
c1 | integer |
CMDB=# select c1 from tb1;
c1
----
1
2
3
(3 rows)
CMDB=# select c1 from tb2;
c1
----
1
2
3
(3 rows)
我们可以看到表结构及数据已经完全恢复出来了。
2、恢复db01库中的s02模式下的数据
[omm@node1 backup]$ gsql -d db01 -p17700 -f schema_db01_s02_20230228.sql
SET
SET
SET
SET
SET
SET
gsql:schema_db01_s02_20230228.sql:16: ERROR: schema "s02" already exists
ALTER SCHEMA
SET
SET
SET
gsql:schema_db01_s02_20230228.sql:34: ERROR: relation "tb1" already exists in schema "s02"
DETAIL: creating new table with existing name in the same schema
ALTER TABLE
gsql:schema_db01_s02_20230228.sql:46: ERROR: relation "tb2" already exists in schema "s02"
DETAIL: creating new table with existing name in the same schema
ALTER TABLE
total time: 38 ms
恢复S02模式中的数据时,可以看到报错提示:relation "table_name" already exists in schema "s02",这是因为我们模拟数据丢失使用的是truncate操作,只清除数据,还保留表结构。我们看下数据是否恢复成功。
CMDB=# \c db01
Non-SSL connection (SSL connection is recommended when requiring high-security)
You are now connected to database "db01" as user "omm".
db01=# set current_schema to s02;
SET
db01=# \d
List of relations
Schema | Name | Type | Owner | Storage
--------+------+-------+-------+----------------------------------
s02 | tb1 | table | omm | {orientation=row,compression=no}
s02 | tb2 | table | omm | {orientation=row,compression=no}
(2 rows)
db01=# select c1 from tb1;
c1
----
1
2
3
(3 rows)
db01=# select c1 from tb2;
c1
----
1
2
3
(3 rows)
可以看到,使用文本方式逻辑备份s02模式下的数据,再恢复也是成功的。
3、恢复db01库中public模式下tb1、tb2表中的数据
[omm@node1 backup]$ gsql -d db01 -p 17700 -f table_db01_tb1_202320228.sql
SET
SET
SET
SET
SET
SET
SET
SET
SET
gsql:table_db01_tb1_202320228.sql:25: ERROR: relation "tb1" already exists in schema "public"
DETAIL: creating new table with existing name in the same schema
ALTER TABLE
total time: 24 ms
[omm@node1 backup]$ gsql -d db01 -p 17700 -f table_db01_tb2_202320228.sql
SET
SET
SET
SET
SET
SET
SET
SET
SET
gsql:table_db01_tb2_202320228.sql:25: ERROR: relation "tb2" already exists in schema "public"
DETAIL: creating new table with existing name in the same schema
ALTER TABLE
total time: 18 ms
查看数据恢复情况:
db01=# select a.c1,b.c1 from tb1 a,tb2 b where a.c1=b.c1;
c1 | c1
----+----
1 | 1
2 | 2
3 | 3
(3 rows)
可以看到,使用逻辑备份的tb1、tb2表数据也恢复了。
Tips:
gs_dump工具导出的备份文件格式可选择纯文本格式或者归档格式。纯文本格式的数据只能通过gsql进行恢复,恢复时间较长。归档格式的数据只能通过gs_restore进行恢复,恢复时间较纯文本格式短。
全库逻辑备份gs_dumpall介绍
gs_dumpall可以导出所有数据库相关信息,它可以导出磐维数据库的所有数据,包括默认数据库postgres的数据、自定义数据库的数据、以及磐维所有数据库公共的全局对象。gs_dumpall只能导出纯文本格式的数据,导出的数据只能通过gsql进行恢复,恢复时间较长。
如果通过逻辑备份进行全库恢复,通常需要重建数据库,导入备份数据来完成,对于可用性要求很高的数据库,这种恢复时间太长,通常不被采用,故不再做详细介绍。