在之前的博客我们了解了Sharding分片的相关信息,如下:
Oracle 18c 必须掌握的新特性 Sharding系列(3) — Sharding对象说明
https://www.cndba.cn/dave/article/3760
Oracle 18c 必须掌握的新特性 Sharding系列(4) — Sharding 分片的方法及高可用
https://www.cndba.cn/dave/article/3761
本篇了解下在SDB中执行DDL命令。
1 在SDB中执行DDL命令
当需要在SDB中新增一个模式(schema)时,必须在目录数据库中执行DDL命令,数据库会验证命令的有效性并在分片目录中创建模式。DDL命令在分片目录数据库中执行成功之后,再自动传递到所有分片上并按顺序来应用变化的数据。在执行命令之前,需要启动SHARD DDL,从而可以将相关的DDL命令传递到分片上执行。例如:
SQL>ALTER SESSION ENABLE SHARD DDL;
如果在DDL传递的过程中某个分片出现故障,那么分片目录会对故障分片进行监控,在分片恢复正常后再应用DDL命令。当给SDB添加新分片时,之前执行过的所有DDL操作会按照顺序依次在新的分片上执行,在DDL操作执行完之前该分片都无法提供访问。
如果要进行其他更细的操作,就需要连接单独的分片进行操作,而调用DBMS相关包的操作无法传递到分片上执行。例如:收集统计信息。
如果执行的操作需要锁表,那么就需要获取每个分片上相关表的锁,否则操作会失败。在分片目录上执行的多分片查询需要在每个分片数据库之间查询。在这种情况下,要确保用户对每个分片都具有相应的权限。
执行DDL命令有两种方式:
1)通过GDSCTL命令行工具,这种方法需要等到所有分片都应用了DDL操作才会返回结果
GDSCTL> sql “create tablespace set data1”
2)通过SQL*PLUS 在分片目录数据库中执行
这种方式执行DDL,只要在分片目录数据库中执行成功后就会返回结果。将DDL命令传递到其他分片会在后台以异步方式进行。执行是否成功需要通过GDSCTL中的show ddl命令来查看。
SQL> create tablespace set data1;
1.1 验证DDL传递
可以通过在GDSCTL工具中执行show ddl和config shard命令来检查DDL是否执行成功。如果是在SQLPLUS执行的DDL操作,那么必须检查每个分片的DDL执行结果,因为SQLPLUS中执行DDL操作是不会返回DDL在其他分片上的执行结果的。假如DDL操作在一个分片上执行失败了,那么这个分片上之后的所有DDL操作都会被阻塞,除非失败的命令被成功执行了,并且在GDSCTL中执行了recover shard命令。
1.2 创建本地和全局对象
当在GDSCTL中通过sql命令创建的对象,将会在所有的分片上创建,这种对象就叫做SDB对象(全局对象)。
当通过SQLPLUS连接分片目录数据库时则可以创建两种对象:SDB对象和本地对象。本地对象只会存储在分片目录数据库中。默认创建的也是SDB对象。如果想要创建本地对象,那么需要禁用SHARD DDL(SDB用户执行alter session disable shard ddl)。如果想要启用某个用户的DDL ,那么该用户必须存在于所有分片和分片目录数据库(也叫SDB用户)。
1.3 创建SDB用户和模式对象
本地用户只能用来创建分片目录数据库中的对象,而没有权限在所有分片中创建对象。因此,如果想要创建SDB 对象,首先启用SHARD DDL并执行CREATE USER命令。默认情况下,SDB用户连接分片目录数据库时会启用SHARD DDL。然后可以通过SDB用户创建其他支持的对象。
本地用户如果启用SHARD DDL,则可以创建non-schema SDB对象,如表空间,directory和context;但是无法创建schema的SDB对象,例如表,视图,索引,函数,存储过程等。 分片对象不能依赖本地对象。例如,无法在本地表上创建分片视图。
1.4 具体实例
1.4.1创建SDB用户
首先启用Shard DDL
SQL> alter session enable shard ddl;
Session altered.
SQL> create user lei identified by oracle;
User created.
验证是否所有分片都执行成功
GDSCTL> show ddl;
id DDL Text Failed shards
-- -------- -------------
….略
19 create user lei identified by ***** #如果某个分片执行失败,那么会显示具体分片名
注意对于由于分片故障导致DDL执行失败,在分片正常后DDL会自动被再次执行。
1.4.2由于某个分片故障导致该分片执行DDL失败的解决方法
这个例子主要是介绍在执行某个DDL操作时,由于某个分片本身的原因而导致DDL在该分片上执行失败,然后根据具体原因找出解决办法,那么失败的DDL操作会重新在该分片上执行。
创建表空间集,在分片目录数据库上执行创建表空间集:
SQL> conn shard_user/oracle
Connected.
SQL> create tablespace set cndba_tbs;
Tablespace created.
查看DDL执行结果,可以看到在分片sh81上执行失败了:
GDSCTL> show ddl;
id DDL Text Failed shards
-- -------- -------------
11 CREATE SHARDED TABLE Customers ( ...
12 CREATE SHARDED TABLE Orders ( O...
13 CREATE SEQUENCE Orders_Seq
14 CREATE SHARDED TABLE LineItems ( ...
15 CREATE MATERIALIZED VIEW "SHARD_USER"...
16 CREATE MATERIALIZED VIEW "SHARD_USER"...
17 CREATE TABLESPACE SET data1
18 CREATE MATERIALIZED VIEW "SHARD_USER"...
19 create user lei identified by *****
20 create tablespace set cndba_tbs sh81
查看分片上失败的具体原因,可以看到是由于数据文件存放路径权限不对,导致Oracle无法创建数据文件导致DDL执行失败。
GDSCTL> config shard -shard sh81
Name: sh81
……
Failed DDL: create tablespace set cndba_tb...
DDL Error: ORA-02585: create tablepsace set failure, one of its tablespaces not created
ORA-06512: at "SYS.EXECASUSER", line 44
ORA-01264: Unable to create datafile file name
ORA-19800: Unable to initialize Oracle Managed Destination
Linux-x86_64 Error: 13: Permission denied
ORA-06512: at "SYS.DBMS_SYS_SQL", line 1529
ORA-06512: at "SYS.EXECASUSER", line 31
ORA-06512: at "GSMADMIN_INTERNAL.EXECUTEDDL", line 58
ORA-06512: at line 1 /(ngsmoci_execute/)
Failed DDL id: 20
解决方法,将目录权限改为Oracle可以进行读写操作即可:
当前目录权限:
[dave@www.cndba.cn oradata]# pwd
/u01/app/oracle/oradata
[dave@www.cndba.cn oradata]# ll
total 0
drwxr-xr-x 2 root root 6 Sep 11 09:09 datafile
修改为oracle用户,组为oinstall:
[dave@www.cndba.cn oradata]# chown oracle.oinstall datafile
[dave@www.cndba.cn oradata]# ll
total 0
drwxr-xr-x 2 oracle oinstall 6 Sep 11 09:09 datafile
drwxr-x--- 3 oracle oinstall 216 Aug 1 17:00 SH81
手动执行恢复操作:
GDSCTL> recover shard -shard sh81
The operation completed successfully
再次查看DDL执行结果:
GDSCTL> show ddl;
id DDL Text Failed shards
-- -------- -------------
11 CREATE SHARDED TABLE Customers ( ...
12 CREATE SHARDED TABLE Orders ( O...
13 CREATE SEQUENCE Orders_Seq
14 CREATE SHARDED TABLE LineItems ( ...
15 CREATE MATERIALIZED VIEW "SHARD_USER"...
16 CREATE MATERIALIZED VIEW "SHARD_USER"...
17 CREATE TABLESPACE SET data1
18 CREATE MATERIALIZED VIEW "SHARD_USER"...
19 create user lei identified by *****
20 create tablespace set cndba_tbs
查看失败分片的状态,恢复正常:
GDSCTL> config shard -shard sh81
Name: sh81
……
CPU Threshold, %: 75
Version: 18.0.0.0
Failed DDL:
DDL Error: ---
Failed DDL id:
1.4.3 由于某个分片执行DDL失败,恢复所有分片的解决方法
本例主要是介绍因某个分片上存在相同对象导致DDL执行失败的解决方法,如果出现该情况,只能删除已经在其他分片上创建的对象,然后用其他名称重新创建该对象。
创建表空间集:
SQL> conn shard_user/oracle
Connected.
SQL> create tablespace set suyi_tbs;
Tablespace created.
查看DDL执行结果,在分片sh81上执行失败:
GDSCTL> show ddl;
id DDL Text Failed shards
-- -------- -------------
12 CREATE SHARDED TABLE Orders ( O...
13 CREATE SEQUENCE Orders_Seq
14 CREATE SHARDED TABLE LineItems ( ...
15 CREATE MATERIALIZED VIEW "SHARD_USER"...
16 CREATE MATERIALIZED VIEW "SHARD_USER"...
17 CREATE TABLESPACE SET data1
18 CREATE MATERIALIZED VIEW "SHARD_USER"...
19 create user lei identified by *****
20 create tablespace set cndba_tbs
21 create tablespace set suyi_tbs sh81
查看失败的原因,分片sh81上已经存在了表空间suyi_tbs所以导致创建表空间集失败:
GDSCTL> config shard -shard sh81
Name: sh81
...
Failed DDL: create tablespace set suyi_tbs
DDL Error: ORA-02585: create tablepsace set failure, one of its tablespaces not created
ORA-06512: at "SYS.EXECASUSER", line 44
ORA-01543: tablespace /'SUYI_TBS/' already exists
ORA-06512: at "SYS.DBMS_SYS_SQL", line 1529
ORA-06512: at "SYS.EXECASUSER", line 31
ORA-06512: at "GSMADMIN_INTERNAL.EXECUTEDDL", line 58
ORA-06512: at line 1 /(ngsmoci_execute/)
Failed DDL id: 21
解决方法, 由于创建表空间集的操作已经在其他分片执行成功了,所以只能先将其他分片上该表空间集删除,然后重新创建。
在分片目录数据库中删除、创建新的表空间集:
SQL> drop tablespace set suyi_tbs;
Tablespace dropped.
SQL> create tablespace set suyi_tbs2;
Tablespace created.
查看执行结果, 如果某个分片上的DDL执行失败,那么就会阻塞之后的所有该分片上的DDL操作。所以ID是22和23的DDL操作都没有在分片sh81上执行。
DSCTL> show ddl;
id DDL Text Failed shards
-- -------- -------------
14 CREATE SHARDED TABLE LineItems ( ...
15 CREATE MATERIALIZED VIEW "SHARD_USER"...
16 CREATE MATERIALIZED VIEW "SHARD_USER"...
17 CREATE TABLESPACE SET data1
18 CREATE MATERIALIZED VIEW "SHARD_USER"...
19 create user lei identified by *****
20 create tablespace set cndba_tbs
21 create tablespace set suyi_tbs sh81
22 drop tablespace set suyi_tbs
23 create tablespace set suyi_tbs2
跳过分片sh81, 由于ID是21的DDL操作执行失败,那么可以通过指定–ignore_first选项来跳过分片sh81,使该DDL不会在该分片上执行:
GDSCTL> recover shard -shard sh81 -ignore_first;
GSM Errors:
primary_grp sh81:ORA-00959: tablespace /'SUYI_TBS/' does not exist
ORA-06512: at "SYS.EXECASUSER", line 44
ORA-06512: at "SYS.DBMS_SYS_SQL", line 1529
ORA-06512: at "SYS.EXECASUSER", line 31
ORA-06512: at "GSMADMIN_INTERNAL.EXECUTEDDL", line 58
ORA-06512: at line 1 (ngsmoci_execute)
再次查看下一个DDL执行结果,ID是22的DDL也执行失败了,因为分片上该表空间集不存在,那么肯定无法删除了。
GDSCTL> show ddl;
id DDL Text Failed shards
-- -------- -------------
14 CREATE SHARDED TABLE LineItems ( ...
15 CREATE MATERIALIZED VIEW "SHARD_USER"...
16 CREATE MATERIALIZED VIEW "SHARD_USER"...
17 CREATE TABLESPACE SET data1
18 CREATE MATERIALIZED VIEW "SHARD_USER"...
19 create user lei identified by *****
20 create tablespace set cndba_tbs
21 create tablespace set suyi_tbs
22 drop tablespace set suyi_tbs sh81
23 create tablespace set suyi_tbs2
继续跳过该分片,不执行ID是22的DDL操作
GDSCTL> recover shard -shard sh81 -ignore_first;
The operation completed successfully
再看创建新的表空间结果,新的表空间集suyi_tbs2在所有分片上都执行成功:
GDSCTL> show ddl;
id DDL Text Failed shards
-- -------- -------------
14 CREATE SHARDED TABLE LineItems ( ...
15 CREATE MATERIALIZED VIEW "SHARD_USER"...
16 CREATE MATERIALIZED VIEW "SHARD_USER"...
17 CREATE TABLESPACE SET data1
18 CREATE MATERIALIZED VIEW "SHARD_USER"...
19 create user lei identified by *****
20 create tablespace set cndba_tbs
21 create tablespace set suyi_tbs
22 drop tablespace set suyi_tbs
23 create tablespace set suyi_tbs2
版权声明:本文为博主原创文章,未经博主允许不得转载。