MySQL InnoDB内存配置

InnoDB内存配置
MySQL将内存分配给各种缓存和缓冲区,以提高数据库操作的性能。当为InnoDB分配内存时,总是考虑操作系统需要的内存,分配给其他应用程序的内存,以及分配给其他MySQL缓冲区和缓存的内存。例如,如果您使用MyISAM表,请考虑分配给键缓冲区的内存量(key_buffer_size)。

InnoDB特定的缓冲区使用以下参数配置:
.innodb_buffer_pool_size定义缓冲池的大小,缓冲池是存放InnoDB表、索引和其他辅助缓冲区缓存数据的内存区域。缓冲池的大小对系统性能很重要,通常建议将innodb_buffer_pool_size配置为系统内存的50%到75%。默认的缓冲池大小是128MB。

在具有大量内存的系统上,可以通过将缓冲池划分为多个缓冲池实例来提高并发性。缓冲池实例的数量由innodb_buffer_pool_instances选项控制。默认情况下,InnoDB创建一个缓冲池实例。缓冲池实例的数量可以在启动时配置。

.innodb_log_buffer_size以字节为单位定义InnoDB所要写入磁盘日志文件中的日志缓存区大小。默认大小为16MB。大型日志缓冲区允许运行大型事务,而不需要在事务提交之前将日志写入磁盘。如果有更新、插入或删除许多行的事务,可以考虑增加日志缓冲区的大小以节省磁盘I/O。Innodb_log_buffer_size可以在启动时配置

警告:
在32位GNU/Linux x86上,注意不要将内存占用设置得太高。glibc可能允许进程堆堵塞线程堆栈,这会导致服务器崩溃。如果分配给mysqld进程的全局和每个线程的缓冲区和缓存的内存接近或超过2GB,这是一个风险。

一个类似于下面的公式,计算MySQL的全局和每个线程的内存分配,可以用来估计MySQL的内存使用。您可能需要修改公式,以考虑到MySQL版本和配置中的缓冲区和缓存。
innodb_buffer_pool_size+ key_buffer_size+ max_connections*(sort_buffer_size+read_buffer_size+binlog_cache_size)+ max_connections*2MB

每个线程使用一个堆栈(通常是2MB,但在Oracle公司提供的MySQL二进制文件中只有256KB),在最坏的情况下还使用sort_buffer_size +read_buffer_size的额外内存

在Linux上,如果内核启用了大页支持,InnoDB可以使用大页为其缓冲池分配内存。

MySQL InnoDB页面大小配置

InnoDB页面大小配置
innodb_page_size选项指定了MySQL实例的所有InnoDB表空间的页面大小。这个值是在创建实例时设置的,之后保持不变。有效值为64K,32K,16K(默认值 ),8k和4k。另外,也可以以字节为单位来指定页面大小(65536,32768,16384,8192,4096)。

默认页面大小为16k适合于各种工作负载,特别是涉及表扫描的查询和涉及批量更新的DML操作。对于涉及许多小写的OLTP工作负载来说,较小的页面大小可能更有效,在这种情况下,当单个页面包含许多行时,争用可能是一个问题。对于SSD存储设备,较小的页面可能也很有效,SSD存储设备通常使用较小的块大小。保持InnoDB页面大小接近存储设备块大小,可以最大限度地减少被重写到磁盘的未更改数据量。

InnoDB内存配置
MySQL将内存分配给各种缓存和缓冲区,以提高数据库操作的性能。当为InnoDB分配内存时,总是考虑操作系统需要的内存,分配给其他应用程序的内存,以及分配给其他MySQL缓冲区和缓存的内存。例如,如果您使用MyISAM表,请考虑分配给键缓冲区的内存量(key_buffer_size)。

MySQL InnoDB临时表空间配置

InnoDB临时表空间配置
默认情况下,InnoDB将在innodb_data_home_dir目录中创建一个名为ibtmp1且自动扩展大小略大小12MB的临时表侬间数据文件。默认的临时表空间数据文件配置可以在启动时使用innodb_temp_data_file_path配置选项来进行修改。

innodb_temp_data_file_path选项指定InnoDB临时表空间数据文件的路径,文件名和文件大小。一个文件的完整目录路径是由innodb_data_home_dir和innodb_temp_data_file_path拼接而成的。文件大小以KB,MG或GB为单位进行指定,表示方式为K,M或G。文件的总大小要略大于12MB。

innodb_data_home_dir默认值为MySQL数据目录(datadir)。

MySQL InnoDB Undo表空间配置

InnoDB Undo表空间配置
默认情况下,InnoDB undo日志是系统表空间的一部分。然后,可以选择在一个或多个单独的undo表空间来存储(表空间通常存储在不同的存储设备上)InnoDB undo日志。

innodb_undo_directory配置选项定义了InnoDB为存储undo日志所创建单独表空间的目录路径。这个选项通常与innodb_rollback_segments和innodb_undo_tablespaces选项联合使用,它决定了unod日志在系统表空间这外的磁盘布局。

注意:innodb_undot_tablespaces将在未来的版本中被丢弃和删除。

MySQL InnoDB日志文件配置

InnoDB日志文件配置
默认情况下,InnoDB将在MySQL数据目录(datadir)中创建大小为48MB名为ib_logfile0和ib_logfile1的两个日志文件。

下面的选项可以被用来修改默认配置:
.innodb_log_group_home_dir 定义InnoDB日志文件(重做日志)的目录路径。如果这个选项没有被配置,InnoDB日志文件将会在MySQL数据目录(datadir)中创建。

可以使用这个选项将InnodDB日志文件与InnoDB数据文件存储在不同的物理存储位置来避免潜在的I/O资源冲突。例如:

[mysqld]
innodb_log_group_home_dir=/dr3/iblogs

注意:InnoDB不会创建目录,因此要确保在启动MySQL服务器之前日志目录已经存在。要确保MySQL服务器对日志目录有正确权限来创建日志文件。

.innodb_log_files_in_group定义日志组中的日志文件数。默认与建议值为2.

.innodb_log_file_size定义日志组中每个日志文件的大小以字节为单位。日志文件的总大小(innodb_log_file_size*innodb_log_files_in_group)不能超过最大值512GB,也就是略小于512GB。一对大小255GB大小的日志文件,就是略接近最大值但不超过它。默认的日志文件大小为48MB。通常,日志文件的合并大小应该足够大,以便服务器能够平滑工作负载活动的高峰和低谷,这通常意味着有足够的重做日志空间来处理超过一个小时的写活动。该值越大,缓冲池中需要的检查点刷新活动就越少,从而节省磁盘I/O。

MySQL InnoDB系统表空间数据文件配置

系统表空间数据文件配置
系统表空间数据文件是通过innodb_data_file_path和innodb_data_home_dir配置选项来进行配置的。

innodb_data_file_path配置选项被用来配置InnoDB系统表空间数据文件。innodb_data_file_path应该是一个或多个数据文件的规范列表。如果要命名多个数据文件,使用分号(;)来进行分隔:
innodb_data_file_path=datafile_spec1[;datafile_spec2]…

例如,下面的设置创建一个最小大小的系统表空间:

[mysqld]
innodb_data_file_path=ibdata1:12M:autoextend

上面的设置配置一个12MB大小命名为ibdata1且自动扩展的数据文件。这里没有指定文件路径,因此,InnoDB将在MySQL数据目录中创建该文件。

数据文件大小可以通过K,M,或G后缀来指示KB,MG或GB。

如果一个表空间包含一个名为ibdata1固定大小为50MB和一个名为ibdata2大小为50MB自动扩展的数据文件可以进行以下配置:

[mysqld]
innodb_data_file_path=ibdata1:50;ibdata2:50:autoextend

数据文件规范的完整语法包括文件名,文件大小和多个选项属性:

file_name:file_size[:autoextend[:max:max_file_size]]

autoexten和max属性只能用于innodb_data_file_path行中的最后一个数据文件

如果对最后一个数据文件指定了autoextend,当表空间中没有可用空间时InnoDB会扩展数据文件大小。默认情况下是一次扩展64MB。为了修改增量,可以修改innodb_autoextend_increment系统变量。

如果存储表空间数据文件的磁盘空间填满,可以在其实磁盘上给表空间增加数据文件。

InnoDB不知道文件系统的最大文件大小,因此要注意文件系统的最大文件大小,比如2GB。为了给自动扩展的数据文件指定一个最大大小,在autoextend属性后面使用max属性。只在限制磁盘使用至关重要的情况下使用max属性,因为超过最大大小会导致致命的错误,可能包括崩溃。下面的设置允许ibdata1增长到限制所指定的500MB:

[mysqld]
innodb_data_file_path=ibdata1:12M:autoextend:max:500M

默认情况下InnoDB在MySQL数据目录(datadir)中创建表空间文件。为了显式指定存储位置,使用innodb_data_home_dir选项。例如,为了在名为myibdata目录中创建两个名为ibdata1和ibdata2的数据文件,使用如下配置:

[mysqld]
innodb_data_home_dir=/path/to/myibdata/
innodb_data_file_path=ibdata1:50M;ibdata2:50M:autoextend

注意:在给innodb_data_home_dir指定值时需要使用斜杆。

InnoDB不会创建目录,因此确保在启动MySQL服务器之前指定的myibdata目录已经存在。还要确保MySQL服务器对所指定的目录有正确的权限来创建文件。更通俗地说,服务器必须在需要创建数据文件的任何目录中具有访问权限。

InnoDB通过将innodb_data_home_dir的值与数据文件名进行文本连接来形成每个数据文件的目录路径。如果在my.cnf中没有指定innodb_data_home_dir选项,那么默认值是“dot”目录./,意思是MySQL数据目录。(MySQL服务器在开始执行时将其当前工作目录更改为数据目录。)

如果将innodb_data_home_dir指定为空字符串,则可以为innodb_data_file_path值中列出的数据文件指定绝对路径。下面的示例等价于上面的设置:

[mysqld]
innodb_data_home_dir=
innodb_data_file_path=/path/to/myibdata/ibdata1:50M;/path/to/myibdata/ibdata2:50M:autoextend

MySQL Deadlocks in InnoDB

Deadlocks in InnoDB
死锁是指不同的事务无法进行处理的情况,因为每个事务都持有对方需要的锁。因为这两个事务都在等待资源可用, 他们都没有释放过它所持有的锁。

当事务锁定多个表中的行(通过update或select … for update等语句),但顺序相反时会发生死锁。当这样的语句锁定索引条目和间隙范围时,每个事务由于时间问题获得一些锁定,而不获得其他锁定也会发生死锁。

为了减少死锁的可能性,请使用事务处理,而不是锁定表语句;保持插入或更新数据的事务处理足够小,以免长时间保持开放,当不同的事务更新多个表或大范围的行时,请在每个事务中使用相同的操作顺序(例如select … for update,在select … for update和update … where语句所使用的列上创建索引。死锁的可能性不受隔离级别的影响,因为隔离级别改变了读取操作的行为,列锁是由于写操作引起的。

当启用死锁检测(默认)并发生死锁时,InnoDB会检测触发条件并回滚其中一个事务(受害者)。如果使用innodb_deadlock_detect配置选项禁用死锁检测,InnoDB依赖于innodb_lock_wait_timeout设置来在发生死锁时回滚事务。因此,即使您的应用程序逻辑是正确的, 您仍然必须处理必须重试事务的情况。若要查看InnoDB用户事务中的最后一个死锁,请使用show engine innodb status命令。如果频繁的出现死锁这就突出表时事务结构或应用程序错误处理存在问题,可以启用innodb_print_all_deadlocks设置将所有死锁的信息打印到mysqld错误日志。

一个InnoDB死锁示例
下面的例子将演示当一个锁请求将造成死锁时可能出现的错误。这个例子将调用两个客户端A和B。

首先客户端A创建一个表并插入一行记录,然后开始一个事务。在这个事务中通过请求共享模式锁的查询语句来对行获得共享锁:

mysql> create table t(i int) engine=innodb;
Query OK, 0 rows affected (0.11 sec)

mysql> insert into t values(1);
Query OK, 1 row affected (0.02 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t where i=1 lock in share mode;
+------+
| i    |
+------+
|    1 |
+------+
1 row in set (0.00 sec)

客户端B开始一个事务并试图从表中删除这行记录:

mysql> start transaction;
Query OK, 0 rows affected (0.01 sec)

mysql> delete from t where i=1;

删除操作请求一个X锁。因它它与客户端A所持有的S锁不兼容,因此请求将会在锁请求队列中进行大排队并且客户端B会被阻塞

最后,客户端A也试图删除这行记录:

mysql> delete from t where i=1;

客户端B出现错误信息:

mysql> delete from t where i=1;
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

这里会发生死锁,因为客户端A需要一个X锁来删除该行。但是,不能授予该锁定请求,因为客户端B已经有了一个关于X锁定的请求,并且正在等待客户端A 来释放它的S锁。由于B事先请求使用X锁,也不能将A持有的S锁升级为X锁。因此,InnoDB会为其中一个客户端通过成错误信息并释放它所持有的锁。客户端将返回以下错误:

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

在这时,客户端A可以被授予锁请求并从表中删除记录

mysql> delete from t where i=1;
Query OK, 1 row affected (0.00 sec)

死锁检测与回滚
当死锁检测被启用时(默认值),InnoDB会自动检测事务的死锁并回滚其中的一个事务或多个事务来打破死锁。InnoDB尝试选择小事务来进行回滚,而事务的大小是由插入,更新或删除的行记录数来判断的。

如果innodb_table_locks=1(默认)和autocommit=0,而且MySQL层知道行级锁,那么InnoDB就知道表锁。否则,InnoDB无法检测到由MySQL locktables语句设置的表锁或由InnoDB以外的存储引擎设置的锁。通过设置innodb_lock_wait_timeout系统的值来解决这些情况。

当InnoDB执行完一个事务的回滚,由该事务所设置的锁都会被释放。但是,如果由于错误只导致一个SQL语句被回滚,则该语句设置的一些锁可能会被保留。这是因为InnoDB以一种格式存储行锁,这样之后就不能知道哪个语句设置了哪个锁。

如果一个事务中的SELECT调用一个存储函数,并且函数中的语句执行失败,这个语句被回滚。之后,如果执行回滚,那么整个事务将会被回滚。

如果InnoDB监控输出的LATEST DETECTED DEADLOCK部分包含一条”TOO DEEP OR LONG SEARCH IN THE LOCK TABLE WAITS-FOR GRAPH, WE WILL ROLL BACKFOLLOWING TRANSACTION”信息,这指示等待列表中的事务数据已经超过了200的限制。当等待列表超过200个事务时就会当作死锁并且试图检查等待列表的事务将被回滚。如果锁定线程必须查看超过1000000个锁是由等待列表中事务所持有也会出现同样的错误。

禁用死锁检测
在高并发系统中,当多线程等待同一个锁时,死锁检测可能会导致速度减慢。这时禁用死锁检测并依赖innodb_lock_wait_timeout在出现死锁时进行事务的回滚可能更有效。可以通过innodb_deadlock_detect配置选项来禁用死锁检测。

如何减少和处理死锁
下面介绍如何组织数据库操作来减少死锁以及处理死锁。

死锁是事务型数据库中一个非常经典的问题,但它们并不危险,除非频繁出现死锁且不能运行特定的事务。正常来说如果事务因为死锁被回滚那么你必须编写你的应用程序来准备重新执行事务。

InnoDB使用自动行级锁。那么可能在只有插入或删除单行记录时也会出现死锁。这是因为这些操作不是真正原子的,它们自动在被插入或删除的行记录所对应的索引记录在设锁。

您可以通过以下技术来处理死锁,并减少其发生的可能性:
.的任何时候,可以执行show engine innodb status命令来判断最近出现死锁的情况。这可以帮助你优化程序来避免死锁。

.如果经常出现死锁警告引起关注,请通过启用innodb_print_all_deadlocks配置选项来收集更广泛的调试信息。关于每个死锁的信息,而不仅仅是被记录在MySQL错误日志中最新的一个,调试后禁用此选项。

.如果事务由于死锁而失败,请随时准备重新执行它。死锁并不危险。再试一次。

.保持事务持续时间小和短,使它们不容易发生碰撞。

.在进行一组相关更改后立即提交事务,使它们不容易发生碰撞。特别是,不要让一个交互式mysql会话长期打开一个未已提交的事务。

.如果使用锁定读取(select … for update 或select … lock in share mode),那么尝试使用低隔离级别比如read committed。

.当修改事务中的多个表或同一表中的不同行集时,每次都按照一致的顺序执行这些操作。然后事务形成定义良好的队列且不会死锁。例如,将数据库操作组织成应用程序中的函数,或调用存储例程,而不是在不同的地方编码多个插入、更新和删除语句。

.向表中添加选择良好的索引。然后,您的查询需要扫描更少的索引记录,从而设置更少的锁。使用explain select来判断MySQL服务器认为哪些索引最适合您的查询。

.使用更少的锁定。如果您可以允许select语句从旧快照返回数据,请不要向语句中添加for update或lock in share mode子句。使用read committed读提交的隔离级别是不错的选择, 因为同一事务中的每个一致性读取都是从它自己的新快照中读取的。

.如果没有其他帮助,请使用表级锁序列化你的事务。对事务表使用lock tables,如InnoDB表,使用set autocommit=0开始事务(而不是start transaction),接着使用lock tables,并且在显式提交事务之前不要unlock tables。例如,如果您需要写入表t1并从表t2中读取,可以执行如下操作:

set autocommit=0;
lock tables t1 write,t2 read,...;
... do something with tables t1 and t2 here ..
commit;
unlock tables;

表级锁阻止对表的并发更新,以牺牲繁忙系统的响应能力为代价避免死锁。

.另一种序列化事务的方法是创建一个仅包含一行的辅助“信号量”表。在访问其他表之前,让每个事务都要更新该行。通过这种方式,所有事务以一种串行的方式发生。请注意,InnoDB即时死锁检测算法在这种情况下也可以工作,因为序列化锁是一个行级锁。使用MySQL表级锁时,必须使用超时方法来解决死锁。

DM8使用共享存储DMASM搭建DMRAC

1.环境准备
硬件:两台相同配置机器,8G内存,80G本地磁盘,2块网卡,另有6块共享磁盘大小分别为2G,2G,10G,10G,10G,10G 操作系统:RedHat Linux 64位。

网络配置:ens32网卡为10.10.10.0内网网段,两台机器分别为10.10.10.201/10.10.10.202;ens34为11.11.11.0外网网段,两台机器分别为11.11.11.11.1/11.11.11.2。内网网段用于MAL通讯。

DM各种工具位于目录:/dm8/dmdbms/bin。配置文件位于目录:/dm8/data。

搭建2节点DMDSC(DMASM)
1.环境准备

主机	 IP地址(对外服务)	IP地址(内部通信) 	实例名	操作系统
dm8rac1	10.10.10.201	        11.11.11.1	        rac0	Redhat 7.8
dm8rac2	10.10.10.202	        11.11.11.2	        rac1	Redhat 7.8

共享存储
/dev/sdb	/dev/raw/raw1	dcr disk	2G
/dev/sdc	/dev/raw/raw2	voting disk	2G
/dev/sdd	/dev/raw/raw3	log disk	10G
/dev/sde	/dev/raw/raw4	data disk1	10G
/dev/sdf	/dev/raw/raw5	data disk2	10G
/dev/sdg	/dev/raw/raw6	data disk3	10G

二、操作系统配置
1、关闭防火墙和SELINUX

[root@gbase ~]# systemctl stop firewalld
[root@gbase ~]# systemctl disable firewalld
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@gbase ~]# systemctl status firewalld
   firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)

Dec 06 17:22:42 gbase systemd[1]: Starting firewalld - dynamic firewall daemon...
Dec 06 17:22:48 gbase systemd[1]: Started firewalld - dynamic firewall daemon.
Dec 07 08:21:59 gbase systemd[1]: Stopping firewalld - dynamic firewall daemon...
Dec 07 08:22:00 gbase systemd[1]: Stopped firewalld - dynamic firewall daemon.

[root@gbase ~]# setenforce 0
[root@gbase ~]# sed -i s:^SELINUX=.*$:SELINUX=disabled:g /etc/selinux/config
[root@gbase ~]# cat /etc/selinux/config

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted


[root@gbase ~]# systemctl stop firewalld
[root@gbase ~]# systemctl disable firewalld
Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
[root@gbase ~]# systemctl status firewalld
   firewalld.service - firewalld - dynamic firewall daemon
   Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:firewalld(1)

Dec 06 17:22:45 gbase systemd[1]: Starting firewalld - dynamic firewall daemon...
Dec 06 17:22:51 gbase systemd[1]: Started firewalld - dynamic firewall daemon.
Dec 07 08:19:39 gbase systemd[1]: Stopping firewalld - dynamic firewall daemon...
Dec 07 08:19:40 gbase systemd[1]: Stopped firewalld - dynamic firewall daemon.
[root@gbase ~]# setenforce 0
[root@gbase ~]# sed -i s:^SELINUX=.*$:SELINUX=disabled:g /etc/selinux/config
[root@gbase ~]# cat /etc/selinux/config

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected.
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

2、修改主机名

[root@gbase ~]# hostname dm8rac1
[root@gbase ~]# sed -i s:^HOSTNAME=.*$:HOSTNAME=dm8rac1:g /etc/sysconfig/network
[root@gbase ~]# echo "
 > 10.10.10.201   dm8rac1
 > 10.10.10.202   dm8rac2" >> /etc/hosts
[root@gbase ~]# cat  /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

 10.10.10.201   dm8rac1
 10.10.10.202   dm8rac2


[root@gbase ~]# hostname dm8rac2
[root@gbase ~]# sed -i s:^HOSTNAME=.*$:HOSTNAME=dm8rac2:g /etc/sysconfig/network
[root@gbase ~]#
[root@gbase ~]# echo "
>  10.10.10.201   dm8rac1
>  10.10.10.202   dm8rac2" >> /etc/hosts
[root@gbase ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

 10.10.10.201   dm8rac1
 10.10.10.202   dm8rac2

三、 安装达梦软件
3.1检查Linux(Unix)系统信息

[root@dm8rac1 ~]# getconf LONG_BIT
64

[root@dm8rac2 ~]# getconf LONG_BIT
64

查询操作系统release信息

[root@dm8rac1 ~]# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.8 Beta (Maipo)

[root@dm8rac2 ~]# cat /etc/redhat-release
Red Hat Enterprise Linux Server release 7.8 Beta (Maipo)

3.2创建安装用户
为了减少对操作系统的影响,用户不应该以root系统用户来安装和运行DM。用户可以在安装之前为DM创建一个专用的系统用户。
1. 创建安装用户组dinstall。

[root@dm8rac1 ~]# groupadd dinstall

[root@dm8rac2 ~]# groupadd dinstall

2. 创建安装用户dmdba。

[root@dm8rac1 ~]# useradd -g dinstall -m -d /home/dmdba -s /bin/bash dmdba

[root@dm8rac2 ~]# useradd -g dinstall -m -d /home/dmdba -s /bin/bash dmdba

3. 初始化用户密码。

[root@dm8rac1 ~]# passwd dmdba
Changing password for user dmdba.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

[root@dm8rac2 ~]# passwd dmdba
Changing password for user dmdba.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

3.3 Linux(Unix)下检查操作系统限制
在Linux(Unix)系统中,因为ulimit命令的存在,会对程序使用操作系统资源进行限制。为了使DM能够正常运行,建议用户检查当前安装用户的ulimit参数。

运行ulimit -a进行查询。如下图所示:

[root@dm8rac1 ~]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 31152
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 31152
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

[root@dm8rac2 ~]# ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 31152
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 31152
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

参数使用限制:
1.data seg size
data seg size (kbytes, -d)
建议用户设置为1048576(即1GB)以上或unlimited(无限制),此参数过小将导致数据库启动失败。
2. file size
file size(blocks, -f)
建议用户设置为unlimited(无限制),此参数过小将导致数据库安装或初始化失败。
3. open files
open files(-n)
建议用户设置为65536以上或unlimited(无限制)。
4.virtual memory
virtual memory (kbytes, -v)
建议用户设置为1048576(即1GB)以上或unlimited(无限制),此参数过小将导致数据库启动失败。如果用户需要为当前安装用户更改ulimit的资源限制,请修改文件/etc/security/limits.conf。

[root@dm8rac1 ~]# vi /etc/security/limits.conf
dmdba soft data unlimited
dmdba hard data unlimited
dmdba soft fsize unlimited
dmdba hard fsize unlimited
dmdba soft nofile 65536
dmdba hard nofile 65536

[root@dm8rac2 ~]# vi /etc/security/limits.conf
dmdba soft data unlimited
dmdba hard data unlimited
dmdba soft fsize unlimited
dmdba hard fsize unlimited
dmdba soft nofile 65536
dmdba hard nofile 65536

[root@dm8rac1 ~]# su - dmdba
[dmdba@dm8rac1 ~]$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 31152
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65536
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 4096
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited


[root@dm8rac2 ~]# su - dmdba
[dmdba@dm8rac2 ~]$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 31152
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 65536
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 4096
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

3.4.检查系统内存与存储空间
1.检查内存
为了保证DM的正确安装和运行,要尽量保证操作系统至少1GB的可用内存(RAM)。如果可用内存过少,可能导致DM安装或启动失败。用户可以使用以下命令检查操作内存:
#获取内存总大小

[root@dm8rac1 ~]# grep MemTotal /proc/meminfo
MemTotal:        8009068 kB

[root@dm8rac12 ~]# grep MemTotal /proc/meminfo
MemTotal:        8009068 kB

#获取交换分区大小

[root@dm8rac1 ~]# grep SwapTotal /proc/meminfo
SwapTotal:       8257532 kB

[root@dm8rac2 ~]# grep SwapTotal /proc/meminfo
SwapTotal:       8257532 kB

#获取内存使用详情

[root@dm8rac1 ~]# free -g
              total        used        free      shared  buff/cache   available
Mem:              7           0           6           0           0           6
Swap:             7           0           7

[root@dm8rac2 ~]# free -g
              total        used        free      shared  buff/cache   available
Mem:              7           0           6           0           0           6
Swap:             7           0           7

2.检查存储空间
1) DM完全安装需要1GB的存储空间,用户需要提前规划好安装目录,预留足够的存储空间。用户在DM安装前也应该为数据库实例预留足够的存储空间,规划好数据路径和备份路径。用户可使用以下命令检查存储空间:
#查询目录/dm8可用空间

[root@dm8rac1 ~]# mkdir /dm8
[root@dm8rac1 ~]# chown -R dmdba:dinstall /dm8
[root@dm8rac1 ~]# chmod -R 775 /dm8

[root@dm8rac2 ~]# mkdir /dm8
[root@dm8rac2 ~]# chown -R dmdba:dinstall /dm8
[root@dm8rac2 ~]# chmod -R 775 /dm8

[root@dm8rac1 ~]# df -h /dm8
Filesystem             Size  Used Avail Use% Mounted on
/dev/mapper/rhel-root   48G  5.6G   43G  12% /


[root@dm8rac2 ~]# df -h /dm8
Filesystem             Size  Used Avail Use% Mounted on
/dev/mapper/rhel-root   48G  5.6G   43G  12% /

2) DM安装程序在安装时将产生临时文件,临时文件需要1GB的存储空间,临时文件目录默认为/tmp。用户可以使用以下命令检查存储空间。
如下图所示:

[root@dm8rac1 ~]# df -h /tmp
Filesystem             Size  Used Avail Use% Mounted on
/dev/mapper/rhel-root   48G  5.6G   43G  12% /


[root@dm8rac2 ~]# df -h /tmp
Filesystem             Size  Used Avail Use% Mounted on
/dev/mapper/rhel-root   48G  5.6G   43G  12% /

3.5.安装DM
创建目录/soft/dmsoft用来存储挂载iso文件后来显示软件包中的文件

[root@dm8rac1 ~]# cd /soft
[root@dm8rac1 soft]# unzip dm8_20211021_x86_rh6_64_ent.zip
Archive:  dm8_20211021_x86_rh6_64_ent.zip
   creating: dm8_20211021_x86_rh6_64_ent/
  inflating: dm8_20211021_x86_rh6_64_ent/dm8_20211021_x86_rh6_64_ent_8.1.2.84.iso
 extracting: dm8_20211021_x86_rh6_64_ent/dm8_20211021_x86_rh6_64_ent_8.1.2.84.iso_SHA256.txt
 extracting: dm8_20211021_x86_rh6_64_ent/verinfo.txt
[root@dm8rac1 soft]# ls -lrt
total 778320
drwxr-xr-x. 2 root root       132 Nov 12 13:43 dm8_20211021_x86_rh6_64_ent
-rw-r--r--. 1 root root 796998047 Nov 29 10:25 dm8_20211021_x86_rh6_64_ent.zip
[root@dm8rac1 soft]# mv dm8_20211021_x86_rh6_64_ent dm8
[root@dm8rac1 soft]# ls -lrt
total 778320
drwxr-xr-x. 2 root root       132 Nov 12 13:43 dm8
-rw-r--r--. 1 root root 796998047 Nov 29 10:25 dm8_20211021_x86_rh6_64_ent.zip

[root@dm8rac1 soft]# mkdir dmsoft
[root@dm8rac1 soft]# mount -t iso9660 -o loop dm8/dm8_20211021_x86_rh6_64_ent_8.1.2.84.iso  /soft/dmsoft
mount: /dev/loop0 is write-protected, mounting read-only

[root@dm8rac1 soft]# cd dmsoft
[root@dm8rac1 dmsoft]# ls -lrt
total 790160
-r-xr-xr-x. 1 root root   2802503 Oct 21 14:04 DM8 Install.pdf
-r-xr-xr-x. 1 root root 806320703 Oct 21 14:11 DMInstall.bin


[root@dm8rac12 ~]# cd /soft
[root@dm8rac2 soft]# unzip dm8_20211021_x86_rh6_64_ent.zip
Archive:  dm8_20211021_x86_rh6_64_ent.zip
   creating: dm8_20211021_x86_rh6_64_ent/
  inflating: dm8_20211021_x86_rh6_64_ent/dm8_20211021_x86_rh6_64_ent_8.1.2.84.iso
 extracting: dm8_20211021_x86_rh6_64_ent/dm8_20211021_x86_rh6_64_ent_8.1.2.84.iso_SHA256.txt
 extracting: dm8_20211021_x86_rh6_64_ent/verinfo.txt
[root@dm8rac2 soft]# ls -lrt
total 778320
drwxr-xr-x. 2 root root       132 Nov 12 13:43 dm8_20211021_x86_rh6_64_ent
-rw-r--r--. 1 root root 796998047 Nov 29 10:25 dm8_20211021_x86_rh6_64_ent.zip
[root@dm8rac2 soft]# mv dm8_20211021_x86_rh6_64_ent dm8
[root@dm8rac2 soft]# ls -lrt
total 778320
drwxr-xr-x. 2 root root       132 Nov 12 13:43 dm8
-rw-r--r--. 1 root root 796998047 Nov 29 10:25 dm8_20211021_x86_rh6_64_ent.zip

[root@dm8rac2 soft]# mkdir dmsoft
[root@dm8rac2 soft]# mount -t iso9660 -o loop dm8/dm8_20211021_x86_rh6_64_ent_8.1.2.84.iso  /soft/dmsoft
mount: /dev/loop0 is write-protected, mounting read-only

[root@dm8rac2 soft]# cd dmsoft
[root@dm8rac2 dmsoft]# ls -lrt
total 790160
-r-xr-xr-x. 1 root root   2802503 Oct 21 14:04 DM8 Install.pdf
-r-xr-xr-x. 1 root root 806320703 Oct 21 14:11 DMInstall.bin

在/soft/dmsoft目录下存在DMInstall.bin文件, DMInstall.bin文件就是DM的安装程序。在运行安装程序前,需要赋予DMInstall.bin文件执行权限。具体命令如下所示:

[root@dm8rac1 dmsoft]# chmod 755  DMInstall.bin
chmod: changing permissions of ‘DMInstall.bin’: Read-only file system


[root@dm8rac2 dmsoft]# chmod 755  DMInstall.bin
chmod: changing permissions of ‘DMInstall.bin’: Read-only file system

在现实中,许多Linux(Unix)操作系统上是没有图形化界面的,为了使DM能够在这些操作系统上顺利安装,DM提供了命令行的安装方式。在终端进入到安装程序所在文件夹,执行以下命令进行命令行安装:

[dmdba@dm8rac1 dmsoft]$ ./DMInstall.bin -i
Please select the installer's language (E/e:English C/c:Chinese) [E/e]:e
Extract install files.........
Welcome to DM DBMS Installer

Whether to input the path of Key File? (Y/y:Yes N/n:No) [Y/y]:n

Whether to Set The TimeZone? (Y/y:Yes N/n:No) [Y/y]:y
TimeZone:
[ 1]: GTM-12=West Date Line
[ 2]: GTM-11=Samoa
[ 3]: GTM-10=Hawaii
[ 4]: GTM-09=Alaska
[ 5]: GTM-08=Pacific(America and Canada)
[ 6]: GTM-07=Arizona
[ 7]: GTM-06=Central(America and Canada)
[ 8]: GTM-05=East(America and Canada)
[ 9]: GTM-04=Atlantic(America and Canada)
[10]: GTM-03=Brasilia
[11]: GTM-02=Middle Atlantic
[12]: GTM-01=Azores
[13]: GTM=Greenwich Mean Time
[14]: GTM+01=Sarajevo
[15]: GTM+02=Cairo
[16]: GTM+03=Moscow
[17]: GTM+04=AbuDhabi
[18]: GTM+05=Islamabad
[19]: GTM+06=Dakar
[20]: GTM+07=BangKok,Hanoi
[21]: GTM+08=China
[22]: GTM+09=Seoul
[23]: GTM+10=Guam
[24]: GTM+11=Solomon
[25]: GTM+12=Fiji
[26]: GTM+13=Nukualofa
[27]: GTM+14=Kiribati
Please Select the TimeZone [21]:21

Installation Type:
1 Typical
2 Server
3 Client
4 Custom
Please Input the number of the Installation Type [1 Typical]:4
1 Server component
2 Client component
  2.1 Manager
  2.2 Monitor
  2.3 DTS
  2.4 Console
  2.5 Analyzer
  2.6 DISQL
3 DM Drivers
4 Manual component
5 DBMS Service
  5.1 Realtime Audit Service
  5.2 Job Service
  5.3 Instance Monitor Service
  5.4 Assistant Plug-In Service
Please Input the number of the Installation Type [1 2 3 4 5]:1 2 3 4 5
Require Space: 1242M

Please Input the install path [/home/dmdba/dmdbms]:/dm8
Available Space:39G
Please Confirm the install path(/dm8)? (Y/y:Yes N/n:No) [Y/y]:y

Pre-Installation Summary
Installation Location: /dm8
Require Space: 1242M
Available Space: 39G
Version Information:
Expire Date:
Installation Type: Custom
Confirm to Install? (Y/y:Yes N/n:No):y
2021-12-07 10:57:53
[INFO] Installing DM DBMS...
2021-12-07 10:57:54
[INFO] Installing BASE Module...
2021-12-07 10:57:56
[INFO] Installing SERVER Module...
2021-12-07 10:57:56
[INFO] Installing CLIENT Module...
2021-12-07 10:57:57
[INFO] Installing DRIVERS Module...
2021-12-07 10:57:57
[INFO] Installing MANUAL Module...
2021-12-07 10:57:57
[INFO] Installing SERVICE Module...
2021-12-07 10:58:03
[INFO] Move log file to log directory.
2021-12-07 10:58:05
[INFO] Installed DM DBMS completely.

Please execute the commands by root:
/dm8/script/root/root_installer.sh

End

以root用户来执行上面的脚本

[root@dm8rac1 ~]# /dm8/script/root/root_installer.sh
Move /dm8/bin/dm_svc.conf to /etc
Modify the files' mode of DM Server


[dmdba@dm8rac2 dmsoft]$ ./DMInstall.bin -i
Please select the installer's language (E/e:English C/c:Chinese) [E/e]:e
Extract install files.........
Welcome to DM DBMS Installer

Whether to input the path of Key File? (Y/y:Yes N/n:No) [Y/y]:n

Whether to Set The TimeZone? (Y/y:Yes N/n:No) [Y/y]:y
TimeZone:
[ 1]: GTM-12=West Date Line
[ 2]: GTM-11=Samoa
[ 3]: GTM-10=Hawaii
[ 4]: GTM-09=Alaska
[ 5]: GTM-08=Pacific(America and Canada)
[ 6]: GTM-07=Arizona
[ 7]: GTM-06=Central(America and Canada)
[ 8]: GTM-05=East(America and Canada)
[ 9]: GTM-04=Atlantic(America and Canada)
[10]: GTM-03=Brasilia
[11]: GTM-02=Middle Atlantic
[12]: GTM-01=Azores
[13]: GTM=Greenwich Mean Time
[14]: GTM+01=Sarajevo
[15]: GTM+02=Cairo
[16]: GTM+03=Moscow
[17]: GTM+04=AbuDhabi
[18]: GTM+05=Islamabad
[19]: GTM+06=Dakar
[20]: GTM+07=BangKok,Hanoi
[21]: GTM+08=China
[22]: GTM+09=Seoul
[23]: GTM+10=Guam
[24]: GTM+11=Solomon
[25]: GTM+12=Fiji
[26]: GTM+13=Nukualofa
[27]: GTM+14=Kiribati
Please Select the TimeZone [21]:21

Installation Type:
1 Typical
2 Server
3 Client
4 Custom
Please Input the number of the Installation Type [1 Typical]:4
1 Server component
2 Client component
  2.1 Manager
  2.2 Monitor
  2.3 DTS
  2.4 Console
  2.5 Analyzer
  2.6 DISQL
3 DM Drivers
4 Manual component
5 DBMS Service
  5.1 Realtime Audit Service
  5.2 Job Service
  5.3 Instance Monitor Service
  5.4 Assistant Plug-In Service
Please Input the number of the Installation Type [1 2 3 4 5]:1 2 3 4 5
Require Space: 1242M

Please Input the install path [/home/dmdba/dmdbms]:/dm8
Available Space:39G
Please Confirm the install path(/dm8)? (Y/y:Yes N/n:No) [Y/y]:y

Pre-Installation Summary
Installation Location: /dm8
Require Space: 1242M
Available Space: 39G
Version Information:
Expire Date:
Installation Type: Custom
Confirm to Install? (Y/y:Yes N/n:No):y
2021-12-07 10:57:53
[INFO] Installing DM DBMS...
2021-12-07 10:57:54
[INFO] Installing BASE Module...
2021-12-07 10:57:56
[INFO] Installing SERVER Module...
2021-12-07 10:57:56
[INFO] Installing CLIENT Module...
2021-12-07 10:57:57
[INFO] Installing DRIVERS Module...
2021-12-07 10:57:57
[INFO] Installing MANUAL Module...
2021-12-07 10:57:57
[INFO] Installing SERVICE Module...
2021-12-07 10:58:03
[INFO] Move log file to log directory.
2021-12-07 10:58:05
[INFO] Installed DM DBMS completely.

Please execute the commands by root:
/dm8/script/root/root_installer.sh

End

以root用户来执行上面的脚本

[root@dm8rac2 ~]# /dm8/script/root/root_installer.sh
Move /dm8/bin/dm_svc.conf to /etc
Modify the files' mode of DM Server

四、绑定UDEV

ACTION=="add", KERNEL=="sdb", RUN+="/bin/raw /dev/raw/raw1 %N"
ACTION=="add", KERNEL=="sdc", RUN+="/bin/raw /dev/raw/raw2 %N"
ACTION=="add", KERNEL=="sdd", RUN+="/bin/raw /dev/raw/raw3 %N"
ACTION=="add", KERNEL=="sde", RUN+="/bin/raw /dev/raw/raw4 %N"
ACTION=="add", KERNEL=="sdf", RUN+="/bin/raw /dev/raw/raw5 %N"
ACTION=="add", KERNEL=="sdg", RUN+="/bin/raw /dev/raw/raw6 %N"

ACTION=="add", KERNEL=="raw[1-6]", OWNER="dmdba", GROUP="dinstall", MODE="660"

[root@dm8rac1 rules.d]# /sbin/udevadm trigger --type=devices --action=change

[root@dm8rac2 rules.d]# /sbin/udevadm trigger --type=devices --action=change

如果不能正常显示就重启操作系统

[root@dm8rac1 ~]# ls -lrt /dev/raw
total 0
crw-rw---- 1 root  disk     162, 0 Dec  7 14:59 rawctl
crw-rw---- 1 dmdba dinstall 162, 5 Dec  7 14:59 raw5
crw-rw---- 1 dmdba dinstall 162, 6 Dec  7 14:59 raw6
crw-rw---- 1 dmdba dinstall 162, 4 Dec  7 14:59 raw4
crw-rw---- 1 dmdba dinstall 162, 3 Dec  7 14:59 raw3
crw-rw---- 1 dmdba dinstall 162, 2 Dec  7 14:59 raw2
crw-rw---- 1 dmdba dinstall 162, 1 Dec  7 14:59 raw1

[root@dm8rac2 ~]# ls -lrt /dev/raw
total 0
crw-rw---- 1 root  disk     162, 0 Dec  7 14:59 rawctl
crw-rw---- 1 dmdba dinstall 162, 5 Dec  7 14:59 raw5
crw-rw---- 1 dmdba dinstall 162, 6 Dec  7 14:59 raw6
crw-rw---- 1 dmdba dinstall 162, 4 Dec  7 14:59 raw4
crw-rw---- 1 dmdba dinstall 162, 3 Dec  7 14:59 raw3
crw-rw---- 1 dmdba dinstall 162, 2 Dec  7 14:59 raw2
crw-rw---- 1 dmdba dinstall 162, 1 Dec  7 14:59 raw1

可以通过blockdev –getsize64 /dev/raw/raw1命令查看裸设备大小

[root@dm8rac1 ~]# blockdev --getsize64 /dev/raw/raw1
2147483648
[root@dm8rac1 ~]# blockdev --getsize64 /dev/raw/raw2
2147483648
[root@dm8rac1 ~]# blockdev --getsize64 /dev/raw/raw3
10737418240
[root@dm8rac1 ~]# blockdev --getsize64 /dev/raw/raw4
10737418240
[root@dm8rac1 ~]# blockdev --getsize64 /dev/raw/raw5
10737418240
[root@dm8rac1 ~]# blockdev --getsize64 /dev/raw/raw6
10737418240


[root@dm8rac2 ~]# blockdev --getsize64 /dev/raw/raw1
2147483648
[root@dm8rac2 ~]# blockdev --getsize64 /dev/raw/raw2
2147483648
[root@dm8rac3 ~]# blockdev --getsize64 /dev/raw/raw3
10737418240
[root@dm8rac4 ~]# blockdev --getsize64 /dev/raw/raw4
10737418240
[root@dm8rac5 ~]# blockdev --getsize64 /dev/raw/raw5
10737418240
[root@dm8rac6 ~]# blockdev --getsize64 /dev/raw/raw6
10737418240

五.配置dmdcr_cfg.ini文件
在2个节点的/dm8/data目录下创建配置文件dmdcr_cfg.ini,在文件中添加如下内容:

[root@dm8rac1 ~]# su - dmdba
Last login: Tue Dec  7 10:58:27 CST 2021 on pts/0
[dmdba@dm8rac1 ~]$ mkdir /dm8/data

[root@dm8rac2 ~]# su - dmdba
Last login: Tue Dec  7 10:58:27 CST 2021 on pts/0
[dmdba@dm8rac2 ~]$ mkdir /dm8/data


[dmdba@dm8rac1 ~]$ cd /dm8/data
[dmdba@dm8rac1 data]$ vi dmdcr_cfg.ini
DCR_N_GRP = 3
DCR_VTD_PATH = /dev/raw/raw2
DCR_OGUID = 63635

[GRP]
DCR_GRP_TYPE = CSS
DCR_GRP_NAME = GRP_CSS
DCR_GRP_N_EP = 2
DCR_GRP_DSKCHK_CNT = 60
[GRP_CSS]
DCR_EP_NAME = CSS0
DCR_EP_HOST = 11.11.11.1
DCR_EP_PORT = 9541
[GRP_CSS]
DCR_EP_NAME = CSS1
DCR_EP_HOST = 11.11.11.2
DCR_EP_PORT = 9541

[GRP]
DCR_GRP_TYPE = ASM
DCR_GRP_NAME = GRP_ASM
DCR_GRP_N_EP = 2
DCR_GRP_DSKCHK_CNT = 60
[GRP_ASM]
DCR_EP_NAME = ASM0
DCR_EP_SHM_KEY = 93360
DCR_EP_SHM_SIZE = 10
DCR_EP_HOST = 10.10.10.201
DCR_EP_PORT = 9641
DCR_EP_ASM_LOAD_PATH = /dev/raw
[GRP_ASM]
DCR_EP_NAME = ASM1
DCR_EP_SHM_KEY = 93361
DCR_EP_SHM_SIZE = 10
DCR_EP_HOST = 10.10.10.202
DCR_EP_PORT = 9641
DCR_EP_ASM_LOAD_PATH = /dev/raw

[GRP]
DCR_GRP_TYPE = DB
DCR_GRP_NAME = GRP_RAC
DCR_GRP_N_EP = 2
DCR_GRP_DSKCHK_CNT = 60
[GRP_RAC]
DCR_EP_NAME = RAC0
DCR_EP_SEQNO = 0
DCR_EP_PORT = 5236
DCR_CHECK_PORT = 9741
[GRP_RAC]
DCR_EP_NAME = RAC1
DCR_EP_SEQNO = 1
DCR_EP_PORT = 5236
DCR_CHECK_PORT = 9741


[dmdba@dm8rac2 ~]$ cd /dm8/data
[dmdba@dm8rac2 data]$ vi dmdcr_cfg.ini
DCR_N_GRP = 3
DCR_VTD_PATH = /dev/raw/raw2
DCR_OGUID = 63635

[GRP]
DCR_GRP_TYPE = CSS
DCR_GRP_NAME = GRP_CSS
DCR_GRP_N_EP = 2
DCR_GRP_DSKCHK_CNT = 60
[GRP_CSS]
DCR_EP_NAME = CSS0
DCR_EP_HOST = 11.11.11.1
DCR_EP_PORT = 9541
[GRP_CSS]
DCR_EP_NAME = CSS1
DCR_EP_HOST = 11.11.11.2
DCR_EP_PORT = 9541

[GRP]
DCR_GRP_TYPE = ASM
DCR_GRP_NAME = GRP_ASM
DCR_GRP_N_EP = 2
DCR_GRP_DSKCHK_CNT = 60
[GRP_ASM]
DCR_EP_NAME = ASM0
DCR_EP_SHM_KEY = 93360
DCR_EP_SHM_SIZE = 10
DCR_EP_HOST = 10.10.10.201
DCR_EP_PORT = 9641
DCR_EP_ASM_LOAD_PATH = /dev/raw
[GRP_ASM]
DCR_EP_NAME = ASM1
DCR_EP_SHM_KEY = 93361
DCR_EP_SHM_SIZE = 10
DCR_EP_HOST = 10.10.10.202
DCR_EP_PORT = 9641
DCR_EP_ASM_LOAD_PATH = /dev/raw

[GRP]
DCR_GRP_TYPE = DB
DCR_GRP_NAME = GRP_RAC
DCR_GRP_N_EP = 2
DCR_GRP_DSKCHK_CNT = 60
[GRP_RAC]
DCR_EP_NAME = RAC0
DCR_EP_SEQNO = 0
DCR_EP_PORT = 5236
DCR_CHECK_PORT = 9741
[GRP_RAC]
DCR_EP_NAME = RAC1
DCR_EP_SEQNO = 1
DCR_EP_PORT = 5236
DCR_CHECK_PORT = 9741

六.使用 DMASMCMD 工具初始化(任意一节点执行)

[dmdba@dm8rac1 ~]$ dmasmcmd
DMASMCMD V8
ASM>create dcrdisk '/dev/raw/raw1' 'dcr'
[Trace]The ASM initialize dcrdisk /dev/raw/raw1 to name DMASMdcr
Used time: 202.727(ms).
ASM>create votedisk '/dev/raw/raw2' 'vote'
[Trace]The ASM initialize votedisk /dev/raw/raw2 to name DMASMvote
Used time: 184.178(ms).
ASM>create asmdisk '/dev/raw/raw3' 'LOG0'
[Trace]The ASM initialize asmdisk /dev/raw/raw3 to name DMASMLOG0
Used time: 105.666(ms).
ASM>create asmdisk '/dev/raw/raw4' 'DATA0'
[Trace]The ASM initialize asmdisk /dev/raw/raw4 to name DMASMDATA0
Used time: 116.970(ms).
ASM>create asmdisk '/dev/raw/raw5' 'LOG1'
[Trace]The ASM initialize asmdisk /dev/raw/raw5 to name DMASMLOG1
Used time: 174.756(ms).
ASM>create asmdisk '/dev/raw/raw6' 'DATA1'
[Trace]The ASM initialize asmdisk /dev/raw/raw6 to name DMASMDATA1
Used time: 132.282(ms).
ASM>init dcrdisk '/dev/raw/raw1' from '/dm8/data/dmdcr_cfg.ini' identified by 'dameng123'
[Trace]DG 126 alloc one extent for inodes, addr(disk_id, disk_auno, extent_no):(0,0,1).
[Trace]DG 126 allocate 4 extents for file 0xfe000002.
[Trace]DG 126 alloc 4 extents for 0xfe000002, addr(disk_id, disk_auno, extent_no):(0, 0, 2)->(0, 0, 5), need_init = 1.
Used time: 00:00:02.397.
ASM>init votedisk '/dev/raw/raw2' from '/dm8/data/dmdcr_cfg.ini'
[Trace]DG 125 alloc one extent for inodes, addr(disk_id, disk_auno, extent_no):(0,0,1).
[Trace]DG 125 allocate 4 extents for file 0xfd000002.
[Trace]DG 125 alloc 4 extents for 0xfd000002, addr(disk_id, disk_auno, extent_no):(0, 0, 2)->(0, 0, 5), need_init = 1.
Used time: 550.896(ms).

七.准备DMASM 的 MAL 配置文件
在2个节点的/dm8/data目录下创建 DMASM 的 MAL 配置文件(命名为 dmasvrmal.ini),使用 DMASM 的所有节点都要配置,内容完全一样。

[dmdba@dm8rac1 data]$ vi dmasvrmal.ini
[MAL_INST1]
MAL_INST_NAME = ASM0
MAL_HOST = 11.11.11.1
MAL_PORT = 7236

[MAL_INST2]
MAL_INST_NAME = ASM1
MAL_HOST = 11.11.11.2
MAL_PORT = 7236


[dmdba@dm8rac2 data]$ vi dmasvrmal.ini
[MAL_INST1]
MAL_INST_NAME = ASM0
MAL_HOST = 11.11.11.1
MAL_PORT = 7236

[MAL_INST2]
MAL_INST_NAME = ASM1
MAL_HOST = 11.11.11.2
MAL_PORT = 7236

八.准备dmdcr.ini 配置文件
dmdcr.ini 是 dmcss、dmasmsvr、dmasmtool 工具的输入参数。记录了当前节点序列号以及 DCR 磁盘路径。在2个节点的/dm/dmdbms/data目录下创建dmdcr.ini 配置文件,dmdcr_path 相同,dmasvrmal.ini 文件内容也相同,dmdcr_seqo 分别为 0 和 1。
节点 1:

[dmdba@dm8rac1 data]$ vi dmdcr.ini
DMDCR_PATH = /dev/raw/raw1
DMDCR_MAL_PATH =/dm8/data/dmasvrmal.ini
DMDCR_SEQNO = 0

#ASM
DMDCR_ASM_RESTART_INTERVAL = 0
DMDCR_ASM_STARTUP_CMD = /dm8/bin/dmasmsvr dcr_ini=/dm8/data/dmdcr.ini

#DB
DMDCR_DB_RESTART_INTERVAL = 0
DMDCR_DB_STARTUP_CMD = /dm8/bin/dmserver path=/dm8/data/rac0_config/dm.ini dcr_ini=/dm8/data/dmdcr.ini



节点2:

[dmdba@dm8rac2 data]$ vi dmdcr.ini
DMDCR_PATH = /dev/raw/raw1
DMDCR_MAL_PATH =/dm8/data/dmasvrmal.ini
DMDCR_SEQNO = 1

#ASM
DMDCR_ASM_RESTART_INTERVAL = 0
DMDCR_ASM_STARTUP_CMD = /dm8/bin/dmasmsvr dcr_ini=/dm8/data/dmdcr.ini

#DB
DMDCR_DB_RESTART_INTERVAL = 0
DMDCR_DB_STARTUP_CMD = /dm8/bin/dmserver path=/dm8/data/rac1_config/dm.ini dcr_ini=/dm8/data/dmdcr.ini

九.启动DMCSS、DMASM 服务程序
1、注册 DMCSS和DMASM服务
节点一:

[root@dm8rac1 ~]# /dm8/script/root/dm_service_installer.sh -t dmcss -dcr_ini /dm8/data/dmdcr.ini -p rac1
Created symlink from /etc/systemd/system/multi-user.target.wants/DmCSSServicerac1.service to /usr/lib/systemd/system/DmCSSServicerac1.service.
Finished to create the service (DmCSSServicerac1)

[root@dm8rac1 ~]# /dm8/script/root/dm_service_installer.sh -t dmasmsvr -dcr_ini /dm8/data/dmdcr.ini -p rac1 -y DmCSSServicerac1
Created symlink from /etc/systemd/system/multi-user.target.wants/DmASMSvrServicerac1.service to /usr/lib/systemd/system/DmASMSvrServicerac1.service.
Finished to create the service (DmASMSvrServicerac1)

节点二:

[root@dm8rac2 ~]# /dm8/script/root/dm_service_installer.sh -t dmcss -dcr_ini /dm8/data/dmdcr.ini -p rac2
Created symlink from /etc/systemd/system/multi-user.target.wants/DmCSSServicerac2.service to /usr/lib/systemd/system/DmCSSServicerac2.service.
Finished to create the service (DmCSSServicerac2)
[root@dm8rac2 ~]# /dm8/script/root/dm_service_installer.sh -t dmasmsvr -dcr_ini /dm8/data/dmdcr.ini -p rac2 -y DmCSSServicerac2
Created symlink from /etc/systemd/system/multi-user.target.wants/DmASMSvrServicerac2.service to /usr/lib/systemd/system/DmASMSvrServicerac2.service.
Finished to create the service (DmASMSvrServicerac2)

2、启动DMCSS和DMASM服务
节点一

[root@dm8rac1 ~]# service DmCSSServicerac1 start
Redirecting to /bin/systemctl start DmCSSServicerac1.service
[root@dm8rac1 ~]# service DmASMSvrServicerac1 start
Redirecting to /bin/systemctl start DmASMSvrServicerac1.service
[root@dm8rac1 ~]# service DmCSSServicerac1 status
Redirecting to /bin/systemctl status DmCSSServicerac1.service
  DmCSSServicerac1.service - DM Cluster Synchronization Services Service(DmCSSServicerac1).
   Loaded: loaded (/usr/lib/systemd/system/DmCSSServicerac1.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2021-12-08 09:50:18 CST; 51s ago
  Process: 14654 ExecStart=/dm8/bin/DmCSSServicerac1 start (code=exited, status=0/SUCCESS)
 Main PID: 14682 (dmcss)
    Tasks: 10
   CGroup: /system.slice/DmCSSServicerac1.service
           └─14682 /dm8/bin/dmcss dcr_ini=/dm8/data/dmdcr.ini

Dec 08 09:50:03 dm8rac1 systemd[1]: Starting DM Cluster Synchronization Services Service(DmCSSServicerac1)....
Dec 08 09:50:18 dm8rac1 DmCSSServicerac1[14654]: [38B blob data]
Dec 08 09:50:18 dm8rac1 systemd[1]: Started DM Cluster Synchronization Services Service(DmCSSServicerac1)..
[root@dm8rac1 ~]# service DmASMSvrServicerac1 status
Redirecting to /bin/systemctl status DmASMSvrServicerac1.service
  DmASMSvrServicerac1.service - DM Auto Storage Manager Service(DmASMSvrServicerac1).
   Loaded: loaded (/usr/lib/systemd/system/DmASMSvrServicerac1.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2021-12-08 09:50:58 CST; 31s ago
  Process: 14729 ExecStart=/dm8/bin/DmASMSvrServicerac1 start (code=exited, status=0/SUCCESS)
 Main PID: 14755 (dmasmsvr)
    Tasks: 10
   CGroup: /system.slice/DmASMSvrServicerac1.service
           └─14755 /dm8/bin/dmasmsvr dcr_ini=/dm8/data/dmdcr.ini

Dec 08 09:50:43 dm8rac1 systemd[1]: Starting DM Auto Storage Manager Service(DmASMSvrServicerac1)....
Dec 08 09:50:58 dm8rac1 DmASMSvrServicerac1[14729]: [41B blob data]
Dec 08 09:50:58 dm8rac1 systemd[1]: Started DM Auto Storage Manager Service(DmASMSvrServicerac1)..

节点二:

[root@dm8rac2 ~]# service DmCSSServicerac2 start
Redirecting to /bin/systemctl start DmCSSServicerac2.service
[root@dm8rac2 ~]# service DmASMSvrServicerac2 start
Redirecting to /bin/systemctl start DmASMSvrServicerac2.service
[root@dm8rac2 ~]# service DmCSSServicerac2 status
Redirecting to /bin/systemctl status DmCSSServicerac2.service
  DmCSSServicerac2.service - DM Cluster Synchronization Services Service(DmCSSServicerac2).
   Loaded: loaded (/usr/lib/systemd/system/DmCSSServicerac2.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2021-12-08 09:52:00 CST; 1min 54s ago
  Process: 14424 ExecStart=/dm8/bin/DmCSSServicerac2 start (code=exited, status=0/SUCCESS)
 Main PID: 14452 (dmcss)
    Tasks: 10
   CGroup: /system.slice/DmCSSServicerac2.service
           └─14452 /dm8/bin/dmcss dcr_ini=/dm8/data/dmdcr.ini

Dec 08 09:51:45 dm8rac2 systemd[1]: Starting DM Cluster Synchronization Services Service(DmCSSServicerac2)....
Dec 08 09:52:00 dm8rac2 DmCSSServicerac2[14424]: [38B blob data]
Dec 08 09:52:00 dm8rac2 systemd[1]: Started DM Cluster Synchronization Services Service(DmCSSServicerac2)..
[root@dm8rac2 ~]# service DmASMSvrServicerac2 status
Redirecting to /bin/systemctl status DmASMSvrServicerac2.service
   DmASMSvrServicerac2.service - DM Auto Storage Manager Service(DmASMSvrServicerac2).
   Loaded: loaded (/usr/lib/systemd/system/DmASMSvrServicerac2.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2021-12-08 09:52:58 CST; 1min 16s ago
  Process: 14499 ExecStart=/dm8/bin/DmASMSvrServicerac2 start (code=exited, status=0/SUCCESS)
 Main PID: 14525 (dmasmsvr)
    Tasks: 15
   CGroup: /system.slice/DmASMSvrServicerac2.service
           └─14525 /dm8/bin/dmasmsvr dcr_ini=/dm8/data/dmdcr.ini

Dec 08 09:52:43 dm8rac2 systemd[1]: Starting DM Auto Storage Manager Service(DmASMSvrServicerac2)....
Dec 08 09:52:58 dm8rac2 DmASMSvrServicerac2[14499]: [41B blob data]
Dec 08 09:52:58 dm8rac2 systemd[1]: Started DM Auto Storage Manager Service(DmASMSvrServicerac2)..

十、创建DMASM磁盘组
在任意节点使用 dmasmtool 工具创建 DMASM 磁盘组。

[dmdba@dm8rac1 ~]$ dmasmtool DCR_INI=/dm8/data/dmdcr.ini
DMASMTOOL V8
ASM>create diskgroup 'DMLOG' asmdisk '/dev/raw/raw3'
Used time: 358.430(ms).
ASM>create diskgroup 'DMDATA' asmdisk '/dev/raw/raw4'
Used time: 330.223(ms).

十一、准备dminit.ini 配置文件
在2个节点的/dm8/data目录下创建 dminit.ini 配置文件,添加如下内容。 在2个节点都创建。

[dmdba@dm8rac1 data]$ vi dminit.ini
db_name = rac
system_path = +DMDATA/data
system = +DMDATA/data/rac/system.dbf
system_size = 128
roll = +DMDATA/data/rac/roll.dbf
roll_size = 128
main = +DMDATA/data/rac/main.dbf
main_size = 128
ctl_path = +DMDATA/data/rac/dm.ctl
ctl_size = 8
log_size = 256
dcr_path = /dev/raw/raw1 #dcr 磁盘路径,目前不支持 asm,只能是裸设备
dcr_seqno = 0
auto_overwrite = 1

[RAC0] #inst_name 跟 dmdcr_cfg.ini 中 DB 类型 group 中 DCR_EP_NAME 对应
config_path = /dm8/data/rac0_config
port_num = 5236
mal_host = 11.11.11.1
mal_port = 9340
log_path = +DMLOG/log/rac0_log01.log
log_path = +DMLOG/log/rac0_log02.log

[RAC1] #inst_name 跟 dmdcr_cfg.ini 中 DB 类型 group 中 DCR_EP_NAME 对应
config_path = /dm8/data/rac1_config
port_num = 5236
mal_host = 11.11.11.2
mal_port = 9340
log_path = +DMLOG/log/rac1_log01.log
log_path = +DMLOG/log/rac1_log02.log


[dmdba@dm8rac2 data]$ vi dminit.ini
db_name = rac
system_path = +DMDATA/data
system = +DMDATA/data/rac/system.dbf
system_size = 128
roll = +DMDATA/data/rac/roll.dbf
roll_size = 128
main = +DMDATA/data/rac/main.dbf
main_size = 128
ctl_path = +DMDATA/data/rac/dm.ctl
ctl_size = 8
log_size = 256
dcr_path = /dev/raw/raw1 #dcr 磁盘路径,目前不支持 asm,只能是裸设备
dcr_seqno = 0
auto_overwrite = 1

[RAC0] #inst_name 跟 dmdcr_cfg.ini 中 DB 类型 group 中 DCR_EP_NAME 对应
config_path = /dm8/data/rac0_config
port_num = 5236
mal_host = 11.11.11.1
mal_port = 9340
log_path = +DMLOG/log/rac0_log01.log
log_path = +DMLOG/log/rac0_log02.log

[RAC1] #inst_name 跟 dmdcr_cfg.ini 中 DB 类型 group 中 DCR_EP_NAME 对应
config_path = /dm8/data/rac1_config
port_num = 5236
mal_host = 11.11.11.2
mal_port = 9340
log_path = +DMLOG/log/rac1_log01.log
log_path = +DMLOG/log/rac1_log02.log

十二、使用dminit初始化数据库
在任意节点启动 dminit 工具初始化数据库。dminit 执行完成后,会在 config_path 目录(/dm8/data/rac0_config 和/dm8/data/rac1_config)下生成配置文件 dm.ini 和 dmmal.ini。

[dmdba@dm8rac1 ~]$ dminit control=/dm8/data/dminit.ini
initdb V8
db version: 0x7000c
file dm.key not found, use default license!
License will expire on 2022-10-21
Normal of FAST
Normal of DEFAULT
Normal of RECYCLE
Normal of KEEP
Normal of ROLL

 log file path: +DMLOG/log/rac0_log01.log


 log file path: +DMLOG/log/rac0_log02.log


 log file path: +DMLOG/log/rac1_log01.log


 log file path: +DMLOG/log/rac1_log02.log

write to dir [+DMDATA/data/rac].
create dm database success. 2021-12-08 10:17:36

将节点一上的/dm8/data/rac1_config的配置目录复制到节点二:

[dmdba@dm8rac1 data]$ scp -r rac1_config 10.10.10.202:`pwd`
The authenticity of host '10.10.10.202 (10.10.10.202)' can't be established.
ECDSA key fingerprint is SHA256:6O8c9WEeEYPbL4ncdRR1RsrjxxmfzPq9Tkq4/6uLSP4.
ECDSA key fingerprint is MD5:e1:73:3e:8d:79:be:5c:82:0f:c7:58:79:45:ad:df:86.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '10.10.10.202' (ECDSA) to the list of known hosts.
dmdba@10.10.10.202's password:
dmmal.ini                                                                                                                                                                                                100%  200    18.1KB/s   00:00
dm.ini                                                                                                                                                                                                   100%   53KB   2.0MB/s   00:00
sqllog.ini                                                                                                                                                                                               100%  481    79.8KB/s   00:00
[dmdba@dm8rac1 data]$

十三、启动数据库服务器
1、在2个节点分别注册DM 数据库服务:
节点一:

[root@dm8rac1 ~]# /dm8/script/root/dm_service_installer.sh -t dmserver -dm_ini /dm8/data/rac0_config/dm.ini -dcr_ini /dm8/data/dmdcr.ini -p rac1 -y DmASMSvrServicerac1
Created symlink from /etc/systemd/system/multi-user.target.wants/DmServicerac1.service to /usr/lib/systemd/system/DmServicerac1.service.
Finished to create the service (DmServicerac1)

节点二:

[root@dm8rac2 ~]# /dm8/script/root/dm_service_installer.sh -t dmserver -dm_ini /dm8/data/rac1_config/dm.ini -dcr_ini /dm8/data/dmdcr.ini -p rac2 -y DmASMSvrServicerac2
Created symlink from /etc/systemd/system/multi-user.target.wants/DmServicerac2.service to /usr/lib/systemd/system/DmServicerac2.service.
Finished to create the service (DmServicerac2)

2、启动数据库

[root@dm8rac1 ~]# service DmServicerac1 start
Redirecting to /bin/systemctl start DmServicerac1.service

[root@dm8rac2 ~]# service DmServicerac2 start
Redirecting to /bin/systemctl start DmServicerac2.service

手工启动命令如下,手工启动后窗口不能关闭,所以配置成服务。

./dmserver /dm8/data/rac0_config/dm.ini dcr_ini=/dm8/data/dmdcr.ini
./dmserver /dm8/data/rac1_config/dm.ini dcr_ini=/dm8/data/dmdcr.ini

十四.连接数据库验证
1.配置服务名文件

[dmdba@dm8rac1 ~]$ vi /etc/dm_svc.conf
TIME_ZONE=(480)
LANGUAGE=(en)
rac=(10.10.10.201:5236,10.10.10.202:5236)
SWITCH_TIME=(10000)
SWITCH_INTERVAL=(10)

[dmdba@dm8rac2 ~]$ vi /etc/dm_svc.conf
TIME_ZONE=(480)
LANGUAGE=(en)
rac=(10.10.10.201:5236,10.10.10.202:5236)
SWITCH_TIME=(10000)
SWITCH_INTERVAL=(10)

2.连接RAC集群
节点一:

[dmdba@dm8rac1 ~]$ disql SYSDBA/SYSDBA@rac

Server[10.10.10.202:5236]:mode is normal, state is open
login used time : 4.611(ms)
disql V8
SQL> select instance_name from v$instance;

LINEID     INSTANCE_NAME
---------- -------------
1          RAC1

used time: 13.949(ms). Execute id is 100.

SQL> select * from v$dsc_ep_info;

LINEID     EP_NAME EP_SEQNO    EP_GUID              EP_TIMESTAMP         EP_MODE      EP_STATUS
---------- ------- ----------- -------------------- -------------------- ------------ ---------
1          RAC0    0           2383210041           2383210694           Control Node OK
2          RAC1    1           2383231629           2383232261           Normal Node  OK

used time: 3.176(ms). Execute id is 101.

节点二:

[dmdba@dm8rac2 ~]$ disql SYSDBA/SYSDBA@rac

Server[10.10.10.201:5236]:mode is normal, state is open
login used time : 6.405(ms)
disql V8
SQL> select instance_name from v$instance;

LINEID     INSTANCE_NAME
---------- -------------
1          RAC0

used time: 5.710(ms). Execute id is 53500.
SQL> select * from v$dsc_ep_info;

LINEID     EP_NAME EP_SEQNO    EP_GUID              EP_TIMESTAMP         EP_MODE      EP_STATUS
---------- ------- ----------- -------------------- -------------------- ------------ ---------
1          RAC0    0           2383210041           2383210726           Control Node OK
2          RAC1    1           2383231629           2383232293           Normal Node  OK

used time: 2.979(ms). Execute id is 53501.
SQL>

DM8高级日志

高级日志
简介
行表和HUGE表在增删改查性能上存在差异,因此在实际的生产环境中,用户可能会同时使用一个行表来管理数据和一个HUGE表来分析数据。具体做法是对行表进行增删改操作,然后把行表中的数据复制到HUGE表中用于查询或分析。如果每次分析数据时都对行表进行全表查询插入HUGE表,性能较低。

为此提出一种解决方案:给行表添加日志辅助表用于记录行表的增删改和TRUNCATE操作,可以根据日志表实现对HUGE表的增量更新,以此来提高从行表复制数据到HUGE表的性能。

使用须知
增量更新过程,我们只提供日志的记录以及日志记录规则的制定,真正执行增量更新是由用户根据日志记录自行操作。辅助表中登记信息,为某一时间点后源表数据的增量变化信息登记。

创建日志辅助表
创建日志辅助表,有两种方式:一是建表时创建;二是修改表时创建。
1. 建表时候使用< 高级日志子句>创建日志辅助表
语法格式

CREATE TABLE < 表名定义> < 表结构定义>;
< 表名定义> ::= [< 模式名>.] < 表名>
< 表结构定义>::=< 表结构定义1> | < 表结构定义2>
< 表结构定义1>::= (< 列定义> {,< 列定义>} [,< 表级约束定义>{,< 表级约束定义>}]) [ON COMMIT  ROWS] [][< 空间限制子句>] [][< 压缩子句>] []< 高级日志子句> [] []
……
< 高级日志子句>::= WITH ADVANCED LOG
省略号(……)

2. 修改表时使用< 高级日志子句>添加日志表
语法格式

ALTER TABLE < 高级日志子句>;

删除日志辅助表
语法格式

ALTER TABLE xxx WITHOUT ADVANCED LOG;

删除日志辅助表的数据
语法格式

ALTER TABLE  TRUNCATE ADVANCED LOG;

数据清除后可能导致源表和HUGE无法同步,需慎重操作。

使用日志辅助表的规则与约束
日志辅助表命名为“表名$ALOG”,用于记录源表的操作但不涉及具体数据。规则与约束:
1. 每个源表仅支持设置一个日志辅助表。
2. 表删除的同时删除其日志辅助表。
3. 表更名时,日志表同步更名。
4. 由于其日志表名长度不得超过128,因此表名长度不得超过123。
5. 辅助表仅登记源表相关增删改及TRUNCATE等涉及数据变化的操作,却不涉及具体数据。
6. 源表执行ADD/DROP/MODIFY COLUMN的DDL操作时,也必须保证日志辅助表为空。
7. 如果表设置了高级日志功能,禁止或者不建议以下操作:
1) 禁止对源表创建聚集索引
2) 禁止删除源表上本存在的聚集索引
3) 禁止直接对分区表的子表执行DELETE、UPDATE、INSERT以及TRUNCATE
4) 禁止在ALTER TABLE时,新建、删除或者修改主键,使主键失效或者生效,或者删除主键列
5) 禁止对临时表、HUGE表和间隔分区表设置高级日志表,禁止查询插入建表方式设置高级日志表。
6) 禁止直接删除高级日志表以及创建后缀为”$ALOG”的表
7) 禁止合并分区
8) 禁止对表加列、删除列和修改列,禁止添加、分裂、交换和删除分区。交换分区时的普通表也禁止带有高级日志
9) 表备份还原后无法控制数据跟踪,无法保证同步数据的正确性。因此不建议对该表进行备份还原操作,或操作后需要人工干预处理

日志辅助表结构
高级日志辅助表“表名$ALOG”的结构如下:

列                   数据类型           说明
ORG_ROWID            BIGINT             源表ROWID。当OP_TYPE=0时,ORG_ROWID=0
OP_TYPE              SMALLINT           登记记录日志动作。
                                        0:TRUNCATE
                                        1:行插入
                                        2:批量插入起始
                                        3:批量插入结束
                                        4:更新
                                        5:删除
                                        6:删除后再插入(仅用于堆表)

COLMAP               VARBINARY(2048)    当OP_TYPE=3时,记录的是批量插入结束的ROWID;
                                        当OP_TYPE=4时,是记录的更新列的列号。例如0xA3,即二进制的10100011,
                                        表示更新的列为第1、2、6、8列,与DM_BIT_TEST()配合使用;其他情况为null

COL_0     与源表的第一个主键列类型相同  源表的第一个主键列
COL_1     与源表的第二个主键列类型相同  源表的第二个主键列
COL_n     ...                           ...

系统过程
高级日志辅助表中的COLMAP列记录的数据,用&操作只能获取前64列的更新情况,因为会数据溢出。增加系统过程DM_BIT_TEST()用于获取一个VARBINARY数据的第N位的数值。
语法格式

DM_BIT_TEST(DATA varbinary, nth int);

功能:返回二进制数据varbinary第nth位是0还是1(最低位序号为1)。如果超过了位数则返回0。
例 0xF1转为二进制后为11110001,从低位开始第5位为1。二进制1011从低位开始第三位为0。

SQL> SELECT DM_BIT_TEST(0xF1,5),DM_BIT_TEST(1011,3);

LINEID     DM_BIT_TEST(0xF1,5) DM_BIT_TEST(1011,3)
---------- ------------------- -------------------
1          1                   0

使用高级日志同步数据的原则
用户根据表定义创建数据同步的目标表,自己编写同步DMSQL脚本来进行同步。对于同步,建议遵守如下的原则:
1. 如果源表有主键,如果用户没有特殊的限制或要求,目标表最好也设置同样的主键。
2. 如果源表没有主键,为了准确同步,最好在目标表上添加一个辅助同步的主键列,同步时将org_rowid列的值插入该列中。
3. 用户同步数据的脚本基本逻辑如下:

declare
/*遍历日志表的游标*/
cursor c IS select * from t01$alog for update;
/*同步用的变量*/
r t01$alog %rowtype;
/*同步批量插入用的变量*/
bi_start t01$alog %rowtype;
org_rec t01%rowtype;
begin
/*遍历日志表,根据各记录的op_type进行同步*/
open c;
loop
fetch c into r;
exit when c%notfound;
if (r.op_type = 0) then
print 'truncate' ;
execute immediate 'truncate table t01';
elseif (r.op_type = 1 or r.op_type = 6) then
print 'insert ' || r.org_rowid;
execute immediate 'insert ....'
elseif (r.op_type = 2) then
bi_start = r;
print 'batch insert start';
elseif (r.op_type = 3) then
print 'batch insert last ' || bi_start.org_rowid || ' ' || cast( r.colmap as bigint);
execute immediate 'insert ....'
elseif (r.op_type = 4) then
print 'update ' || r.org_rowid;
select * into org_rec from t01 where ……;
execute immediate 'update ....' using bi_start… r…;
elseif (r.op_type = 5) then
print 'delete ' || r.org_rowid;
execute immediate 'delete ....'
end if;
end loop;
close c;
/*清理日志表*/
execute immediate 'alter table t01 truncate advanced log';
end;
/

4. 如果在数据同步时源表仍有并发的DML,脚本中查询日志时要使用for update子句。

5. 同步脚本根据源表的结构有所不同:
1) 如果源表有聚集主键
在同步时可使用日志辅助表中的org_rowid和主键列辅助源表定位。使用主键列定位目标表。
2) 如果源表有主键,但不是聚集主键
直接根据org_rowid定位数据,最好不要使用主键列来定位源表。主键列仅用来定位目标表。
如果该情况下更新了主键列,对于聚集主键,将是删除后更新,如果不是聚集主键,仍是记录更新,日志辅助表中的主键列仍是原值,所以非聚集主键时主键列不要用来定位源表。
3) 如果没有主键
使用org_rowid来进行源表的定位;目标表的定义根据用户自己的方式使用org_rowid定位。
6. 如果源表中没有聚集索引,批量插入时可以根据OP_TYPE=3时的org_rowid(批量插入起始ROWID)和COLMAP中的数据(批量插入结束ROWID)范围查询源表插入目标表;如果有聚集索引,考虑到组合索引无法进行范围查询,只能使用第一个主键和rowid进行范围查询。
7. MPP环境下,因为高级日志表是本地表,所以同步数据的时候,只能各个节点单独做同步。

应用实例
创建不带主键的源表
1. 创建源表

SQL> Create table t01(a int, b int, c varchar);
executed successfully
used time: 16.049(ms). Execute id is 2438.

SQL> insert into t01 values(88,88, '原始数据1');
affect rows 1

used time: 0.689(ms). Execute id is 2440.
SQL> insert into t01 values(99,99, '原始数据2');
affect rows 1

used time: 0.430(ms). Execute id is 2442.

2. 在源表上创建日志辅助表

SQL> Alter table t01 with advanced log;
executed successfully
used time: 28.284(ms). Execute id is 2443.

3. 查看日志辅助表结构

SQL> Select tabledef('SYSDBA','T01$ALOG');

LINEID     TABLEDEF('SYSDBA','T01$ALOG')
---------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1          CREATE TABLE "SYSDBA"."T01$ALOG"
(
"ORG_ROWID" BIGINT NOT NULL,
"OP_TYPE" SMALLINT NOT NULL,
"COLMAP" VARBINARY(2048),
CLUSTER PRIMARY KEY("ORG_ROWID", "OP_TYPE")) STORAGE(ON "MAIN", CLUSTERBTR) ;

used time: 0.846(ms). Execute id is 2445.

4. 在源表中删除1行数据。

SQL> delete from t01 where a=88;
affect rows 1

used time: 1.329(ms). Execute id is 2447.

SQL> Select * from t01$alog;

LINEID     ORG_ROWID            OP_TYPE     COLMAP
---------- -------------------- ----------- ----------
1          1                    5           NULL

used time: 0.567(ms). Execute id is 2449.

5. 在源表中更新1行数据。

SQL> update t01 set c='hello world' where a=99;
affect rows 1

used time: 0.907(ms). Execute id is 2451.
SQL> Select * from t01$alog;

LINEID     ORG_ROWID            OP_TYPE     COLMAP
---------- -------------------- ----------- ----------
1          1                    5           NULL
2          2                    4           0x04

used time: 0.220(ms). Execute id is 2452.

6. 在源表中再次更新同1行数据。这一操作在日志表中没有记录。因为将源表上一条(99,99, ‘原始数据2’)的数据更新为(99,99,’hello world’)之后,又再次更新为(99,99,’hello world!’)。这两步更新操作的最终结果就和直接更新为(99,99,’hello world!’)一样,所以两步操作只有一条记录。

SQL> update t01 set c='hello world!' where a=99;
affect rows 1

used time: 0.976(ms). Execute id is 2457.
SQL> Select * from t01$alog;

LINEID     ORG_ROWID            OP_TYPE     COLMAP
---------- -------------------- ----------- ----------
1          1                    5           NULL
2          2                    4           0x04

used time: 0.307(ms). Execute id is 2458.

7. 先清空源表数据,再查看日志辅助表的变化。发现日志辅助表中也清空了之前的记录,只记录下了清空源表的操作。

SQL> Truncate table t01;
executed successfully
used time: 28.025(ms). Execute id is 2460.
SQL> Select * from t01$alog;

LINEID     ORG_ROWID            OP_TYPE     COLMAP
---------- -------------------- ----------- ----------
1          0                    0           NULL

used time: 0.414(ms). Execute id is 2461.

8. 在源表中批量插入100行数据。单机情况下,大于100条才叫批量插入。

SQL> insert into t01 select level a,level+1 b,level c connect by level< =100 order by a,b; affect rows 100 used time: 2.692(ms). Execute id is 2464. SQL> Select * from t01$alog;

LINEID     ORG_ROWID            OP_TYPE     COLMAP
---------- -------------------- ----------- ------------------
1          0                    0           NULL
2          1                    2           NULL
3          1                    3           0x0000000000000064

used time: 0.343(ms). Execute id is 2466.

9. 在源表中插入1行数据。

SQL> insert into t01 values(1001,1002,1003);
affect rows 1

used time: 0.539(ms). Execute id is 2468.
SQL> Select * from t01$alog;

LINEID     ORG_ROWID            OP_TYPE     COLMAP
---------- -------------------- ----------- ------------------
1          0                    0           NULL
2          1                    2           NULL
3          1                    3           0x0000000000000064
4          101                  1           NULL

used time: 0.178(ms). Execute id is 2470.

10.同步数据
创建huge表。因为不带主键,为了准确同步,在目标表huge_t01上添加一个辅助同步的主键列c_rowid,同步时将org_rowid列的值插入该列中

SQL> create huge table huge_t01 (c_rowid bigint, a int, b int, c varchar(1024));
executed successfully
used time: 26.784(ms). Execute id is 2474.

运行同步脚本。同步脚本由用户根据实际情况自行编写。本例中脚本如下:

SQL> declare
2   /*遍历日志表的游标*/
3   cursor c IS select * from t01$alog for update;
4   /*同步用的变量*/
5   r t01$alog %rowtype;
6   /*同步批量插入用的变量*/
7   bi_start t01$alog %rowtype;
8   set_sql varchar;
9   upd_sql varchar;
10  i int;
11  begin
12  /*遍历日志表,根据各记录的op_type进行同步*/
13  open c;
14  loop
15  fetch c into r;
16  exit when c%notfound;
17  if (r.op_type = 0) then
18  print 'truncate' ;
19  execute immediate 'truncate table huge_t01;';
20  elseif (r.op_type = 1 or r.op_type = 6) then
21  print 'insert ' || r.org_rowid;
22  execute immediate 'insert into huge_t01 select rowid,* from t01 where rowid=?;' using r.org_rowid;
23  elseif (r.op_type = 2) then
24  bi_start = r;
25  print 'batch insert start';
26  elseif (r.op_type = 3) then
27  print 'batch insert last ' || bi_start.org_rowid || ' ' || cast( r.colmap as bigint);
28  execute immediate 'insert into huge_t01 select rowid,* from t01 where rowid>= ? and rowid< = ?;' using r.org_rowid, cast(r.colmap as bigint); 29 elseif (r.op_type = 4) then 30 print 'update ' || r.org_rowid; 31 set_sql = ''; 32 i = 0; 33 if (dm_bit_test(r.colmap,1)) = 1 then set_sql = set_sql || 'a = org.a'; i = i+1; end if; 34 if (dm_bit_test(r.colmap,2)) = 1 then if i > 0 then set_sql = set_sql ||','; end if; set_sql = set_sql || 'b = org.b'; i = i+1; end if;
35  if (dm_bit_test(r.colmap,3)) = 1 then if i > 0 then set_sql = set_sql ||','; end if; set_sql = set_sql || 'c = org.c'; i = i+1; end if;
36  upd_sql = 'declare org t01%rowtype; begin select * into org from t01 where rowid=?; update huge_t01 set ' || set_sql || ' where c_rowid=?; end;';
37  execute immediate upd_sql using r.org_rowid, r.org_rowid;
38  elseif (r.op_type = 5) then
39  print 'delete ' || r.org_rowid;
40  execute immediate 'delete from huge_t01 where c_rowid=?;' using r.org_rowid;
41  end if;
42  end loop;
43  close c;
44  /*清理日志表*/
45  execute immediate 'alter table t01 truncate advanced log';
46  end;
47  /
DMSQL executed successfully
used time: 197.177(ms). Execute id is 2478.

11.查询huge表中的数据。可以看出,huge_t01上的数据都是源表创建了日志辅助表之后的增量数据。

SQL> Select count(*) from huge_t01;

LINEID     COUNT(*)
---------- --------------------
1          101

used time: 0.622(ms). Execute id is 2479.

创建带主键的源表
1. 创建带有日志辅助表的源表

SQL> Create table t01(a int, b int, c varchar, primary key(a,b)) with advanced log;
executed successfully
used time: 14.030(ms). Execute id is 2834.

2. 查看日志辅助表结构

SQL> Select tabledef('SYSDBA','T01$ALOG');

LINEID     TABLEDEF('SYSDBA','T01$ALOG')
---------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1          CREATE TABLE "SYSDBA"."T01$ALOG"
(
"ORG_ROWID" BIGINT NOT NULL,
"OP_TYPE" SMALLINT NOT NULL,
"COLMAP" VARBINARY(2048),
"COL_0" INTEGER,
"COL_1" INTEGER,
CLUSTER PRIMARY KEY("ORG_ROWID", "OP_TYPE")) STORAGE(ON "MAIN", CLUSTERBTR) ;

used time: 0.637(ms). Execute id is 2844.

3. 清空源表

SQL> Truncate table t01;
executed successfully
used time: 14.417(ms). Execute id is 2849.

SQL> Select * from t01$alog;

LINEID     ORG_ROWID            OP_TYPE     COLMAP     COL_0       COL_1
---------- -------------------- ----------- ---------- ----------- -----------
1          0                    0           NULL       NULL        NULL

used time: 0.760(ms). Execute id is 2857.

4. 在源表中插入一条记录

SQL> insert into t01 values(1001,1002,1003);
affect rows 1

used time: 0.621(ms). Execute id is 2860.
SQL> Select * from t01$alog;

LINEID     ORG_ROWID            OP_TYPE     COLMAP     COL_0       COL_1
---------- -------------------- ----------- ---------- ----------- -----------
1          0                    0           NULL       NULL        NULL
2          1                    1           NULL       1001        1002

used time: 0.313(ms). Execute id is 2861.

5. 同步数据
创建huge表。

SQL> create huge table huge_t01 (a int, b int, c varchar(1024), primary key(a,b));
executed successfully
used time: 24.819(ms). Execute id is 2868.

运行同步脚本。同步脚本由用户根据实际情况自行编写。本例中脚本如下:

SQL> declare
2   /*遍历日志表的游标*/
3   cursor c IS select * from t01$alog for update;
4   /*同步用的变量*/
5   r t01$alog %rowtype;
6   /*同步批量插入用的变量*/
7   bi_start t01$alog %rowtype;
8   set_sql varchar;
9   upd_sql varchar;
10  i int;
11  begin
12  /*遍历日志表,根据各记录的op_type进行同步*/
13  open c;
14  loop
15  fetch c into r;
16  exit when c%notfound;
17  if (r.op_type = 0) then
18  print 'truncate' ;
19  execute immediate 'truncate table huge_t01;';
20  elseif (r.op_type = 1 or r.op_type = 6) then
21  print 'insert ' || r.org_rowid;
22  execute immediate 'insert into huge_t01 select * from t01 where rowid=?;' using r.org_rowid;
23  elseif (r.op_type = 2) then
24  bi_start = r;
25  print 'batch insert start';
26  elseif (r.op_type = 3) then
27  print 'batch insert last ' || bi_start.org_rowid || ' ' || cast( r.colmap as bigint);
28  execute immediate 'insert into huge_t01 select * from t01 where rowid>= ? and rowid< = ?;' using r.org_rowid, cast(r.colmap as bigint); 29 elseif (r.op_type = 4) then 30 print 'update ' || r.org_rowid; 31 set_sql = ''; 32 i = 0; 33 if (dm_bit_test(r.colmap,1)) = 1 then set_sql = set_sql || 'a = org.a'; i = i+1; end if; 34 if (dm_bit_test(r.colmap,2)) = 1 then if i > 0 then set_sql = set_sql ||','; end if; set_sql = set_sql || 'b = org.b'; i = i+1; end if;
35  if (dm_bit_test(r.colmap,3)) = 1 then if i > 0 then set_sql = set_sql ||','; end if; set_sql = set_sql || 'c = org.c'; i = i+1; end if;
36  upd_sql = 'declare org t01%rowtype; begin select * into org from t01 where rowid=?; update huge_t01 set ' || set_sql || ' where a = ? and b = ?; end;';
37  execute immediate upd_sql using r.org_rowid, r.col_0, r.col_1;
38  elseif (r.op_type = 5) then
39  print 'delete ' || r.org_rowid;
40  execute immediate 'delete from huge_t01 where a= ? and b = ?;' using r.col_0, r.col_1;
41  end if;
42  end loop;
43  close c;
44  /*清理日志表*/
45  execute immediate 'alter table t01 truncate advanced log';
46  end;
47  /
DMSQL executed successfully
used time: 134.846(ms). Execute id is 2872.

6. 查询huge表中的数据。可以看出,huge_t01上的数据都是源表创建了日志辅助表之后的增量数据。

SQL> select * from huge_t01;

LINEID     A           B           C
---------- ----------- ----------- ----
1          1001        1002        1003

used time: 1.276(ms). Execute id is 2875.

DM8管理数组索引

数组索引指在一个只包含单个数组成员的对象列上创建的索引。
语法格式

CREATE ARRAY INDEX < 索引名> ON [< 模式名>.] < 表名> (< 索引列定义>)

使用说明
1) 暂不支持在水平分区表上创建数组索引;
2) 暂时不支持在有数组索引表上进行批量装载(数组索引失效的例外);
3) 支持创建数组索引的对象只能包含数组一个成员。数组可以是DM静态数组、动态数组或者ORACLE兼容的嵌套表或VARRAY;
4) 数组项类型只能是可比较的标量类型,不支持复合类型、对象类型或大字段类型;
5) 临时表不支持;
6) 数组索引不支持改名;
7) 数组索引列不支持改名;
8) 数组索引只能是单索引,不能为组合索引;
9) 不支持空值的检索
10) MPP环境不支持数组索引。

数组索引修改语句与普通索引用法相同,与普通索引不同的是,数组索引不支持NOSORT和ONLINE用法。

数组索引使用
使用数组索引进行查询,必须使用谓词CONTAINS。
语法格式

CONTAINS(< 索引列名>,)

或者

CONTAINS(< 索引列名>,arr_var_exp)

参数
val:必须为与对象列数组项相同或可转换的标量类型表达式。
arr_var_exp:必须为数组类型(DM静态数组、动态数组或者ORACLE兼容的嵌套表或VARRAY),其数组项类型必须与对象列数组项类型相同或可转换。

举例说明

SQL> CREATE TYPE ARR_NUM1 IS VARRAY(1024) OF NUMBER;   --VARRAY数组
2   /
executed successfully
used time: 27.267(ms). Execute id is 13.
SQL> CREATE TYPE ARR_NUM2 IS TABLE OF NUMBER;    --嵌套表
2   /
executed successfully
used time: 27.319(ms). Execute id is 14.
SQL> CREATE TYPE ARR_NUM3 IS ARRAY NUMBER[];   --动态
2   /
executed successfully
used time: 20.404(ms). Execute id is 15.
SQL> CREATE TYPE ARR_NUM4 IS ARRAY NUMBER[3];   --静态
2   /
executed successfully
used time: 18.836(ms). Execute id is 16.
SQL> CREATE CLASS CLS1 AS V ARR_NUM1;END;
2   /
executed successfully
used time: 16.774(ms). Execute id is 17.

SQL> CREATE TABLE TEST (C1 CLS1);
executed successfully
used time: 21.077(ms). Execute id is 20.
SQL> INSERT INTO TEST VALUES(CLS1(ARR_NUM1(1,2,3)));
affect rows 1

used time: 1.497(ms). Execute id is 21.
SQL> INSERT INTO TEST VALUES(CLS1(ARR_NUM1(1,2)));
affect rows 1

used time: 0.598(ms). Execute id is 22.
SQL> INSERT INTO TEST VALUES(CLS1(ARR_NUM1(2,1)));
affect rows 1

used time: 0.627(ms). Execute id is 23.
SQL> INSERT INTO TEST VALUES(CLS1(ARR_NUM1(1,5)));
affect rows 1

used time: 0.555(ms). Execute id is 24.
SQL> INSERT INTO TEST VALUES(CLS1(ARR_NUM1(2,4)));
affect rows 1

used time: 0.925(ms). Execute id is 25.
SQL> INSERT INTO TEST VALUES(CLS1(ARR_NUM1(4,5,6)));
affect rows 1

used time: 0.908(ms). Execute id is 26.
SQL> CREATE ARRAY INDEX IDX ON TEST(C1);  --创建数组索引
executed successfully
used time: 36.684(ms). Execute id is 27.
SQL> SELECT * FROM TEST WHERE CONTAINS(C1,1,2,3);  --使用数组索引查询

LINEID     C1
---------- ----------------------------
1          SYSDBA.CLS1(ARR_NUM1(1,2,3))
2          SYSDBA.CLS1(ARR_NUM1(1,2))
3          SYSDBA.CLS1(ARR_NUM1(2,1))
4          SYSDBA.CLS1(ARR_NUM1(1,5))
5          SYSDBA.CLS1(ARR_NUM1(2,4))

used time: 3.133(ms). Execute id is 28.



--嵌套表
SQL> DECLARE
2   X ARR_NUM2;
3   BEGIN
4   X := ARR_NUM2();
5   X.EXTEND(3);
6   X(1) := 1;
7   X(2) := 2;
8   X(3) := 3;
9   SELECT * FROM TEST WHERE CONTAINS(C1,X);
10  END;
11  /

LINEID     C1
---------- ----------------------------
1          SYSDBA.CLS1(ARR_NUM1(1,2,3))
2          SYSDBA.CLS1(ARR_NUM1(1,5))
3          SYSDBA.CLS1(ARR_NUM1(2,1))
4          SYSDBA.CLS1(ARR_NUM1(1,2))
5          SYSDBA.CLS1(ARR_NUM1(2,4))

used time: 7.699(ms). Execute id is 32.

--动态数组
SQL> DECLARE
2   X ARR_NUM3;
3   BEGIN
4   X := NEW NUMBER [3];
5   X[1]:= 1;
6   X[2]:= 2;
7   X[3]:= 3;
8   SELECT * FROM TEST WHERE CONTAINS(C1,X);
9   END;
10  /

LINEID     C1
---------- ----------------------------
1          SYSDBA.CLS1(ARR_NUM1(1,2,3))
2          SYSDBA.CLS1(ARR_NUM1(1,5))
3          SYSDBA.CLS1(ARR_NUM1(2,1))
4          SYSDBA.CLS1(ARR_NUM1(1,2))
5          SYSDBA.CLS1(ARR_NUM1(2,4))

used time: 5.921(ms). Execute id is 34.

--静态数组
SQL> DECLARE
2   X ARR_NUM4;
3   BEGIN
4   X[1]:= 1;
5   X[2]:= 2;
6   X[3]:= 3;
7   SELECT * FROM TEST WHERE CONTAINS(C1,X);
8   END;
9   /

LINEID     C1
---------- ----------------------------
1          SYSDBA.CLS1(ARR_NUM1(1,2,3))
2          SYSDBA.CLS1(ARR_NUM1(1,5))
3          SYSDBA.CLS1(ARR_NUM1(2,1))
4          SYSDBA.CLS1(ARR_NUM1(1,2))
5          SYSDBA.CLS1(ARR_NUM1(2,4))

used time: 5.954(ms). Execute id is 36.

数组索引删除语句

SQL> drop index idx;
executed successfully
used time: 70.830(ms). Execute id is 38.