背景
gs_dump 是 MogDB 中一个功能丰富灵活的数据库导出工具,在数据库的维护、迁移和开发中经常使用。该工具允许用户根据需要导出整个数据库或者数据库中的特定对象,如模式(schema)、表(tables)、视图(views)等。
近期有客户咨询gs_dump如何保证数据一致性?备份期间对数据库和表如何加锁?为了解答这个问题,顺便了解一下gs_dump的实现过程,本文对该工具的源码进行了一番解读。
由于无法查看到 MogDB 的gs_dump工具的源码,所以源码使用了gitee上用openGauss 5.0版本的gs_dump代码作为参考。
脚本路径:src/bin/pg_dump/
gs_dump的功能主要在pg_dump.cpp脚本中,同目录下还有pg_backup、pg_dumpall、pg_restore等功能脚本。从脚本名字上来看,这个脚本是继承自postgres。
下面通过分析pg_dump.cpp的main函数,从源码层面解读gs_dump 导出操作时的工作流程。
初始化和设置
包含必要的头文件并设置环境相关的配置。
定义各种宏和常量以进行操作。
声明全局变量和结构体用于处理用户输入、数据库连接和转储选项。
命令行参数解析
在getopt_dump函数中使用 getopt_long 来解析命令行参数,并根据解析结果设置相应的全局变量,存储各种选项,如压缩级别、输出格式、用户名等
在getopt_dump 函数中,解析命令行的入参:
创建输出文件,注册清理机制
createArchive 函数接受了从命令行参数中解析出的输出路径,压缩等级等参数,创建输出文件。
连接数据库
ConnectDatabase函数使用给定的参数建立数据库连接,如果连接报错就清理输出文件;如果正常,则在fout对象中设置仅当前会话生效的参数。
再使用setup_connection 函数建立与数据库的连接,后面将会在此连接中执行导出。
开启事务
fout->remoteVersion >= 90100表示pg的版本大于9.1。
gs_dump 参数 --serializable-deferrable 可以控制导出事务的隔离级别。默认gs_dump事务的隔离级别为REPEATABLE READ,如果设置了serializable-deferrable参数,事务的隔离级别为SERIALIZABLE,但在Mogdb中,SERIALIZABLE等价于REPEATABLE READ,所以gs_dump事务的隔离级别始终REPEATABLE READ。DEFERRABLE允许一个只读串行事务延迟执行,即如果在导出之前,有读写事务处于活动状态,转储的开始时间可能会延迟等待读写事务结束,这样能保证使用的快照与之后的数据库状态一致。
添加导出schema和表
这部分代码使用expand_schema_name_patterns和expand_table_name_patterns 将要导出的schema和table 的oid保存在列表中。
添加schema时,schema_include_patterns参数来自于命令行参数-n,在expand_schema_name_patterns函数中,通过简单的查询pg_namespace视图,将schema的oid 添加到列表中。
而添加表时table_include_patterns和table_exclude_patterns分别来自命令行参数-t 和-T,通过查询pg_class 和 pg_namespace,将oid 添加分别添加到导出类别和排除列表中。
获取导出数据对象
扫描数据库并为要导出的所有对象创建DumpableObject结构。
获取依赖和排序
根据每个对象的依赖关系,调用getDependencies函数,整理对象间的依赖关系,调用sortDumpableObjects来决定各个数据库对象导出的顺序。
执行导出
这里主要调用了dumpDumpableObject函数,本函数根据要导出的对象类型,调用不同的导出函数进行处理。主要逻辑如下
以导出表为例,
dumpTable 函数只导出表定义,调用了dumpTableSchema生成表或视图的声明
dumpTableData函数导出表数据,根据命令行参数–inserts,选择使用copy命令导出还是导出成insert 语句
在执行COPY 命令时,会对表上加AssessShareLock锁,此锁能和除了ExclusiveLock以外的锁共存,也就是在执行copy命令不影响对表的增删改操作,只和DDL操作冲突。
导出资源
调用RestoreArchive函数,真正的导出数据。RestoreArchive函数在pg_backup_archiver.cpp文件中。
释放资源
导出完成后,释放资源,退出导出任务:
以上通过对opengauss 5.0源码中pg_dump.cpp mian函数的解读,可以了解到在执行gs_dump 操作导出数据库对象时具体做了哪些工作。
关于作者
陈坤,云和恩墨技术顾问,具有银行、保险、交易所等金融行业数据库运维经验,擅长数据库自动化运维工具开发。