DM8联机逻辑备份perl脚本实现要点(单双引号、system和disql)

概要

此文章非完整脚本功能分享,仅就实现逻辑备份功能进行分享。

问题背景

在编写DM8自动化备份perl脚本中,在涉及联机物理库级备份时,需要执行相关操作,正常情况下,相应语句如下(已简写,便于理解):

方式一:disql命令调用

#!/usr/bin/perl

my $user = "SYSDBA";
my $passwd = "SYSDBA";
my $bak_name = "TEMP01";
my $bak_dir = "'/usr/local/dm8/backup'";

system("disql $user/$passwd -e \"backup database full to $bak_name backupset $bak_dir\"");

方式二:disql脚本调用

#!/usr/bin/perl

my $user = "SYSDBA";
my $passwd = "SYSDBA";
my $bak_name = "TEMP01";
my $bak_dir = "'/usr/local/dm8/backup'";

#自动创建脚本文件
open bak_sql,'>','/usr/local/dm8/bak.sql';
print bak_sql "backup database full to $bak_name backupset $bak_dir;";
close bak_sql;

system("disql $user/$passwd \\`/usr/local/dm8/bak.sql");

实现过程思路一(相关基础知识在最下方三节)

 基础联机物理库级全备语句:

backup database full to TMP01 backupset '/usr/local/dm8/backup';

⚠️backupset后是备份路径,需要使用单引号!!使用双引号或不使用都会报错(见下图) 

 使用disql命令执行:

disql SYSDBA/SYSDBA -e "backup database full to TMP01 backupset '/usr/local/dm8/backup'"

在perl脚本中利用system调用命令:

#!/usr/bin/perl

system("disql SYSDBA/SYSDBA -e \"backup database full to TMP01 backupset '/usr/local/dm8/backup'\"");

思路:在system函数中套用disql命令即可,使用双引号是因为后续登陆用户名、用户密码和备份路径都将以变量形式输入,在这情况下,原先disql命令中的双引号就需要进行转义!

最终方式:将登陆用户名、用户密码、备份文件名称和备份路径都用变量表示 

#!/usr/bin/perl

my $user = "SYSDBA";
my $passwd = "SYSDBA";
my $bak_name = "TEMP01";
my $bak_dir = "'/usr/local/dm8/backup'";

system("disql $user/$passwd -e \"backup database full to $bak_name backupset $bak_dir\"");

方式一不足:

基于达梦数据库机制,建议在数据库用户下执行上述备份命令(如dmdba),通过该用户执行上述脚本没问题,如果是root用户,那么则需要切换至dmdba,此时system命令无法识别如下语句:

system("su dmdba -c \"disql SYSDBA/SYSDBA -e \"backup database full to TMP01 backupset '/usr/local/dm8/backup'\"\"")

实现过程思路二(相关基础知识在最下方三节)

事先在某路径下创建脚本文件,并使用disql命令调用:

#/opt/scripts/test.sql脚本内容:
backup database full to TMP01 backupset '/usr/local/dm8/backup';

#disql脚本调用:
[root@VM-0-8-centos scripts]# disql SYSDBA/SYSDBA \`/opt/scripts/test.sql;

⚠️`注意需要使用转义!!

在perl脚本中利用system调用命令:

#!/usr/bin/perl
system("disql SYSDBA/SYSDBA \\`/opt/scripts/test.sql");

⚠️原句中的\`是有意义的,因此,需要将\进行转义。

 最终方式:将登陆用户名、用户密码、备份文件名称和备份路径都用变量表示并且test.sql脚本文件自动生成

#!/usr/bin/perl

my $user = "SYSDBA";
my $passwd = "SYSDBA";
my $bak_name = "TEMP01";
my $bak_dir = "'/usr/local/dm8/backup'";

#自动创建脚本文件
open bak_sql,'>','/usr/local/dm8/bak.sql';
print bak_sql "backup database full to $bak_name backupset $bak_dir;";
close bak_sql;

system("disql $user/$passwd \\`/usr/local/dm8/bak.sql");

perl单双引号

单引号

要点:

单引号下,除了单引号(')和反斜线(\),其他都是正常显示,其中反斜线是转义字符。

实例:

#!/usr/bin/perl

$s1='hello world!';
print "$s1\n";

$s2='hello world!\n';
print "$s2\n";

my $s3='he\'llo world!';
print "$s3\n";

my $s4='he\'llo\' world!';
print "$s4\n";

my $s5='he\\llo world!';
print "$s5\n";

my $s6='he\\ll\\o world!';
print "$s6\n";

执行结果:

hello world!
hello world!\n
he'llo world!
he'llo' world!
he\llo world!
he\ll\o world!

错误使用:单引号内加单引号,未转义

my $s1='he'llo world!';

错误:

Bareword found where operator expected at ./my06 line 3, near "'he'llo"
    (Missing operator before llo?)
syntax error at ./my06 line 3, near "'he'llo world"
Can't find string terminator "'" anywhere before EOF at ./my06 line 3.

特别说明:单引号内加反斜线,仍显示反斜线本身!反斜线仅仅在反斜线和单引号之前,才表示为转义。

双引号

要点:

双引号内可以使用变量内插(即放入变量),和反斜线作为转义字符,只不过转义范围相较单引号更广。

转义字符列表:

\n 换行
\r   回车

\t   水平制表符

\f   换页符
\b 退格
\a 系统响铃
\e ESC (ASCⅡ 编码的转义字符)
\007 任何八进制的ASCⅡ(此例子007表示系统响铃)
\x7f   任何十六进制的ASCⅡ(此例子7f表示删除键的控制代码)
\cC   控制符,也就是control键的代码(此例子此表示同时按下ctrl键和C键的返回码)
\\ 反斜线
\" 反双引号
\l 将下个字符转为小写
\L 将到\E为止的所有字符转为小写
\u   将下个字符转为大写
\U 将到\E为止的所有字符转为大写
\Q 将到\E为止的非单词(non-word)字符加上反斜线
\E 结束\L、\U、\Q

实例:

#!/usr/bin/perl

$s1="hello world!";
print "$s1\n";

$s2="$s1";
print "$s2\n";

$s3="hel\lo world!";
print "$s3\n";

$s4="hel\\lo world!";
print "$s4\n";

$s5="he'llo' world!";
print "$s5\n";

$s6="he\'llo' world!";
print "$s6\n";

$s7="he\'llo\' world!";
print "$s7\n";

执行结果:

s1: hello world!
s2: hello world!
s3: helo world!
s4: hel\lo world!
s5: he'llo' world!
s6: he'llo' world!
s7: he'llo' world!

拓展实验:双引号里套双引号、单引号套单引号

#!/usr/bin/perl

$s1="he\"llo\" w\"orld!";
-->he"llo" w"orld!

$s2="$s1";
-->he"llo" w"orld!

$s3="hel"lo world";
-->出错

$s4="he'llo\' w'orld!";

-->he'llo' w'orld!

整体结论(注意和system函数中做区分):

在字符串中,使用print "" 中的双引号视为一个执行标识符,不具备其他意义;定义变量中的""和''都只视为怎么操作内部的符号,不具备其他意义。

system函数

使用 system() Perl函数来执行任何Unix命令,该命令的输出将进入perl脚本的输出。默认情况下,它是屏幕,即STDOUT。

变量的使用注意事项:

$PATH="hello world!";
system('echo $PATH');
system("echo $PATH");
system("echo \$PATH");

/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/dm8/bin:/root/bin
hello world!
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/usr/local/dm8/bin:/root/bin

从上面可以看出,system单引号内使用的变量为系统变量,双引号内使用的变量为perl变量,双引号内变量前$加转义字符后,便称为输出系统变量。

disql命令

该命令是达梦数据库自带的客户端命令工具,跟Oracle数据库的sqlplus工具、MySQL数据库的mysql工具一样,用来与数据库服务器进行交互。

disql使用方式:

[dmdba@VM-0-8-centos scripts]$ disql help
disql V8
version: 03134283890-20220304-158322-10045
DISQL 用法1:disql -h|help  显示disql版本信息和帮助信息

DISQL 用法2:disql [ [<option>] [<logon> | {/NOLOG}] [<start>] ]

 <option> 为: [-L] [-S]

  -L 只尝试登录一次
  -S 隐藏模式,隐藏<SQL>标识符

 <logon> 为::= {<username>[/<password>] | /}[@<connect_identifier>][<option>] [<os_auth>]
 <connect_identifier>为[<svc_name> | host[:port] | <unixsocket_file>]
 HOST如果是IPv6的地址,需要用[]指明是IPv6地址,例如[fe80::1e6f:65ff:fed1:3724%6]
 INET_TYPE如果是UNIXSOCKET类型,<connect_identifier>需要指明是unixsocket地址,例如:/data/sdb/DAMENG/foo.sock
 <option> ::= #{<extend_option>=<value>[,<extend_option>=<value>]...}
 <os_auth> ::= AS {SYSDBA|SYSSSO|SYSAUDITOR|USERS|AUTO}

 <extend_option>            <value>
 MPP_TYPE                    GLOBAL/LOCAL
 INET_TYPE                   UDP/TCP/IPC/RDMA/UNIXSOCKET
 SSL_PATH                    <path_str>
 SSL_PWD                     <pwd_str>
 PROXY_CLIENT                <user_str>
 GWDSN                       <GATEWAY DSN>

 <start> ::= <`sql脚本> | <direct cmd> | <direct sql> 运行disql脚本

 /NOLOG 选项能在未登录DM服务器的情况下启动disql

 <`sql脚本>::= `<filename>[<parameter> { <parameter>}...]"

 <direct sql>::= -e "<SQL语句>[;<SQL语句>]"

 <direct cmd>::= -c "<set 命令>"

重点关注使用方式:

1.使用脚本(⚠️反斜线在执行过程中是否需要转义)

disql 用户名/用户密码@ip地址:端口号 `脚本

如:

disql SYSDBA/SYSDBA `/usr/local/dm8/insert_data.sql;

2.使用命令

disql 用户名/用户密码@ip地址:端口号 -e "SQL语句1;SQL语句2;..."

如:

disql SYSDBA/SYSDBA -e "select * from user_tables";

disql脚本变量参数使用

 脚本文件中变量以&数字形式出现,传入参数时使用按顺序将参数写在disql脚本名后面,如:

#test.sql脚本内容:&1表示备份文件名称、&2表示备份路径

backup database full to &1 backupset &2;

[root@VM-0-8-centos scripts]# disql SYSDBA/SYSDBA

服务器[LOCALHOST:5236]:处于普通打开状态
登录使用时间 : 1.385(ms)
disql V8
SQL> `/opt/scripts/test.sql TMP01 '/usr/local/dm8/backup'
SQL> backup database full to &1 backupset &2;
原值 1:backup database full to &1 backupset &2;
新值 1:backup database full to TMP01 backupset '/usr/local/dm8/backup';
backup database full to TMP01 backupset '/usr/local/dm8/backup';
[-8055]:备份目录冲突.
已用时间: 10.729(毫秒). 执行号:0.
SQL> 

注意1:路径需要加单引号;

注意2:加参数的方式仅能进入dm8命令窗口输入,无法使用disql直接输入,如:

disql SYSDBA/SYSDBA \`/opt/scripts/test.sql tmp01 '/usr/local/dm8/backup';

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值