Oracle在线数据重组与重定义的适用场景
千呼万唤始出来,大家要看的在线重定义(下)今天终于出炉了,前面两篇已经介绍过了《Oracle 在线重定义(中)》相关基础知识及示例了,这一篇简单介绍下重定义的适用场景和功能以及普通表改分区表的四种方式,则算是大杂烩。
————————————————————————————
微信公众号:JiekeXu DBA之路
墨天轮:https://www.modb.pro/u/4347
CSDN :https://blog.csdn.net/JiekeXu
腾讯云:https://cloud.tencent.com/developer/user/5645107
————————————————————————————
数据库持续在线以保持应用程序的可用性,减少运维复杂度
- 修改表或簇的存储参数
- 为表添加,修改或删除列
- 修改表的约束
- 增加并行查询支持
- 重建表以减少碎片
- 将堆表变为索引组织表或相反
- 改变物化视图表结构
- 重建索引
- 修改索引的分区方式
- 为表添加或删除分区,改变分区结构
- 表的分区拆分及合并
- 表分区交换
- 将堆表变为索引组织表或相反
- 普通表转为分区表
- 分区表转普通表
- 修改表的分区方式
- 将表移动到相同或不同的 tablespace
数据文件在线迁移
使用 Oracle 12C 以后的版本,您现在可以在数据文件在线并被访问时执行以下操作:
• 重命名在线数据文件
• 迁移在线数据文件
• 复制在线数据文件
• 重新定位在线数据文件和覆盖已有文件
• 将在线数据文件迁移到 Oracle ASM
1. 查询数据文件位置
select
file_id,tablespace_name,file_name,bytes/1024/1024
from dba_data_files d
where tablespace_name='JiekeXu_TBS';
2. 迁移数据文件
alter database move datafile 15 to
'+DATA/orcldb/datafile/jiekexu_tbs01.dbf';
分区维护的在线操作
Move: 更改分区位置和存储属性
Merge: 许多分区合并为一个分区
Split: 一个分区变成很多分区
表转换在线操作
将非分区表转换为分区表
改变分区表的分区
在线重新定义表的功能
• 修改表或集群的存储参数。
• 将表或集群移动到不同的表空间
• 在表或集群中添加、修改或删除一个或多个列
• 添加或删除分区支持(仅限非集群表)
• 改变分区结构
• 更改单个表分区或子分区的物理属性,包括将其移动到同一架构中的不同表空间
• 重新创建表或集群以减少碎片
• 压缩或更改表、分区、索引键或 LOB 列的压缩类型。
• 将 LOB 列从 BasicFiles LOB 存储转换为 SecureFiles LOB 存储,或执行相反的操作。
• 您可以通过查询 V$ONLINE_REDEF 视图来监控在线重定义表操作的进度
• 将普通表(堆组织)的组织更改为索引组织表,或执行相反的操作。
在线重定义的步骤
上篇文章已经介绍了在线重定义了,这里简单罗列一下主要步骤。
- 验证是否可以执行在线重定义
- 创建过渡临时表
- 执行表的在线重定义
- 复制创建依赖对象
- 进行原表与过渡表数据同步
- 结束在线定义过程
将普通表改为分区表的四种方式
1)在线重定义
使用在线重定义的方式,上面两篇已经介绍过了,大家可以自己实际测试一下。需要注意的点也挺多,比如主外键约束、不支持的数据类型、表空间大小、归档空间、OGG 等第三方同步工具,收集统计信息等等,下面其他方式也需要考虑这些问题,一定要经过测试验证方可实施,这里只是抛砖引玉,仅供参考。
2)CTAS 创建分区表或导入导出
新建分区表,然后停止相关业务,使用 insert into … select 的方式导入数据,如果表小的话直接 CTAS 创建分区表,如果表数据量比较大,可以考虑使用数据泵导出导入或者使用并行 DML 导入:
alter session enable parallel dml;
insert /*+ parallel(12)*/ into Jieke.T_test_bak1124
select /*+ parallel(12)*/ * from Jieke.T_test;
然后删除约束,做两次 rename重命名操作,创建合适的本地索引或全局索引及约束。
3)分区交换&分区分裂
在 Oracle 12.2以上的版本,创建只有一个分区的分区表, 用 exchange partition 将原表变成分区表后,再 split partition,然后重命名表。
官方文档链接:https://docs.oracle.com/en/database/oracle/oracle-database/19/vldbg/maintenance-partition-tables-indexes.html#GUID-93BFB499-39A6-4DDE-88C3-BF7A63848E25
Exchanging Partitions: 通过交换数据段,可以将分区或子分区转换为非分区表,也可以将非分区表转换为分区表的分区或子分区。还可以将哈希分区表转换为复合 * 哈希分区表的分区,或将复合 * 哈希分区表的分区转换为哈希分区表。同样,也可以将范围分区表或列表分区表转换为复合 * 范围分区表或列表分区表的分区,或将复合 * 范围分区表或列表分区表的分区转换为范围分区表或列表分区表。交换表分区对于快速进出分区表非常有用。例如,在数据仓库环境中,交换分区有助于将新的增量数据高速加载到现有的分区表中。请注意,在交换过程中,源数据被移动到目标数据,而目标数据又被移动到源数据。
除非指定 UPDATE INDEXES,否则 Oracle 数据库会将正在交换分区的表上的全局索引或所有全局索引分区标记为不可用。被交换表上的全局索引或全局索引分区仍然无效。对于索引组织的表,不能使用 UPDATE INDEXES。请使用 UPDATE GLOBAL INDEXES 代替。如果在 DBMS_STATS 表首选项 INCREMENTAL 设置为 true 且 INCREMENTAL_LEVEL 设置为 TABLE 时,在非分区表上收集了统计信息,则分区表上的递增统计信息将在分区交换操作中保留。在虚拟列的列统计信息失序的情况下,将删除列统计信息,而不是保留过时的统计信息。有关删除的信息将写入警报日志文件。
SPLIT PARTITION: 可以将一个分区的内容拆分为两个新分区。ALTER TABLE 或 ALTER INDEX 语句中的 SPLIT PARTITION 子句用于将一个分区的内容重新分配到两个新分区中。当分区过大,导致备份、恢复或维护操作需要很长时间才能完成,或者认为分区中的数据过多时,可以考虑这样做。还可以使用 SPLIT PARTITION 子句重新分配 I/O 负载。该子句不能用于散列分区或子分区。除了父表之外,不能在引用分区表中拆分分区或子分区。在父表中拆分分区或子分区时,拆分会级联到所有子表。不过,在主表上发出 SPLIT 语句分割分区或子分区时,可以使用 DEPENDENT TABLES 子句为从属表设置特定属性。对于堆组织的表,支持使用关键字 ONLINE 将 SPLIT 操作作为联机操作进行分区维护,这样就可以在分区维护操作进行时同时进行 DML 操作。对于 ONLINE 操作,无论是否指定 UPDATE INDEXES 子句,拆分索引默认情况下都会更新。
如下简单示例,仅供参考:
--要改造成为分区表的源表
CREATE TABLE sales_exchange_table
( prod_id NUMBER NOT NULL,
cust_id NUMBER NOT NULL,
time_id DATE NOT NULL,
channel_id NUMBER NOT NULL,
promo_id NUMBER NOT NULL,
quantity_sold NUMBER(10,2) NOT NULL,
amount_sold NUMBER(10,2) NOT NULL
);
INSERT INTO sales_exchange_table VALUES (1002,110,TO_DATE('19-02-2020','dd-mm-yyyy'),12,18,150,4800);
INSERT INTO sales_exchange_table VALUES (1001,100,TO_DATE('12-03-2020','dd-mm-yyyy'),10,15,400,6500);
INSERT INTO sales_exchange_table VALUES (1001,100,TO_DATE('31-05-2020','dd-mm-yyyy'),10,15,600,8000);
INSERT INTO sales_exchange_table VALUES (2105,101,TO_DATE('25-06-2020','dd-mm-yyyy'),12,19,100,3000);
INSERT INTO sales_exchange_table VALUES (1002,120,TO_DATE('31-08-2020','dd-mm-yyyy'),10,15,400,6000);
INSERT INTO sales_exchange_table VALUES (2105,101,TO_DATE('25-10-2020','dd-mm-yyyy'),12,19,250,7500);
INSERT INTO sales_exchange_table VALUES (1002,110,TO_DATE('15-02-2021','dd-mm-yyyy'),12,18,300,9500);
INSERT INTO sales_exchange_table VALUES (1002,120,TO_DATE('31-03-2021','dd-mm-yyyy'),10,15,200,3000);
INSERT INTO sales_exchange_table VALUES (2105,101,TO_DATE('25-04-2021','dd-mm-yyyy'),12,19,150,9000);
commit;
INSERT INTO sales_exchange_table VALUES (1001,101,TO_DATE('15-04-2022','dd-mm-yyyy'),12,19,150,7500);
INSERT INTO sales_exchange_table VALUES (1002,101,TO_DATE('25-08-2022','dd-mm-yyyy'),12,19,150,9000);
INSERT INTO sales_exchange_table VALUES (2105,101,TO_DATE('17-04-2023','dd-mm-yyyy'),12,19,150,9000);
INSERT INTO sales_exchange_table VALUES (1001,101,TO_DATE('25-09-2023','dd-mm-yyyy'),12,19,150,9200);
INSERT INTO sales_exchange_table VALUES (2105,101,TO_DATE('25-04-2024','dd-mm-yyyy'),12,19,150,9500);
commit;
alter table SALES_EXCHANGE_TABLE add primary key (TIME_ID);
然后新建分区表,只有一个分区,以 time_id 为例,取其最大值创建分区表。
CREATE TABLE sales_exchange_table_new
( prod_id NUMBER NOT NULL,
cust_id NUMBER NOT NULL,
time_id DATE NOT NULL,
channel_id NUMBER NOT NULL,
promo_id NUMBER NOT NULL,
quantity_sold NUMBER(10,2) NOT NULL,
amount_sold NUMBER(10,2) NOT NULL
)
PARTITION BY RANGE (time_id)
(PARTITION s_2024 VALUES LESS THAN (TO_DATE('01-01-2025','dd-mm-yyyy')));
分区交换
交换分区指可以用一个非分区表与分区表的某个分区/子分区进行置换(数据段交换)。利用交换分区可以快速将数据载入或者移出分区表,且置换分区操作没有类型限制,所有的分区策略都可以使用此特性。
REM You must disable or DROP the constraint before the exchange。删除或者禁用外键约束
ALTER TABLE sales_exchange_table DROP CONSTRAINT sales_exchange_table_fk;
ALTER TABLE sales_exchange_table_new EXCHANGE PARTITION s_2024 WITH TABLE sales_exchange_table UPDATE GLOBAL INDEXES;
SELECT * FROM sales_exchange_table_new;
SQL > SELECT * FROM sales_exchange_table_new PARTITION(s_2024);
PROD_ID CUST_ID TIME_ID CHANNEL_ID PROMO_ID QUANTITY_SOLD AMOUNT_SOLD
---------- ---------- ------------------- ---------- ---------- ------------- -----------
1002 110 2020-02-19 00:00:00 12 18 150 4800
1001 100 2020-03-12 00:00:00 10 15 400 6500
1001 100 2020-05-31 00:00:00 10 15 600 8000
2105 101 2020-06-25 00:00:00 12 19 100 3000
1002 120 2020-08-31 00:00:00 10 15 400 6000
2105 101 2020-10-25 00:00:00 12 19 250 7500
1002 110 2021-02-15 00:00:00 12 18 300 9500
1002 120 2021-03-31 00:00:00 10 15 200 3000
2105 101 2021-04-25 00:00:00 12 19 150 9000
1001 101 2022-04-15 00:00:00 12 19 150 7500
1002 101 2022-08-25 00:00:00 12 19 150 9000
2105 101 2023-04-17 00:00:00 12 19 150 9000
1001 101 2023-09-25 00:00:00 12 19 150 9200
2105 101 2024-04-25 00:00:00 12 19 150 9500
14 rows selected.
SQL > select * from sales_exchange_table;
no rows selected
分区分裂
23:36:12 JIEKEXU@JIEKEXUPDB> ALTER TABLE sales_exchange_table_new
23:38:10 2 SPLIT PARTITION s_2024 INTO
23:38:10 3 (PARTITION p_2020_year VALUES LESS THAN (TO_DATE('01-01-2021','dd-mm-yyyy')),
23:38:10 4 PARTITION p_2021_year VALUES LESS THAN (TO_DATE('01-01-2022','dd-mm-yyyy')),
23:38:10 5 PARTITION p_2022_year VALUES LESS THAN (TO_DATE('01-01-2023','dd-mm-yyyy')),
23:38:10 6 PARTITION p_2023_year VALUES LESS THAN (TO_DATE('01-01-2024','dd-mm-yyyy')),
23:38:10 7 PARTITION p_2024_year
23:38:10 8 ) ONLINE;
Table altered.
Elapsed: 00:00:00.26
23:38:12 JIEKEXU@JIEKEXUPDB> select * from sales_exchange_table_new;
PROD_ID CUST_ID TIME_ID CHANNEL_ID PROMO_ID QUANTITY_SOLD AMOUNT_SOLD
---------- ---------- ------------------- ---------- ---------- ------------- -----------
1002 110 2020-02-19 00:00:00 12 18 150 4800
1001 100 2020-03-12 00:00:00 10 15 400 6500
1001 100 2020-05-31 00:00:00 10 15 600 8000
2105 101 2020-06-25 00:00:00 12 19 100 3000
1002 120 2020-08-31 00:00:00 10 15 400 6000
2105 101 2020-10-25 00:00:00 12 19 250 7500
1002 110 2021-02-15 00:00:00 12 18 300 9500
1002 120 2021-03-31 00:00:00 10 15 200 3000
2105 101 2021-04-25 00:00:00 12 19 150 9000
1001 101 2022-04-15 00:00:00 12 19 150 7500
1002 101 2022-08-25 00:00:00 12 19 150 9000
2105 101 2023-04-17 00:00:00 12 19 150 9000
1001 101 2023-09-25 00:00:00 12 19 150 9200
2105 101 2024-04-25 00:00:00 12 19 150 9500
14 rows selected.
Elapsed: 00:00:00.00
23:39:08 JIEKEXU@JIEKEXUPDB> SELECT * FROM sales_exchange_table_new PARTITION(p_2021_year);
PROD_ID CUST_ID TIME_ID CHANNEL_ID PROMO_ID QUANTITY_SOLD AMOUNT_SOLD
---------- ---------- ------------------- ---------- ---------- ------------- -----------
1002 110 2021-02-15 00:00:00 12 18 300 9500
1002 120 2021-03-31 00:00:00 10 15 200 3000
2105 101 2021-04-25 00:00:00 12 19 150 9000
Elapsed: 00:00:00.01
23:39:28 JIEKEXU@JIEKEXUPDB> SELECT * FROM sales_exchange_table_new PARTITION(p_2022_year);
PROD_ID CUST_ID TIME_ID CHANNEL_ID PROMO_ID QUANTITY_SOLD AMOUNT_SOLD
---------- ---------- ------------------- ---------- ---------- ------------- -----------
1001 101 2022-04-15 00:00:00 12 19 150 7500
1002 101 2022-08-25 00:00:00 12 19 150 9000
Elapsed: 00:00:00.00
23:39:47 JIEKEXU@JIEKEXUPDB> SELECT * FROM sales_exchange_table_new PARTITION(p_2023_year);
PROD_ID CUST_ID TIME_ID CHANNEL_ID PROMO_ID QUANTITY_SOLD AMOUNT_SOLD
---------- ---------- ------------------- ---------- ---------- ------------- -----------
2105 101 2023-04-17 00:00:00 12 19 150 9000
1001 101 2023-09-25 00:00:00 12 19 150 9200
Elapsed: 00:00:00.01
23:40:07 JIEKEXU@JIEKEXUPDB> SELECT * FROM sales_exchange_table_new PARTITION(p_2024_year);
PROD_ID CUST_ID TIME_ID CHANNEL_ID PROMO_ID QUANTITY_SOLD AMOUNT_SOLD
---------- ---------- ------------------- ---------- ---------- ------------- -----------
2105 101 2024-04-25 00:00:00 12 19 150 9500
Elapsed: 00:00:00.00
23:40:26 JIEKEXU@JIEKEXUPDB> SELECT * FROM sales_exchange_table_new PARTITION(p_2021_year);
PROD_ID CUST_ID TIME_ID CHANNEL_ID PROMO_ID QUANTITY_SOLD AMOUNT_SOLD
---------- ---------- ------------------- ---------- ---------- ------------- -----------
1002 110 2021-02-15 00:00:00 12 18 300 9500
1002 120 2021-03-31 00:00:00 10 15 200 3000
2105 101 2021-04-25 00:00:00 12 19 150 9000
Elapsed: 00:00:00.00
如下其他管理操作,添加分区、查看分区等不需要现在里面操作。
--添加分区
alter table sales_exchange_table_new add partition p_2025_year values less than (TO_DATE('2026-01-01','yyyy-mm-dd'));
--查看分区
select OWNER,TABLE_NAME,PARTITIONING_TYPE,PARTITION_COUNT,STATUS,INTERVAL from dba_part_tables
where table_name=upper('sales_exchange_table_new') and owner='JIEKEXU';
select TABLE_OWNER,TABLE_NAME,PARTITION_NAME,NUM_ROWS from dba_tab_partitions
where table_name=upper('sales_exchange_table_new') and TABLE_OWNER='JIEKEXU';
最后收尾工作,重命名表收集统计信息,恢复应用访问等操作。
alter table sales_exchange_table rename to sales_exchange_table_bak20240125;
alter table sales_exchange_table_new rename to sales_exchange_table;
--收集统计信息
exec dbms_stats.gather_table_stats(ownname => 'JIEKEXU', tabname => 'SALES_EXCHANGE_TABLE',estimate_percent => 100,method_opt => 'for all columns size auto',no_invalidate => FALSE,degree => DBMS_STATS.AUTO_DEGREE,cascade => TRUE);
##--重命名分区
ALTER TABLE sales_exchange_table_new RENAME PARTITION p_2025_year TO p_default_year;
##--truncate 分区
alter table sales_exchange_table_new truncate partition p_2025_year update indexes;
如下是操作间隔分区示例
--交换间隔分区
ALTER TABLE interval_sales
EXCHANGE PARTITION FOR (TO_DATE('01-JUN-2007','dd-MON-yyyy'))
WITH TABLE interval_sales_jun_2007
INCLUDING INDEXES;
--分裂间隔分区
ALTER TABLE all_seasons SPLIT PARTITION quarter_1 AT (TO_DATE('16-dec-1997','dd-mon-yyyy')) INTO (PARTITION q1_1997_1 SUBPARTITIONS 4 STORE IN (ts1,ts3), PARTITION q1_1997_2);
4)Modify修改分区策略
在 Oracle 12.2 以上的版本, 可以直接通过 alter table test modify partition 命令, 将普通表直接改成分区表, 并且支持 online 在线操作不停业务。下面简单介绍下 modify 修改分区的办法。
官方文档:https://docs.oracle.com/en/database/oracle/oracle-database/19/vldbg/maintenance-partition-tables-indexes.html#GUID-763391C6-44E8-401D-8119-DC12926F5877
可以使用 ALTER TABLE MODIFY PARTITION SQL 语句更改常规(堆组织)表的分区策略。
修改分区策略,如将哈希分区改为复合范围-哈希分区,可以脱机或联机执行。在联机模式下执行时,转换不会影响正在进行的 DML 操作。在离线模式下执行时,转换不允许在修改期间同时进行 DML 操作。索引作为表修改的一部分得到维护。修改分区策略时,索引列是新分区键前缀的所有未指定索引会自动转换为本地分区索引;否则,索引会转换为全局索引。
域索引不支持修改操作。UPDATE INDEXES 子句不能更改最初定义索引列表的列,也不能更改索引的唯一性属性或任何其他索引属性。
有关将非分区表转换为分区表的信息,请参阅将非分区表转换为分区表。
通过在 ALTER TABLE SQL 语句中添加 MODIFY 子句,可以将非分区表转换为分区表。此外,还可以指定关键字 ONLINE,以便在转换过程中进行并发 DML 操作。
下面是 ALTER TABLE 语句使用 ONLINE 关键字在线将表转换为分区表的示例。
ALTER TABLE employees_convert MODIFY
PARTITION BY RANGE (employee_id) INTERVAL (100)
( PARTITION P1 VALUES LESS THAN (100),
PARTITION P2 VALUES LESS THAN (500)
) ONLINE
UPDATE INDEXES
( IDX1_SALARY LOCAL,
IDX2_EMP_ID GLOBAL PARTITION BY RANGE (employee_id)
( PARTITION IP1 VALUES LESS THAN (MAXVALUE))
);
下面例子展示了如何使用 ALTER TABLE 将范围分区表在线转换为复合范围-哈希分区表。在示例中修改 ALTER TABLE 时,会更新索引。
Example Modifying the partitioning strategy
CREATE TABLE mod_sales_partitioning
( prod_id NUMBER NOT NULL,
cust_id NUMBER NOT NULL,
time_id DATE NOT NULL,
channel_id NUMBER NOT NULL,
promo_id NUMBER NOT NULL,
quantity_sold NUMBER(10,2) NOT NULL,
amount_sold NUMBER(10,2) NOT NULL
)
PARTITION BY RANGE (time_id)
(PARTITION sales_q1_2017 VALUES LESS THAN (TO_DATE('01-APR-2017','dd-MON-yyyy')),
PARTITION sales_q2_2017 VALUES LESS THAN (TO_DATE('01-JUL-2017','dd-MON-yyyy')),
PARTITION sales_q3_2017 VALUES LESS THAN (TO_DATE('01-OCT-2017','dd-MON-yyyy')),
PARTITION sales_q4_2017 VALUES LESS THAN (TO_DATE('01-JAN-2018','dd-MON-yyyy'))
);
CREATE INDEX i1_cust_id_indx ON mod_sales_partitioning (cust_id) LOCAL;
CREATE INDEX i2_time_id_indx ON mod_sales_partitioning (time_id);
CREATE INDEX i3_prod_id_indx ON mod_sales_partitioning (prod_id);
SELECT TABLE_NAME, PARTITIONING_TYPE FROM USER_PART_TABLES WHERE TABLE_NAME ='MOD_SALES_PARTITIONING';
TABLE_NAME PARTITION_NAME
------------------------- --------------
MOD_SALES_PARTITIONING RANGE
SELECT TABLE_NAME, PARTITION_NAME FROM USER_TAB_PARTITIONS WHERE TABLE_NAME ='MOD_SALES_PARTITIONING';
TABLE_NAME PARTITION_NAME
------------------------- --------------
MOD_SALES_PARTITIONING SALES_Q1_2017
MOD_SALES_PARTITIONING SALES_Q2_2017
MOD_SALES_PARTITIONING SALES_Q3_2017
MOD_SALES_PARTITIONING SALES_Q4_2017
...
ALTER TABLE mod_sales_partitioning
MODIFY
PARTITION BY RANGE (time_id) SUBPARTITION BY HASH (cust_id)
SUBPARTITIONS 8
( PARTITION sales_q1_2017 VALUES LESS THAN (TO_DATE('01-APR-2017','dd-MON-yyyy')),
PARTITION sales_q2_2017 VALUES LESS THAN (TO_DATE('01-JUL-2017','dd-MON-yyyy')),
PARTITION sales_q3_2017 VALUES LESS THAN (TO_DATE('01-OCT-2017','dd-MON-yyyy')),
PARTITION sales_q4_2017 VALUES LESS THAN (TO_DATE('01-JAN-2018','dd-MON-yyyy')))
ONLINE
UPDATE INDEXES
( i1_cust_id_indx LOCAL,
i2_time_id_indx GLOBAL PARTITION BY RANGE (time_id)
(PARTITION ip1_indx VALUES LESS THAN (MAXVALUE) ) );
SELECT TABLE_NAME, PARTITIONING_TYPE, SUBPARTITIONING_TYPE FROM USER_PART_TABLES WHERE TABLE_NAME ='MOD_SALES_PARTITIONING';
TABLE_NAME PARTITION SUBPARTIT
--------------------------- -------------- ----------
MOD_SALES_PARTITIONING RANGE HASH
SELECT TABLE_NAME, PARTITION_NAME, SUBPARTITION_NAME FROM USER_TAB_SUBPARTITIONS WHERE TABLE_NAME ='MOD_SALES_PARTITIONING';
TABLE_NAME PARTITION_NAME SUBPARTITION_NAME
--------------------------- ------------------ ------------------
MOD_SALES_PARTITIONING SALES_Q1_2017 SYS_SUBP567
MOD_SALES_PARTITIONING SALES_Q1_2017 SYS_SUBP568
MOD_SALES_PARTITIONING SALES_Q1_2017 SYS_SUBP569
MOD_SALES_PARTITIONING SALES_Q1_2017 SYS_SUBP570
...
全文完,希望可以帮到正在阅读的你,如果觉得此文对你有帮助,可以分享给你身边的朋友,同事,你关心谁就分享给谁,一起学习共同进步~~~
欢迎关注我的公众号【JiekeXu DBA之路】,第一时间一起学习新知识!
————————————————————————————
公众号:JiekeXu DBA之路
CSDN :https://blog.csdn.net/JiekeXu
墨天轮:https://www.modb.pro/u/4347
腾讯云:https://cloud.tencent.com/developer/user/5645107
————————————————————————————