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.

MySQL replace语句

MySQL replace语法

REPLACE [LOW_PRIORITY | DELAYED]
[INTO] tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[(col_name [, col_name] ...)]
{VALUES | VALUE} (value_list) [, (value_list)] ...
REPLACE [LOW_PRIORITY | DELAYED]
[INTO] tbl_name
[PARTITION (partition_name [, partition_name] ...)]
SET assignment_list
REPLACE [LOW_PRIORITY | DELAYED]
[INTO] tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[(col_name [, col_name] ...)]
SELECT ...
value:
{expr | DEFAULT}
value_list:
value [, value] ...
assignment:
col_name = value
assignment_list:
assignment [, assignment] ...

REPLACE的工作方式与INSERT完全相同,不同的是,如果表中的旧行与PRIMARY KEY或UNIQUE索引中的新行具有相同的值,则在插入新行之前删除旧行。

REPLACE是MySQL对SQL标准的扩展。它要么插入,要么删除和插入。

DELAYED插入和替换在MySQL 5.6中已被弃用。MySQL 5.7不支持DELAYED。服务器识别但忽略DELAYED关键字,将替换作为非延迟替换处理,并生成er_warn_legacy_syntax_convert警告。(不再支持REPLACE DELAYED。语句被转换为REPLACE。)DELAYED关键字将在未来的版本中被删除。

只有当一个表有一个主键或唯一索引时,REPLACE才有意义。否则,它将等价于INSERT,因为没有索引可用于确定新行是否与另一行重复。

所有列的值都取自REPLACE语句中指定的值。所有缺失的列都被设置为默认值,就像INSERT一样。不能引用当前行的值并在新行中使用它们。如果使用诸如SET col_name = col_name + 1这样的赋值,对右边列名的引用将被视为DEFAULT(col_name),因此赋值等价于

SET col_name = DEFAULT(col_name) + 1。

要使用REPLACE,必须同时拥有表的INSERT和DELETE特权。

如果显式替换生成的列,则唯一允许的值是DEFAULT

REPLACE支持显式分区选择,使用partition关键字和分区、子分区或两者的相对名称列表。与INSERT一样,如果不可能将新行插入到任何这些分区或子分区中,则REPLACE语句将失败,并出现Found a row not matching the given partition set错误。

REPLACE语句返回一个计数,以指示受影响的行数。这是删除和插入的行之和。如果对于单行REPLACE计数为1,则插入一行,不删除任何行。如果计数大于1,则在插入新行之前删除一个或多个旧行。如果表包含多个唯一索引,并且新行在不同唯一索引中重复不同旧行的值,则单个行可以替换多个旧行。

受影响的行数可以很容易地确定REPLACE是只添加了一行,还是也替换了任何行:检查计数是否为1(添加)或更大(替换)。

如果您使用的是C API,受影响的行数可以通过mysql_affected_rows()函数获得。

您不能在子查询中替换一个表并从同一表中进行选择

MySQL对于replace(和load data … replace)使用如下算法:
1.尝试将新行插入到表中
2.当因为主键或唯一索引出现重复键错误而插入失败时:
a.从表中删除具有重复键值的冲突行
b.请再次将新行插入表中

在出现重复键错误的情况下,存储引擎可能会将REPLACE作为更新而不是删除加插入来执行,但语义是相同的。除了存储引擎增加Handler_xxx状态变量的方式不同之外,没有用户可见的影响

因为REPLACE …SELECT语句的结果依赖于SELECT语句中的行顺序,并且这种顺序不能总是得到保证,当记录这些语句时,主服务器和从服务器可能出现分歧。基于这个理由,replace … select语句对于基于语句的复制来说被标记为不安全。当使用基于语句的模式时,这些语句会在错误日志中产生一个警告,而当使用MIXED模式时,这些语句会使用基于行的格式写入二进制日志。

当修改没有分区的现有表以适应分区时,或者在修改已分区表的分区时,可以考虑修改表的主键(参见22.6.1节,分区键、主键和唯一键)。您应该注意,如果这样做,REPLACE语句的结果可能会受到影响,就像修改非分区表的主键一样。考虑下面的CREATE table语句创建的表:

CREATE TABLE test (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
data VARCHAR(64) DEFAULT NULL,
ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id)
);

当我们创建这个表并运行mysql客户机中显示的语句时,结果如下所示:

mysql> REPLACE INTO test VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.03 sec)

mysql> REPLACE INTO test VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 2 rows affected (0.10 sec)

mysql> SELECT * FROM test;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
1 row in set (0.01 sec)

现在我们创建第二个表,与第一个表几乎相同,除了主键现在是包含2列的复合主键,如下所示(强调文本):

CREATE TABLE test2 (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
data VARCHAR(64) DEFAULT NULL,
ts TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id, ts)
);

当我们在test2上运行与在原始测试表上相同的两个REPLACE语句时,我们得到了不同的结果:

mysql> REPLACE INTO test2 VALUES (1, 'Old', '2014-08-20 18:47:00');
Query OK, 1 row affected (0.06 sec)

mysql> REPLACE INTO test2 VALUES (1, 'New', '2014-08-20 18:47:42');
Query OK, 1 row affected (0.01 sec)

mysql> SELECT * FROM test2;
+----+------+---------------------+
| id | data | ts                  |
+----+------+---------------------+
|  1 | Old  | 2014-08-20 18:47:00 |
|  1 | New  | 2014-08-20 18:47:42 |
+----+------+---------------------+
2 rows in set (0.01 sec)

这是因为,当运行test2时,id和ts列值必须与现有行的值匹配,以便替换该行;否则,插入一行。

使用MyISAM等存储引擎(使用表级锁)的REPLACE语句影响分区表,只要不更新表分区列,则只锁那些包含匹配REPLACE语句WHERE子句的行的分区;否则锁定整个表。(对于像InnoDB这样使用行级锁的存储引擎,不会发生分区锁。)

MySQL load data加载数据

load data 加载数据
load data infile语法如下:

LOAD DATA [LOW_PRIORITY | CONCURRENT] [LOCAL] INFILE 'file_name'
[REPLACE | IGNORE]
INTO TABLE tbl_name
[PARTITION (partition_name [, partition_name] ...)]
[CHARACTER SET charset_name]
[{FIELDS | COLUMNS}
[TERMINATED BY 'string']
[[OPTIONALLY] ENCLOSED BY 'char']
[ESCAPED BY 'char']
]
[LINES
[STARTING BY 'string']
[TERMINATED BY 'string']
]
[IGNORE number {LINES | ROWS}]
[(col_name_or_user_var
[, col_name_or_user_var] ...)]
[SET col_name={expr | DEFAULT},
[, col_name={expr | DEFAULT}] ...]


load data infile语句从文本文件中读取数据加载到数据表中有非常高的效率。为了将数据从表中写入文本文件可以使用select … into outfile,为了将数据从文本文件加载回数据表,使用load data infile语句。对于这两种语句fields与lines子句是相同的。这两个子句是可选的,如果两个子句被指定那么fields必须在lines的前面。

也可以使用mysqlimport工具来加载数据文件,它是通过发送oad data infile语句给服务器来进行操作。mysqlimport的–local选项会导致mysqlimport从客户端主机上读取数据文件。如果客户端和服务器支持压缩协议使用–compress选项将得到更好的性能。

文件名必须以字面值字符串的形式给出。在Windows上,在路径名中指定反斜杠为正斜杠或双反斜杠。character_set_filesystem系统变量控制文件名的解释。

LOAD DATA支持使用带有一个或多个以逗号分隔的分区、子分区或是同时指定分区与子分区的名称列表的partition选项进行显式分区选择。使用此选项时,如果文件中的任何行不能插入到列表中指定的任何分区或子分区中,则语句会失败,错误为Found a row not matching the给定的分区集。

对于使用MyISAM等使用表锁的存储引擎的分区表,LOAD DATA不能删除任何分区锁。这不适用于使用行级锁的存储引擎的表,比如InnoDB

服务器使用由character_set_database系统变量指示的字符集来解释文件中的信息。SET NAMES和character_set_client的设置不会影响输入的解释。如果输入文件的内容使用与默认不同的字符集,通常最好使用character set子句指定文件的字符集。二进制字符集指定不转换。

LOAD DATA INFILE将文件中的所有字段解释为具有相同的字符集,而不考虑字段值加载到的列的数据类型。为了正确解释文件内容,您必须确保它是用正确的字符集编写的。例如,如果你写一个数据文件使用mysqldump -T或者在mysql中发出SELECT…INTO OUTFILE语句,一定要使用–default-character-set选项输出时所使用的字符集在当文件被LOAD DATA INFILE加载时将要使用。

如果使用LOW_PRIORITY, LOAD DATA语句的执行将被延迟,直到没有其他客户端从表中读取数据。这只会影响仅使用表级锁的存储引擎(如MyISAM、memory和merge)。

如果MyISAM表指定CONCURRENT来满足并发插入条件的(即,它中间不包含空闲块),那么在执行LOAD DATA时,其他线程可以从表中检索数据。即使没有其他线程同时使用这个表,这个选项也会略微影响LOAD DATA的性能。

使用基于行的复制,无论MySQL版本如何,都可以并发复制。使用基于语句的复制,在MySQL 5.5.1之前不会执行并发复制(见Bug #34628)。

LOCAL关键字影响文件的预期位置和错误处理,如后面所述。只有当服务器和客户机都配置为允许LOCAL时,LOCAL才能工作。例如,如果mysqld在启动时禁用了local_infile系统变量,那么LOCAL就不起作用

local关键字的影响期望在文件中的何处被找到:
.如果local关键字被指定,通过客户端主机上的客户端程序来读取文件并发送给服务器。这个文件可以被指定完全路径名来指定精确位置。如果指定相对路径名,这将会解析成启动客户端程序目录的相对路径。

当使用load data local时,在服务器的临时目录中会创建一个文件副本。这不是由tmpdir或slave_load_tmpdir的值决定的目录,而是操作系统的临时目录,并且在MySQL服务器中不能配置(通常系统临时目录在linux系统中是/tmp,在windows中是c:\windows\temp)。如果临时目录没有足够的空间可能会造成load data local语句失败。

.如果local关键字没有指定,那么数据文件必须存储在服务器上并且服务器可以直接读取。服务器使用以下规则来定位文件:

.如果文件名是绝对路径名,服务器将按照给定的方式使用它。

.如果文件名是包含一个或多个前导组件的相对路径名,服务器将相对于服务器的数据目录搜索该文件。

.如果文件名中没有给出前导组件,服务器将在默认数据库的数据库目录中查找该文件。

在非local情况下,这些规则意味着从服务器的数据目录中读取名为./myfile.txt的文件,而从默认数据库的数据库目录中读取名为myfile.txt的文件。例如,如果db1是默认数据库,那么下面的LOAD DATA语句将从db1的数据库目录中读取文件data.txt,即使该语句显式地将文件加载到db2数据库中的一个表中:

LOAD DATA INFILE 'data.txt' INTO TABLE db2.my_table;

非local加载操作读取位于服务器上的文本文件。出于安全原因,这些操作要求您拥有FILE特权。非local加载操作受secure_file_priv系统变量设置的影响。如果变量值是非空目录名,则要加载的文件必须位于该目录中。如果变量值为空(不安全),则该文件只需要由服务器读取。

使用LOCAL比让服务器直接访问文件要慢一些,因为文件的内容必须通过客户机连接发送到服务器。另一方面,您不需要FILE特权来加载本地文件。

local也会影响错误的处理:
.使用load data infile,数据解释和重复键错误终止操作。
.使用load data local infile 数据解释和重复键错误成为警告,操作继续进行,因为服务器没有办法在操作过程中停止文件传输。对于重复键错误,这就相当于指定了IGNORE。

REPLACE和IGNORE关键字控制对在唯一键值上存在与现有行有重复的输入行的处理:
.如果指定replace,输入行将替换存在行。换句话说,与现有行的主键或唯一索引有相同的值。

.如果指定ignore,与现有行的唯一键值重复的行会被丢弃。

.如果没有指定这些选项,那么依据是否指定了local来决定。在没有指定local时,当找到重复键值时会报错且文件中剩余的内容会被忽略。当指定local时,默认的行为与指定了ignore是一样的,这是因为服务器不能阻止正在执行的文件传输操作。

为了在加载操作时忽略外键约束,可以在执行load data之前执行set foreign_key_checks=0语句。

如果对一个MyISAM空表执行load data infile操作,那么所有非唯一索引将在单独的一个批处理中创建(类似于repair table)。通常来说,当有许多索引的情况下这将使load data infile操作更快。在一些极端的情况下,在加载数据文件之前可以执行alter table … disable keys来禁用索引,在加载数据文件之后执行alter table .. enable kyes来重建索引这要比创建索引效率更高。

对于load data infile和select … into outfile语句来说fiels和lines子句的语法是相同的。这些子句是可选项,但如果都被指定的话fields必须在lines的前面。

如果指定fields子句,它的每一个子句(terminated by,[optionally] enclosed by和escaped by)也是可选项,除非你必须至少指定一个。

如果没有指定fields或lines子句,默认就和下面所写的一样:

FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'
LINES TERMINATED BY '\n' STARTING BY ''

反斜杠是SQL语句中字符串中的MySQL转义字符,因此要指定一个字面值的反斜杠,您必须指定两个反斜杠才能将值解释为单个反斜杠。转义序列’\t’和’\n’分别指定制表符和换行符

换句话说,在读取输入时,默认值导致LOAD DATA INFILE执行如下操作:
.在换行处查看行边界。
.不会跳过任何行前缀
.在制表符中将行拆分为字段
.不要期望字段用引号括起来
.将前面有转义字符\的字符解释为转义序列。例如,“\t”、“\n”、“\\”分别表示制表符、换行符、反斜杠

相反,默认值会导致select … into outfile执行如下操作
.在字段之间写制表符
.要用引号括起字段
.使用\转义字段值中出现的制表符、换行符或\实例
.在行尾写换行

如果您已经在Windows系统上生成了文本文件,您可能必须使用LINES TERMINATED BY ‘\r\n’来正确读取该文件,因为Windows程序通常使用两个字符作为行结束符。有些程序,如写字板,在写文件时可能使用\r作为行结束符。要读取这样的文件,请使用以’\r’结尾的行。

如果您想要读入的所有行都有一个您想要忽略的公共前缀,您可以使用LINES STARTING BY ‘prefix_string’来跳过该前缀和它之前的任何内容。如果某一行不包含前缀,则跳过整行。假设您发出以下语句:

load data infile '/tmp/test.txt' into table test fields terminated by ',' lines starting by 'xxx';

如果数据文件内容类似如下:

xxx"abc",1
something xxx"def",2
"ghi",3

上面数据文件执行加载后行数将是(“abc”,1)和(“def”,2)。第三行将会被跳过因为它不包含前缀。

ignore number lines选项可以用来忽略文件开头的行。例如,可以使用ignore 1 lines来跳过包含列名的首标题行:

load data infile '/tmp/test.txt' into table test ignore 1 lines;

当你使用SELECT…INTO OUTFILE与LOAD DATA INFILE一起将数据从数据库写入文件,然后稍后将文件读回数据库,这两个语句的字段和行处理选项必须匹配。否则,LOAD DATA INFILE将不能正确解释文件的内容。假设你使用SELECT…写入一个以逗号分隔的字段的文件:

select * into outfile 'data.txt' fields terminated by ',' from table2;

要将逗号分隔的文件读入,正确的语句应该是:

load data infile 'data.txt' into table table2 fields terminated by ',';

如果您尝试使用下面所示的语句读取文件,则不会工作,因为它指示LOAD DATA INFILE查找字段之间的制表符:

load data infile 'data.txt' into table table2 fields terminated by '\t';

可能的结果是,每个输入行将被解释为单个字段。

LOAD DATA INFILE可用于读取从外部来源获得的文件。例如,许多程序可以以逗号分隔值(CSV)格式导出数据,例如,行中有用逗号分隔的字段,并用双引号括起来,并使用列名的首行。如果这样一个文件中的行以回车/换行对结束,这里显示的语句说明了用于加载文件的字段和行处理选项。

LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name
FIELDS TERMINATED BY ',' ENCLOSED BY '"'
LINES TERMINATED BY '\r\n'
IGNORE 1 LINES;

如果输入值不一定用引号括起来,请在enclosed BY关键字前使用optionally。

任何字段处理或行处理选项都可以指定一个空字符串(“)。如果不为空,则FIELDS[OPTIONALLY] ENCLOSEDBY和FIELDS ESCAPED BY值必须是单个字符。FIELDS TERMINATED BY、LINES started BY和LINES TERMINATED BY值可以多于一个字符。例如,要写以回车/换行对结尾的行,或读取包含此类行的文件,请指定lines terminated by ‘\r\n’子句。

要读取包含由%%作为行分隔符的的文件,您可以这样做

CREATE TABLE jokes
(a INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
joke TEXT NOT NULL);
LOAD DATA INFILE '/tmp/jokes.txt' INTO TABLE jokes
FIELDS TERMINATED BY ''
LINES TERMINATED BY '\n%%\n' (joke);
< ?pre>
fields [optionally] enclosed by控制字段的引用。对于(select ... into outfile)输出,如果你忽略了关键字optionally,所有的字段都包含在enclosed by字符包含着。
这里显示了这样的输出示例(使用逗号作为字段分隔符):
"1","a string","100.20"
"2","a string containing a , comma","102.20"
"3","a string containing a \" quote","102.20"
"4","a string containing a \", quote and comma","102.20"

如果你指定optionally,那么enclosed by字符只用来封装字符串数据类型的值(比如char,binary,text或enum):

1,"a string",100.20
2,"a string containing a , comma",102.20
3,"a string containing a \" quote",102.20
4,"a string containing a \", quote and comma",102.20

字段值中出现的enclosed by字符将通过在它们前面加上escaped by字符进行转义。此外,如果您指定了一个空的escaped by值,可能会无意中生成无法被LOAD DATA INFILE正确读取的输出。例如,如果转义字符为空,前面显示的输出将如下所示。注意,第四行第二个字段包含引号后面的逗号,这(错误地)似乎是结束该字段:

1,"a string",100.20
2,"a string containing a , comma",102.20
3,"a string containing a " quote",102.20
4,"a string containing a ", quote and comma",102.20

对于输入,如果存在enclosed by 字符,则从字段值的末尾删除。(无论是否指定了optionally,这都是正确的;optionally对输入解释没有影响。)出现在enclosed by字符前的escaped by字符将被解释为当前字段值的一部分。

如果字段以enclosed by字符开头,则该字符的实例只有在后跟字段或行terminated by序列时才会被识别为终止字段值。为了避免歧义,在字段值中出现enclosed by字符的次数可以加倍,并被解释为该字符的单个实例。例如,如果指定了enclosed by ‘”‘则会像这里所示处理引号:

"The ""BIG"" boss" -> The "BIG" boss
The "BIG" boss -> The "BIG" boss
The ""BIG"" boss -> The ""BIG"" boss

fields escaped by控制如何读取或写入特殊字符
.对于输入,如果fields escaped by字符不为空,则剥离出现的该字符,并按照字面意思将下面的字符作为字段值的一部分。一些双字符序列是例外,其中第一个字符是转义字符。这些序列如下表所示(转义字符使用\)。本节稍后将描述NULL处理规则。

如果fields escaped by字符为空,则不会发生转义序列解释

.对于输出,如果fields escaped by字符不为空,则它用于在输出中作为以下字符的前缀

 .fields escaped by字符
 .fields [optionally] enclosed by字符
 .fields terminated by和lines terminated by值的第一个字符
 .ASCII 0(转义字符后面实际写的是ASCII 0,而不是零值字节)

如果fields escaped by字符为空,则不转义任何字符,NULL输出为NULL,而不是\N。指定空转义字符可能不是一个好主意,特别是如果数据中的字段值包含刚才给出的列表中的任何字符。

在某些情况下,字段和行处理选项相互作用:
.如果LINES TERMINATED BY为空字符串而FIELDS TERMINATED BY为非空字符串,则行也会以FIELDS TERMINATED BY结束。

.如果FIELDS TERMINATED BY和FIELDS ENCLOSED BY值都为空(“),则使用固定行(非分隔)格式。使用固定行格式,字段之间不使用分隔符(但仍然可以使用行结束符)。相反,读写列值时使用足够宽的字段宽度来容纳字段中的所有值。对于TINYINT、SMALLINT、MEDIUMINT、INT和BIGINT,无论声明的显示宽度是多少,字段宽度分别为4、6、8、11和20。

lines terminated by仍然用于分隔行。如果一行不包含所有字段,则将其余列设置为其默认值。如果你没有行结束符,你应该把它设置为”。在这种情况下,文本文件必须包含每一行的所有字段。

固定行格式也影响NULL值的处理,如后面所述

NULL值的处理根据所使用的FIELDS和LINES选项而不同:
.对于默认的FIELDS和LINES值,NULL被写为输出的\N字段值,而\N字段值被读为输入的NULL(假设escaped by字符是\)。
.如果FIELDS ENCLOSED BY不为空,则将包含字面值NULL的字段读取为NULL值。这不同于在fields enclosed by字符中包含的单词NULL,它被读为字符串’NULL’。
.如果fields escaped by为空,则NULL被写成单词NULL。
.使用固定行格式(当FIELDS TERMINATED BY和FIELDS ENCLOSED BY都为空时使用),NULL被写成空字符串。这将导致表中的NULL值和空字符串在写入文件时无法区分,因为两者都是作为空字符串写入的。如果需要在重新读入文件时区分这两者,那么不应该使用固定行格式。

尝试将NULL加载到NOT NULL列会导致为列的数据类型分配隐式默认值,并出现警告,或者在严格的SQL模式下出现错误。

不被load data infile所支持的情况:
.固定大小的行(fields terminated by和fields enclosed by都是空的)和BLOB或TEXT列
.如果指定一个分隔符与另一个分隔符或前缀相同,则LOAD DATA INFILE无法正确解释输入。例如,下面的FIELDS子句会导致问题:FIELDS TERMINATED BY ‘”‘ ENCLOSED BY ‘”‘

如果fields escaped by为空,则包含FIELDS ENCLOSED BY或LINES TERMINATED BY后跟FIELDS TERMINATED BY的字段值将导致LOAD DATA INFILE过早停止读取字段或行。这是因为LOAD DATA INFILE不能正确地确定字段或行值的结束位置。

下面的示例加载persondata表的所有列:

LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;

默认情况下,当LOAD DATA INFILE语句末尾没有提供字段列表时,输入行将包含每个表的所有字段。如果只想加载表的部分列,请指定字段列表:

LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata (col1,col2,...);

如果输入文件中字段的顺序与表中列的顺序不同,还必须指定字段列表。否则,MySQL无法判断如何将输入字段与表列匹配。

列列表可以包含列名或用户变量。对于用户变量,SET子句允许您在将结果分配给列之前对其值执行转换.

SET子句中的用户变量有几种用法。下面的示例将第一个输入列直接用于t1.column1的值,并将第二个输入列赋值给一个用户变量,该变量在用于t1.column2的值之前进行除法操作

LOAD DATA INFILE 'file.txt'
INTO TABLE t1
(column1, @var1)
SET column2 = @var1/100;

SET子句可用于提供非从输入文件派生的值。下面的语句将column3设置为当前日期和时间

LOAD DATA INFILE 'file.txt'
INTO TABLE t1
(column1, column2)
SET column3 = CURRENT_TIMESTAMP;

可以通过指定用户变量且不将变量指定到表列来放弃输入值:

LOAD DATA INFILE 'file.txt'
INTO TABLE t1
(column1, @dummy, column2, @dummy, column3);

列/变量列表和SET子句的使用受以下限制:
.SET子句中的赋值操作符应该只有列名在赋值操作符的左边。
.你可以在SET赋值的右边使用子查询。返回要分配给列的值的子查询只能是标量子查询。此外,也不能使用子查询从正在加载的表中进行选择
.对于列/变量列表或SET子句,不处理被IGNORE子句忽略的行
.当以固定行格式加载数据时,不能使用用户变量,因为用户变量没有显示宽度

在处理输入行时,LOAD DATA将其分割为字段,并根据列/变量列表和SET子句(如果存在的话)使用这些值。然后将生成的行插入到表中。如果表中有BEFORE INSERT或AFTER INSERT触发器,则分别在插入行之前或之后激活它们。

如果一个输入行有太多的字段,额外的字段将被忽略,警告的数量将增加

如果输入行字段太少,则将缺少输入字段的表列设置为默认值。

对空字段值的解释与缺失字段不同:
.对于字符串类型,列被设置为空字符串
.对于数字类型,列被设置为0
.对于日期和时间类型,该列被设置为该类型的适当零值

如果在INSERT或UPDATE语句中显式地将空字符串赋给字符串、数字类型或日期或时间类型,则会得到相同的值

如果SQL模式被设置为限制值,那么空字段值或不正确字段值的处理与刚才描述的不同。例如,如果sql_mode设置为traditional,对于数字列转换空值或值(如’x’)将导致错误,而不是转换为0。(对于LOCAL或IGNORE,即使使用限制性sql_mode值,也会出现警告而不是错误,并且使用与非限制性SQL模式相同的最接近值行为插入行。这是因为服务器没有办法在操作过程中停止文件的传输。)

只有TIMESTAMP列列值为NULL和列没有声明为允许NULL值或者如果TIMESTAMP列的默认值是当前的时间戳,并且在指定字段列表时从字段列表中省略它时,TIMESTAMP列会被设置为当前日期和时间。

LOAD DATA INFILE将所有输入视为字符串,所以不能像INSERT语句那样对ENUM或SET列使用数值。所有的ENUM和SET值必须指定为字符串。BIT值不能使用二进制表示法直接加载(例如,b’011010′)。为了解决这个问题,使用SET子句去掉前导b’和末尾b’,并执行base-2到base-10的转换,以便MySQL正确地将值加载到BIT列中:

[mysql@localhost ~]$ cat /var/lib/mysql/bit_test.txt
b'10'
b'1111111'

mysql> create table bit_test(b bit(10));
Query OK, 0 rows affected (0.10 sec)


mysql> load data infile '/var/lib/mysql/bit_test.txt'
    -> into table bit_test(@var1)
    -> set b=cast(conv(mid(@var1,3,length(@var1)-3),2,10) as unsigned);
Query OK, 2 rows affected (0.15 sec)
Records: 2  Deleted: 0  Skipped: 0  Warnings: 0


mysql> select bin(b+0) from bit_test;
+----------+
| bin(b+0) |
+----------+
| 10       |
| 1111111  |
+----------+
2 rows in set (0.00 sec)

对于0b二进制表示法中的BIT值(例如0b011010),使用这个SET子句来去掉前导的0b:

SET b = CAST(CONV(MID(@var1, 3, LENGTH(@var1)-2), 2, 10) AS UNSIGNED)

在Unix上,如果需要LOAD DATA从管道读取数据,可以使用以下技术(示例将/目录的清单加载到表db1.t1中):

mkfifo /mysql/data/db1/ls.dat
chmod 666 /mysql/data/db1/ls.dat
find / -ls > /mysql/data/db1/ls.dat &
mysql -e "LOAD DATA INFILE 'ls.dat' INTO TABLE t1" db1

在这里,您必须在单独的终端上运行生成要加载的数据的命令和mysql命令,或者在后台运行数据生成过程(如前面的示例所示)。如果您不这样做,管道将阻塞,直到数据被mysql进程读取。

当LOAD DATA INFILE语句完成时,它将返回如下格式的信息字符串

Records: 1 Deleted: 0 Skipped: 0 Warnings: 0

Windows 使用VSCode远程连接到Linux开发调试MySQL

Windows 使用VSCode远程连接到Linux开发调试MySQL

1.Linux系统上安装相关开发工具

[root@gbase yum.repos.d]# yum install gdb-gdbserver

[root@gbase yum.repos.d]# yum install gdb

[root@gbase yum.repos.d]# yum install gcc

[root@gbase yum.repos.d]# yum install cmake

2.配置VSCode可以免密登录Linux

2.1在Windows上生成密钥

C:\Users\Administrator>ssh-keygen -t rsa

Generating public/private rsa key pair.

Enter file in which to save the key (C:\Users\Administrator\.ssh\id_rsa):

Enter passphrase (empty for no passphrase):

Enter same passphrase again:

Your identification has been saved in id_rsa.

Your public key has been saved in id_ras.pub.

The key fingerprint is:

SHA256:2ya72QX0JQBxKTLM+3S1H3FFYnHHrve1t0cSbqXJiqI mysql@gbase

The key’s randomart image is:

+—[RSA 2048]—-+

| o ooo. ++*|

| = …….o+|

| + ……+ |

| . …..oo o|

| oS.. .+ B |

| .o . X +|

| o o..o ++|

| .*… .+|

| E.+o. .+|

+—-[SHA256]—–+

2.2 在Linux服务器上生成密钥

[root@gbase ~]# su – mysql

Last login: Sun Sep 26 09:24:11 CST 2021 on pts/5

[mysql@gbase ~]$ pwd

/home/mysql

[mysql@gbase ~]$ ls -lrt

total 0

drwxrwxr-x. 2 mysql mysql 6 Sep 24 16:19 perl5

[mysql@gbase ~]$ cd ~/.ssh

-bash: cd: /home/mysql/.ssh: No such file or directory

[mysql@gbase ~]$ mkdir ~/.ssh

[mysql@gbase ~]$ cd ~/.ssh

[mysql@gbase .ssh]$ pwd

/home/mysql/.ssh

[mysql@gbase .ssh]$ ls -lrt

total 0

增加root权限:visudo 进入文本后找到root ALL=(ALL) ALL,另起一行,加入admin ALL=(ALL) NOPASSWD:ALL su admin 切换到新用户 再使

用sudo su -切换回root,说明权限正常,进行下一步

[root@gbase ~]# visudo

## Allow root to run any commands anywhere

root ALL=(ALL) ALL

mysql ALL=(ALL) NOPASSWD:ALL

[mysql@gbase ~]$ sudo su –

Last login: Sun Sep 26 11:41:38 CST 2021 on pts/1

[root@gbase ~]# su – mysql

Last login: Sun Sep 26 14:20:50 CST 2021 from 192.168.1.12 on pts/3

[mysql@gbase ~]$

2.3将windows中生成的公钥上传到/home/mysql/.ssh/目录

C:\Users\Administrator>scp C:\Users\Administrator\.ssh\id_rsa.pud mysql@192.168.1.249:/home/mysql/.ssh/authorized_keys

[mysql@gbase ~]$ chmod 700 /home/mysql/.ssh

[mysql@gbase ~]$ chmod 600 /home/mysql/.ssh/authorized_keys

2.4切换到root,关闭root登录 sudo su – vim /etc/ssh/sshd_config 找到#PermitRootLogin yes去掉#把yes改为no systemctl restart sshd 重启服务并生效

[root@gbase .ssh]# vim /etc/ssh/sshd_config

# $OpenBSD: sshd_config,v 1.100 2016/08/15 12:32:04 naddy Exp $

# This is the sshd server system-wide configuration file. See

# sshd_config(5) for more information.

# This sshd was compiled with PATH=/usr/local/bin:/usr/bin

# The strategy used for options in the default sshd_config shipped with

# OpenSSH is to specify options with their default value where

# possible, but leave them commented. Uncommented options override the

# default value.

# If you want to change the port on a SELinux system, you have to tell

# SELinux about this change.

# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER

#

Port 22

#AddressFamily any

#ListenAddress 0.0.0.0

#ListenAddress ::

HostKey /etc/ssh/ssh_host_rsa_key

#HostKey /etc/ssh/ssh_host_dsa_key

HostKey /etc/ssh/ssh_host_ecdsa_key

HostKey /etc/ssh/ssh_host_ed25519_key

# Ciphers and keying

#RekeyLimit default none

# Logging

#SyslogFacility AUTH

SyslogFacility AUTHPRIV

#LogLevel INFO

# Authentication:

#LoginGraceTime 2m

PermitRootLogin no #改成no

#StrictModes yes

#MaxAuthTries 6

#MaxSessions 10

RSAAuthentication yes #要开启

PubkeyAuthentication yes #要开启

# The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2

# but this is overridden so installations will only check .ssh/authorized_keys

AuthorizedKeysFile .ssh/authorized_keys

[root@gbase ~]# service sshd restart

Redirecting to /bin/systemctl restart sshd.service

在windows中测试ssh登录

C:\Users\Administrator>ssh mysql@192.168.1.249

Last login: Sun Sep 26 14:22:54 2021

]ysql@gbase:~[mysql@gbase ~]$ pwd

/home/mysql

2.5 配置vscode通过remote ssh连接Linux的配置文件C:\Users\Administrator\.ssh\config

Host 192.168.1.249

HostName 192.168.1.249

User root

IdentityFile “D:\ssh\vscode”

2.6 通过vscode远程连接Linux服务器出现以下错误

> Waiting for client to transfer server archive…

> Waiting for /home/mysql/.vscode-server/bin/7f6ab5485bbc008386c4386d08766667e1552

> 44e/vscode-scp-done.flag and vscode-server.tar.gz to exist

>

[12:31:20.267] Got request to download on client for {“platform”:”linux”,”arch”:”x64″,”destFolder”:”/home/mysql/.vscode-server/bin/7f6ab5485bbc008386c4386d08766667e155244e”}

[12:31:20.268] Downloading VS Code server locally…

[12:31:20.420] Resolver error: Error: Running the contributed command: ‘_workbench.downloadResource’ failed.

[mysql@gbase /]$ cd /home/mysql

[mysql@gbase ~]$ ls -lrt .vscode-server

total 0

drwxrwxr-x. 3 mysql mysql 54 Sep 26 09:46 bin

[mysql@gbase ~]$ cd .vscode-server

[mysql@gbase .vscode-server]$ ls

bin

[mysql@gbase .vscode-server]$ cd bin

[mysql@gbase bin]$ ls

7f6ab5485bbc008386c4386d08766667e155244e

[mysql@gbase bin]$ cd 7f6ab5485bbc008386c4386d08766667e155244e/

[mysql@gbase 7f6ab5485bbc008386c4386d08766667e155244e]$ ls

vscode-remote-lock.mysql.7f6ab5485bbc008386c4386d08766667e155244e vscode-server.tar.gz

[mysql@gbase 7f6ab5485bbc008386c4386d08766667e155244e]$ ls -lrt

total 0

-rw-rw-r–. 1 mysql mysql 0 Sep 26 11:37 vscode-remote-lock.mysql.7f6ab5485bbc008386c4386d08766667e155244e

-rw-rw-r–. 1 mysql mysql 0 Sep 26 11:37 vscode-server.tar.gz

上面的7f开头的文件夹称为Commit Id,现在利用Commit ID下载远程连接需要的文件。对于Stabe Version(在VS Code报错的的窗口中Ctrl+F

搜索stable,有则为Stable Version)的Remote SSH插件,如下图,在“输出”窗口中Ctrl+F搜索“stable”。

[12:31:14.904] Using commit id “7f6ab5485bbc008386c4386d08766667e155244e” and quality “stable” for server

然后使用这个链接:https://update.code.visualstudio.com/commit:$COMMIT_ID/server-linux-x64/stable下载所需文件,注意链接中的

$COMMIT_ID这几个字符(注意$不要忘记)需要换成自己的,比如我的是 7f6ab5485bbc008386c4386d08766667e155244e,那么此时我通

过https://update.code.visualstudio.com/commit:7f6ab5485bbc008386c4386d08766667e155244e/server-linux-x64/stable就可以下载到

我需要的文件。

对于Insider版本,

通过https://update.code.visualstudio.com/commit:7f6ab5485bbc008386c4386d08766667e155244e/server-linux-x64/insider这个链接下载相

应文件。

下载完毕后,将下载的文件upload到Remote Server的~/.vscode-server/bin/xxx文件夹下(也可以在Remote Server上直接

执行wget https://vscode.cdn.azure.cn/stable/7f6ab5485bbc008386c4386d08766667e155244e/vscode-server-linux-x64.tar.gz即可下载,

这样就不用进行上传操作了),同时删除其他文件,最后再使用tar -xvf vscode-server-linux-x64.tar.gz –strip-components 1解压文件,

sftp> put D:\ssh\vscode-server-linux-x64.tar.gz

Uploading vscode-server-linux-x64.tar.gz to /home/mysql/vscode-server-linux-x64.tar.gz

100% 45296KB 45296KB/s 00:00:00

D:/ssh/vscode-server-linux-x64.tar.gz: 46383314 bytes transferred in 0 seconds (45296 KB/s)

[mysql@gbase 7f6ab5485bbc008386c4386d08766667e155244e]$ tar -xvf vscode-server-linux-x64.tar.gz –strip-components 1

然后使用chmod +x node server.sh为node和server.sh添加可执行权限。

[mysql@gbase 7f6ab5485bbc008386c4386d08766667e155244e]$ chmod +x node server.sh

[mysql@gbase 7f6ab5485bbc008386c4386d08766667e155244e]$ ls -lrt

total 117512

-rwxr-xr-x. 1 mysql mysql 222 Sep 22 20:00 server.sh

-rw-r–r–. 1 mysql mysql 34147 Sep 22 20:00 product.json

-rw-r–r–. 1 mysql mysql 1255 Sep 22 20:00 package.json

-rw-r–r–. 1 mysql mysql 13380 Sep 22 20:00 LICENSE

-rwxr-xr-x. 1 mysql mysql 73873984 Sep 22 20:02 node

drwxr-xr-x. 3 mysql mysql 135 Sep 22 20:02 out

drwxr-xr-x. 3 mysql mysql 33 Sep 22 20:02 bin

drwxr-xr-x. 32 mysql mysql 4096 Sep 22 20:02 extensions

drwxr-xr-x. 78 mysql mysql 4096 Sep 22 20:02 node_modules

-rw-rw-r–. 1 mysql mysql 0 Sep 26 11:37 vscode-remote-lock.mysql.7f6ab5485bbc008386c4386d08766667e155244e

-rw-rw-r–. 1 mysql mysql 0 Sep 26 11:37 vscode-server.tar.gz

-rw-rw-r–. 1 mysql mysql 46383314 Sep 26 11:57 vscode-server-linux-x64.tar.gz

再次使用VS Code尝试链接,这一步会链接成功。

3.vscode在远程远程服务器上依次安装 C/C++、CMake、CMake Tools插件

在使用vscode 远程调试程序时出现以下信息:

Updating C/C++ dependencies…

Downloading package ‘C/C++ language components (Linux / x86_64)’ Failed. Retrying… Failed. Retrying… Failed. Retrying…Waiting 8 seconds… Failed. Retrying…Waiting 15 seconds… Failed. Retrying…Waiting 15 seconds… Failed. Retrying…Waiting 15 seconds… Failed. Retrying…Waiting 15 seconds… Failed. Retrying…Waiting 15 seconds… Failed. Retrying…Waiting 15 seconds… Failed to download https://go.microsoft.com/fwlink/?linkid=2170969

Failed at stage: downloadPackages

Error: getaddrinfo ENOTFOUND go.microsoft.com

at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:67:26)

If you work in an offline environment or repeatedly see this error, try downloading a version of the extension with all the dependencies pre-included from https://github.com/microsoft/vscode-cpptools/releases, then use the “Install from VSIX” command in VS Code to install it.


安装 C/C++ language components插件失败

我们只能手动安装

打开网址https://go.microsoft.com/fwlink/?linkid=2170969下载bin_linupwd

x.zip文件

将bin_linux.zip文件解压

cpptools

cpptools-srv

LICENSE.txt

将这三个文件拷贝到远程Linux服务器的/home/mysql/.vscode-server/extensions/ms-vscode.cpptools-1.6.0/bin目录中

如果原先存在这个文件的话先将其备份。

sftp> put F:\bin_linux\bin\*

Uploading cpptools to /home/mysql/.vscode-server/extensions/ms-vscode.cpptools-1.6.0/bin/cpptools

100% 19544KB 19544KB/s 00:00:00

F:/bin_linux/bin/cpptools: 20014008 bytes transferred in 0 seconds (19544 KB/s)

Uploading cpptools-srv to /home/mysql/.vscode-server/extensions/ms-vscode.cpptools-1.6.0/bin/cpptools-srv

100% 11508KB 11508KB/s 00:00:00

F:/bin_linux/bin/cpptools-srv: 11784664 bytes transferred in 0 seconds (11508 KB/s)

Uploading LICENSE.txt to /home/mysql/.vscode-server/extensions/ms-vscode.cpptools-1.6.0/bin/LICENSE.txt

100% 11KB 11KB/s 00:00:00

F:/bin_linux/bin/LICENSE.txt: 11972 bytes transferred in 0 seconds (11 KB/s)

但是没有用,仍然报错

如是通过vsix来进行安装

github上release好多个版本,我远程看代码的主机是redhat Linux系统,所有下载cpptools-linux.vsix。

先删除我们上传到/home/mysql/.vscode-server/extensions/ms-vscode.cpptools-1.6.0/bin的三个文件

[mysql@gbase bin]$ ls -lrt

total 31188

-rw-rw-r–. 1 mysql mysql 11784664 Aug 23 22:29 cpptools-srv

-rw-rw-r–. 1 mysql mysql 20014008 Aug 23 22:29 cpptools

-rw-rw-r–. 1 mysql mysql 11972 Aug 23 22:34 LICENSE.txt

-rw-rw-r–. 1 mysql mysql 582 Sep 26 12:05 common.json

-rw-rw-r–. 1 mysql mysql 301 Sep 26 12:05 linux.clang.arm.json

-rw-rw-r–. 1 mysql mysql 310 Sep 26 12:05 linux.clang.arm64.json

-rw-rw-r–. 1 mysql mysql 300 Sep 26 12:05 linux.clang.x64.json

-rw-rw-r–. 1 mysql mysql 291 Sep 26 12:05 linux.clang.x86.json

-rw-rw-r–. 1 mysql mysql 301 Sep 26 12:05 linux.gcc.arm.json

-rw-rw-r–. 1 mysql mysql 310 Sep 26 12:05 linux.gcc.arm64.json

-rw-rw-r–. 1 mysql mysql 302 Sep 26 12:05 linux.gcc.x64.json

-rw-rw-r–. 1 mysql mysql 291 Sep 26 12:05 linux.gcc.x86.json

-rw-rw-r–. 1 mysql mysql 284 Sep 26 12:05 macos.clang.arm.json

-rw-rw-r–. 1 mysql mysql 293 Sep 26 12:05 macos.clang.arm64.json

-rw-rw-r–. 1 mysql mysql 283 Sep 26 12:05 macos.clang.x64.json

-rw-rw-r–. 1 mysql mysql 274 Sep 26 12:05 macos.clang.x86.json

-rw-rw-r–. 1 mysql mysql 284 Sep 26 12:05 macos.gcc.arm.json

-rw-rw-r–. 1 mysql mysql 293 Sep 26 12:05 macos.gcc.arm64.json

-rw-rw-r–. 1 mysql mysql 283 Sep 26 12:05 macos.gcc.x64.json

-rw-rw-r–. 1 mysql mysql 274 Sep 26 12:05 macos.gcc.x86.json

drwxrwxr-x. 15 mysql mysql 145 Sep 26 12:05 messages

-rw-rw-r–. 1 mysql mysql 87 Sep 26 12:05 windows.clang.arm.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 12:05 windows.clang.arm64.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 12:05 windows.clang.x64.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 12:05 windows.clang.x86.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 12:05 windows.gcc.arm.json

-rw-rw-r–. 1 mysql mysql 89 Sep 26 12:05 windows.gcc.arm64.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 12:05 windows.gcc.x64.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 12:05 windows.gcc.x86.json

-rw-rw-r–. 1 mysql mysql 299 Sep 26 12:05 windows.msvc.arm.json

-rw-rw-r–. 1 mysql mysql 324 Sep 26 12:05 windows.msvc.arm64.json

-rw-rw-r–. 1 mysql mysql 383 Sep 26 12:05 windows.msvc.x64.json

-rw-rw-r–. 1 mysql mysql 359 Sep 26 12:05 windows.msvc.x86.json

[mysql@gbase bin]$ rm -rf cpptools*

[mysql@gbase bin]$ rm -rf LICENSE.txt

[mysql@gbase bin]$ ls -lrt

total 116

-rw-rw-r–. 1 mysql mysql 582 Sep 26 12:05 common.json

-rw-rw-r–. 1 mysql mysql 301 Sep 26 12:05 linux.clang.arm.json

-rw-rw-r–. 1 mysql mysql 310 Sep 26 12:05 linux.clang.arm64.json

-rw-rw-r–. 1 mysql mysql 300 Sep 26 12:05 linux.clang.x64.json

-rw-rw-r–. 1 mysql mysql 291 Sep 26 12:05 linux.clang.x86.json

-rw-rw-r–. 1 mysql mysql 301 Sep 26 12:05 linux.gcc.arm.json

-rw-rw-r–. 1 mysql mysql 310 Sep 26 12:05 linux.gcc.arm64.json

-rw-rw-r–. 1 mysql mysql 302 Sep 26 12:05 linux.gcc.x64.json

-rw-rw-r–. 1 mysql mysql 291 Sep 26 12:05 linux.gcc.x86.json

-rw-rw-r–. 1 mysql mysql 284 Sep 26 12:05 macos.clang.arm.json

-rw-rw-r–. 1 mysql mysql 293 Sep 26 12:05 macos.clang.arm64.json

-rw-rw-r–. 1 mysql mysql 283 Sep 26 12:05 macos.clang.x64.json

-rw-rw-r–. 1 mysql mysql 274 Sep 26 12:05 macos.clang.x86.json

-rw-rw-r–. 1 mysql mysql 284 Sep 26 12:05 macos.gcc.arm.json

-rw-rw-r–. 1 mysql mysql 293 Sep 26 12:05 macos.gcc.arm64.json

-rw-rw-r–. 1 mysql mysql 283 Sep 26 12:05 macos.gcc.x64.json

-rw-rw-r–. 1 mysql mysql 274 Sep 26 12:05 macos.gcc.x86.json

drwxrwxr-x. 15 mysql mysql 145 Sep 26 12:05 messages

-rw-rw-r–. 1 mysql mysql 87 Sep 26 12:05 windows.clang.arm.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 12:05 windows.clang.arm64.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 12:05 windows.clang.x64.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 12:05 windows.clang.x86.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 12:05 windows.gcc.arm.json

-rw-rw-r–. 1 mysql mysql 89 Sep 26 12:05 windows.gcc.arm64.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 12:05 windows.gcc.x64.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 12:05 windows.gcc.x86.json

-rw-rw-r–. 1 mysql mysql 299 Sep 26 12:05 windows.msvc.arm.json

-rw-rw-r–. 1 mysql mysql 324 Sep 26 12:05 windows.msvc.arm64.json

-rw-rw-r–. 1 mysql mysql 383 Sep 26 12:05 windows.msvc.x64.json

-rw-rw-r–. 1 mysql mysql 359 Sep 26 12:05 windows.msvc.x86.json

通过vscode 从vsix来进行安装,选择本地目录D:\ssh\cpptools-linux.vsix文件

[mysql@gbase bin]$ ls -lrt

total 31188

-rw-rw-r–. 1 mysql mysql 582 Sep 26 15:01 common.json

-rw-rw-r–. 1 mysql mysql 20014008 Sep 26 15:01 cpptools

-rw-rw-r–. 1 mysql mysql 11784664 Sep 26 15:01 cpptools-srv

-rw-rw-r–. 1 mysql mysql 11972 Sep 26 15:01 LICENSE.txt

-rw-rw-r–. 1 mysql mysql 301 Sep 26 15:01 linux.clang.arm.json

-rw-rw-r–. 1 mysql mysql 310 Sep 26 15:01 linux.clang.arm64.json

-rw-rw-r–. 1 mysql mysql 300 Sep 26 15:01 linux.clang.x64.json

-rw-rw-r–. 1 mysql mysql 291 Sep 26 15:01 linux.clang.x86.json

-rw-rw-r–. 1 mysql mysql 301 Sep 26 15:01 linux.gcc.arm.json

-rw-rw-r–. 1 mysql mysql 310 Sep 26 15:01 linux.gcc.arm64.json

-rw-rw-r–. 1 mysql mysql 302 Sep 26 15:01 linux.gcc.x64.json

-rw-rw-r–. 1 mysql mysql 291 Sep 26 15:01 linux.gcc.x86.json

-rw-rw-r–. 1 mysql mysql 284 Sep 26 15:01 macos.clang.arm.json

-rw-rw-r–. 1 mysql mysql 293 Sep 26 15:01 macos.clang.arm64.json

-rw-rw-r–. 1 mysql mysql 283 Sep 26 15:01 macos.clang.x64.json

-rw-rw-r–. 1 mysql mysql 274 Sep 26 15:01 macos.clang.x86.json

-rw-rw-r–. 1 mysql mysql 284 Sep 26 15:01 macos.gcc.arm.json

-rw-rw-r–. 1 mysql mysql 293 Sep 26 15:01 macos.gcc.arm64.json

-rw-rw-r–. 1 mysql mysql 283 Sep 26 15:01 macos.gcc.x64.json

-rw-rw-r–. 1 mysql mysql 274 Sep 26 15:01 macos.gcc.x86.json

drwxrwxr-x. 15 mysql mysql 145 Sep 26 15:01 messages

-rw-rw-r–. 1 mysql mysql 87 Sep 26 15:01 windows.clang.arm.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 15:01 windows.clang.arm64.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 15:01 windows.clang.x64.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 15:01 windows.clang.x86.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 15:01 windows.gcc.arm.json

-rw-rw-r–. 1 mysql mysql 89 Sep 26 15:01 windows.gcc.arm64.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 15:01 windows.gcc.x64.json

-rw-rw-r–. 1 mysql mysql 87 Sep 26 15:01 windows.gcc.x86.json

-rw-rw-r–. 1 mysql mysql 299 Sep 26 15:01 windows.msvc.arm.json

-rw-rw-r–. 1 mysql mysql 324 Sep 26 15:01 windows.msvc.arm64.json

-rw-rw-r–. 1 mysql mysql 383 Sep 26 15:01 windows.msvc.x64.json

-rw-rw-r–. 1 mysql mysql 359 Sep 26 15:01 windows.msvc.x86.json

重启vscdoe

4.使用vscode远程编译Linux服务器的MySQL源码,mysql源码在/soft/mysql-5.7.26/目录

这里需要配置Cmake 生成setting.json配置文件 点击CMake Tool的设置按钮,再点击Extention Settings

这里选择Remote [SSH:192.168.1.249],我这对于Build Directory选择使用默认配置,因为${workspaceFolder}就是/soft/mysql-5.7.26目录,所以$${workspaceFolder}/build也就是/soft/mysql-5.7.26/build目录

所以Source Directory目录选择使用默认的$workspaceFolder}目录

给Configure Args配置以下三个参数

-DWITH_BOOST=/soft/mysql-5.7.26/boost/boost_1_59_0

-DDOWNLOAD_BOOST=1

-DWITH_DEBUG=1

选择编译器

给CMake选择Debug模式

然后进行编译

编译完成后,在Linux服务器上初始化mysql数据库

创建data,etc目录用来分别存放数据文件与配置文件my.cnf

[mysql@gbase build]$ mkdir {data,etc}

[mysql@gbase build]$ cd etc

[mysql@gbase etc]$ vi my.cnf

[mysqld]

basedir=/soft/mysql-5.7.26/build

datadir=/soft/mysql-5.7.26/build/data

bind-address=0.0.0.0

user=mysql

port=3306

log-error=/soft/mysql-5.7.26/build/data/mysql.err

pid-file=/soft/mysql-5.7.26/build/data/mysqld.pid

socket = /soft/mysql-5.7.26/build/data/mysql.sock

character-set-server=utf8mb4

default-storage-engine=INNODB

explicit_defaults_for_timestamp = true

[mysql@gbase build]$ sql/mysqld –defaults-file=etc/my.cnf –initialize-insecure

[mysql@gbase build]$ cd data

[mysql@gbase data]$ ls

auto.cnf ib_buffer_pool ibdata1 ib_logfile0 ib_logfile1 mysql mysql.err performance_schema sys

[mysql@gbase data]$ ls -lrt

total 110632

-rw-r—–. 1 mysql mysql 50331648 Sep 26 15:43 ib_logfile1

-rw-r—–. 1 mysql mysql 56 Sep 26 15:43 auto.cnf

-rw-r—–. 1 mysql mysql 1046 Sep 26 15:43 mysql.err

drwxr-x—. 2 mysql mysql 8192 Sep 26 15:43 performance_schema

drwxr-x—. 2 mysql mysql 4096 Sep 26 15:43 mysql

drwxr-x—. 2 mysql mysql 8192 Sep 26 15:43 sys

-rw-r—–. 1 mysql mysql 419 Sep 26 15:43 ib_buffer_pool

-rw-r—–. 1 mysql mysql 50331648 Sep 26 15:43 ib_logfile0

-rw-r—–. 1 mysql mysql 12582912 Sep 26 15:43 ibdata1

[mysql@gbase data]$ more mysql.err

2021-09-26T07:43:43.288066Z 0 [Warning] Changed limits: max_open_files: 1024 (requested 5000)

2021-09-26T07:43:43.288312Z 0 [Warning] Changed limits: table_open_cache: 431 (requested 2000)

2021-09-26T07:43:43.289227Z 0 [ERROR] Can’t find error-message file ‘/soft/mysql-5.7.26/build/share/errmsg.sys’. Check error-message file location and ‘lc-messages-dir’ configuration directive.

2021-09-26T07:43:46.058883Z 0 [Warning] InnoDB: New log files created, LSN=45790

2021-09-26T07:43:46.360628Z 0 [Warning] InnoDB: Creating foreign key constraint system tables.

2021-09-26T07:43:46.558161Z 0 [Warning] No existing UUID has been found, so we assume that this is the first time that this server has been started. Generating a new UUID: 7b190ba6-1e9d-11ec-93d5-005056a31fca.

2021-09-26T07:43:46.567453Z 0 [Warning] Gtid table is not ready to be used. Table ‘mysql.gtid_executed’ cannot be opened.

2021-09-26T07:43:46.569018Z 1 [Warning] root@localhost is created with an empty password ! Please consider switching off the –initialize-insecure option.

[mysql@gbase mysql-5.7.26]$ gcc -v -E -x c++ –

Using built-in specs.

COLLECT_GCC=gcc

Target: x86_64-redhat-linux

Configured with: ../configure –prefix=/usr –mandir=/usr/share/man –infodir=/usr/share/info –with-bugurl=http://bugzilla.redhat.com/bugzilla –enable-bootstrap –enable-shared –enable-threads=posix –enable-checking=release –with-system-zlib –enable-__cxa_atexit –disable-libunwind-exceptions –enable-gnu-unique-object –enable-linker-build-id –with-linker-hash-style=gnu –enable-languages=c,c++,objc,obj-c++,java,fortran,ada,go,lto –enable-plugin –enable-initfini-array –disable-libgcj –with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/isl-install –with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-x86_64-redhat-linux/cloog-install –enable-gnu-indirect-function –with-tune=generic –with-arch_32=x86-64 –build=x86_64-redhat-linux

Thread model: posix

gcc version 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)

COLLECT_GCC_OPTIONS=’-v’ ‘-E’ ‘-mtune=generic’ ‘-march=x86-64’

/usr/libexec/gcc/x86_64-redhat-linux/4.8.5/cc1plus -E -quiet -v -D_GNU_SOURCE – -mtune=generic -march=x86-64

ignoring nonexistent directory “/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include-fixed”

ignoring nonexistent directory “/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../x86_64-redhat-linux/include”

#include “…” search starts here:

#include < ...> search starts here:

/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5

/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/x86_64-redhat-linux

/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/backward

/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include

/usr/local/include

/usr/include

将下面的内容加入到c_cpp_properties.json中的includePath中

/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5

/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/x86_64-redhat-linux

/usr/lib/gcc/x86_64-redhat-linux/4.8.5/../../../../include/c++/4.8.5/backward

/usr/lib/gcc/x86_64-redhat-linux/4.8.5/include

/usr/local/include

/usr/include

加入后错误信息消失

Proudly powered by WordPress | Indrajeet by Sus Hill.