现代C++白皮书

Read more →

Envs

hugo # wget https://github.com/gohugoio/hugo/releases/download/v0.92.1/hugo_0.92.1_Linux-64bit.deb https://github.91chi.fun/https://github.com//gohugoio/hugo/releases/download/v0.92.2/hugo_extended_0.92.2_Linux-64bit.deb sudo dpkg -i hugo*.deb 140.82.113.3 aria2c -s 5 https://github.com/gohugoio/hugo/releases/download/v0.92.1/hugo_0.92.1_Linux-64bit.deb https://github.com/gohugoio/hugo/releases/download/v0.92.1/hugo_0.92.1_Linux-64bit.deb 可以使用aria2下载,ubuntu使用apt install aria2直接安装工具,使用-s开启多路下载 aria2c -s 5 https://github.com/gohugoio/hugo/releases/download/v0.92.1/hugo_0.92.1_Linux-64bit.deb manager用户 https://www.jianshu.com/p/a76a93e8c662 Unix # 分区问题,集群上多块磁盘分区挂载到指定目录 fdisk disk 可以对一个磁盘进行分区的添加和删除等操作 p d w h 添加磁盘挂载 lsblk -f 查看磁盘 mkfs.xfs -f -n ftype=1 /dev/sdb1 格式化磁盘 mount /dev/sdb1 /var/lib/docker 挂载 xfs_info /dev/sdb1 | grep ftype=1 blkid /dev/sdb1 查看UUID UUID=<UUID> /var/lib/docker xfs defaults 0 0 写进/etc/fstab 问题Couldn't find device with uuid 4mhUbb-Ls1h-jp0d-JuJK-C38V-T3tX-f7s2IN 原因未知,疑似但是这个UUID是前面挂载的分区格式化之前的UUID,所以可能是挂载的时候出了什么问题,但是之前对其他机器操作无问题,此问题只出现在集群中的一两太机器上。 解决: 使用 vgreduce --removemissing --verbose lvname 解决,但是需要视情况而定,需要知道自己在做什么 其中会使用的命令 lsblk vgscan pvscan cat /etc/lvm/archive/* | less 查看UUID和盘符之前的关系 lvextend -L +300G /dev/mapper/centos-root 扩展分区大小 xfs_growfs /dev/mapper/centos-root 扩展且生效 lvremove /dev/mapper/centos-home 删除lv lvcreate -L 100G -n /dev/mapper/centos-home 创建lv mkdf.
Read more →

Docker

docker 常用命令速查,私用
Read more →

C++ Primer Plus

编译器 # 把高级语言编译成可执行语言工具,分为前端后后端,前端值得是高级语言的解析,后端是指翻译解析之后的结果为机器语言 多文件 ** 连接 多文件编译可以有两种方式,一是直接编译为一个可以执行文件,二是按模块或者按文件编译为库,然后连接到执行文件 连接方式有两种, 一是静态连接,把所有的库文件打包到最后的生成文件中,优点是不需要额外的依赖外部环境,独立性强,缺点是文件体积大 二是动态链接,为了解决静态链接的缺点,执行文件在执行到库相关的代码的时候才加载库,有一点需要注意的是,程序运行的时候,在使用到动态库的时候才映射动态库到内存空间中。原理是编译待援在编译的时候,会更具声明生成函数的调用逻辑,但是只是一个地址跳转语句,所以,只要不调用,就不会有问题,当调用到了。才会加载库然后映射库的地址,这个完整的过程称为重定向。 动态连接 C语言编程透视 声明 声明是为了在编译的时候编译器能进行完整的上下文编译。他需要更具声明来确定编译信息,否则编译器无法确定编译中的语句信息,声明可以辅助完成这个情况, 所以理论上编译的时候是可以不需要实现的,可以在其他编译单元中实现声明的函数,其声明的文件可以不引用头文件,即两个编译单元完全可以无任何联系,除了声明之外,在连接的时候,连接器会根据编译出来的信息去确定函数调用情况,这里有一个问题,按上述的描述,是一个声明对应一个实现,如果有一个声明对应多个实现呢 == : 会有覆盖问题,如果多个动态链接库都有同一个声明的实现,则连接的时候连接第一个,后面的则忽略,这也提醒我们,在大型项目中,避免同名全局函数或者变量,使用namespace或者static限制作用域, g++ -o tt ../main.cpp -ldl ./libhellolib.so ./libhellolib1.so LD_LIBRARY_PATH=$PWD ./tt 头文件,避免公用代码的重复,预处理时展开头文件,需要使用#pragma once避免重复引用,头文件只是简单的文件替换,理论上的可以替换任何文本。 cmake * 子模块,使用add_subdirectory引入 * 第三方库 * 只是头文件,直接指定头文件目录编译即可 * 使用子模块 * 使用为连接库 * 使用git模块 STL 重点为容器和算法 lambda表达式,实质上是仿函数,是一个结构体实现()运算的重载,捕获的时候按照声明的新式捕获参数,建议使用的时候明确使用的参数,使用哪个就捕获哪一个,否则他实际上会占据一定的大小的,配合std::function使用 CTAD — complie-time argument deduction,编译器参数推断,C++17引入的,可以在编译器按照上下文推断类型,具体表现在lambda参数可以使用auto,容器可以不适用<> ranges https://zhuanlan.zhihu.com/p/350068132 module raii 获取资源即初始化,释放资源即销毁,具体的实现是使用构造函数和析构函数,当前的实现为智能指针,其他用户自己管理的资源最好也使用raii,遮这样在函数有多个出口的时候,就不会有意外的情况,本质上还是自己管理资源,不想其他的语言有GC 异常安全,C++中异常机制在回溯栈的时候会析构对象,所以如果没有实现RAII,则自己管理的内存则无法释放,C++的异常可以发生在任何地方,如果发生在析构函数中,则需要自己处理,不要在析构函数中抛出异常的,在构造函数中的时候,也需要捕获异常然后释放已经申请的资源,构造函数异常的时候,是不会调用析构函数的, 构造函数 构造函数有时候会隐士的生成对象,即使没有显示声明,使用explicit避免这种情况,单参数的时候会,多参数使用{},调用的时候也会 直接使用多参数的时候,()和{}是有区别的,()除了正常的使用外,其他情况不具备特殊含义 int a = (10, 11); int a = {10, 11}; tt t(1, 2); tt q{1, 3}; tt w = {1, 4}; tests({1,5}); ``` 上面的语句1正确,a的值为11,2错误,{}这种用法的意义是参数列表,是会构造对象的。ps,调用构造函数的时候,有具体的对象的时候两种括号无差别,但是无对象的时候有区别,如上,细品 默认构造函数 拷贝构造( A(A const & a) ) A a = aa; 移动构造( A(A && a) ) 赋值构造( A&operator=(A const& a) ) A a; a = aa; 移动赋值( A&operator=(A && a) ) =delte和=default 类内部变量可以赋初值 三五法则 拷贝构造或者赋值构造需要区分深拷贝和浅拷贝,这也是构造函数肯可能引入的问题,例如浅拷贝导致内存的重复释放, 各种构造函数更多的是需要考虑当前对象的来源,如果是直接从零开始的,则是普通的构造函数,如果是从别的对象来的,则需要考虑深浅拷贝的问题,以及构造之后别的对象是否还需要的问题,简而言之,就是资源细节上的考虑,只要内涉及到资源的操作,则需要多话费一些心思区考虑, 函数返回多值
Read more →

issues # 1490 # 1921 # 1699 # http://10.20.16.216:9090/ADB/AntDB/-/issues/1490 http://10.20.16.216:9090/ADB/AntDB/-/issues/1921 http://10.20.16.216:9090/ADB/AntDB/-/issues/1699 问题 # 使用到reduce的地方(包括查询)偶现以下错误,再次执行sql就正常; ERROR: remote node 16389 closed socket CONTEXT: dynamic reduce 复现方法 # 使用修改分布方式的方式去复现问题,过程如下: 创建100张表,然后并发100,不停执行下面的语句,5分钟之内会出现报错: alter table xxx distribute by replication; alter table xxx distribute by random; 无法直接复现 1779 # http://10.20.16.216:9090/ADB/AntDB/-/issues/1779 问题 # 执行计划不正确导致dyreduce执行出错 复现方法 # create table tttb1( c1 int,c2 varchar(100),c3 varchar(100)); create table tttb2(c1 int,sheet_num varchar(100)); create table tttb3(c1 int,order_no varchar(100)); explain select count(distinct c2) from tttb1 where c2 in (select distinct sheet_num from tttb2,tttb3 where sheet_num=order_no and c3='1'); create table tb1(c1 int,c2 varchar(100),c3 varchar(100)); create table tb2(c1 int,sheet_num varchar(100)); create table tb3(c1 int,order_no varchar(100)); explain select count(distinct c2) from tb1 where c2 in (select distinct sheet_num from tb2,tb3 where sheet_num=order_no and c3='1'); insert into tb1 select (random()*10000000)::int, (random()*10000000)::int, (random()*10000000)::int from generate_series(1,100000); insert into tb2 select (random()*10000000)::int, (random()*10000000)::int from generate_series(1,100000); insert into tb3 select (random()*10000000)::character varying, (random()*10000000)::int from generate_series(1,100000); create table tb1int(c1 int, c2 int,c3 int); create table tb2int(c1 int, sheet_num int); create table tb3int(c1 int, order_no int); explain select count(distinct c2) from tb1int where c2 in (select distinct sheet_num from tb2int,tb3int where sheet_num=order_no and c3=1); insert into tb1int select (random()*10000000)::int, (random()*10000000)::int, (random()*10000000)::int from generate_series(1,100000); insert into tb2int select (random()*10000000)::int, (random()*10000000)::int from generate_series(1,100000); insert into tb3int select (random()*10000000)::int, (random()*10000000)::int from generate_series(1,100000); 1875 # http://10.
Read more →

语句 prepare s3(int, int) as select no_o_id from bmsql_new_order where no_w_id = $1 and no_d_id = $2 order by no_o_id asc; QUERY PLAN --------------------------------------------------------------------------------------------------- Cluster Gather (cost=291.52..430.37 rows=459 width=4) Remote node: 16386 -> Sort (cost=291.52..292.67 rows=459 width=4) Output: no_o_id Sort Key: bmsql_new_order.no_o_id -> Bitmap Heap Scan on public.bmsql_new_order (cost=13.46..271.23 rows=459 width=4) Output: no_o_id Recheck Cond: ((bmsql_new_order.no_w_id = 1) AND (bmsql_new_order.no_d_id = 1)) -> Bitmap Index Scan on bmsql_new_order_pkey (cost=0.00..13.34 rows=918 width=0) Index Cond: ((bmsql_new_order.no_w_id = 1) AND (bmsql_new_order.no_d_id = 1)) Remote node: 16386 (11 rows) QUERY PLAN -------------------------------------------------------------------------------------------------------------------- Data Node Scan on "__REMOTE_SORT_QUERY__" (cost=0.00..0.00 rows=1000 width=4) Output: bmsql_new_order.no_o_id Node/s: data_1 Remote query: SELECT no_o_id FROM ONLY public.
Read more →

predicate_refuted_by 和 make_new_qual_list的运行逻辑以及PARAM 无法选出一个节点的原因 make_new_qual_list需要使用表达式和分区信息构造新的表达式,但是PARAM不是常量,所以无法构造, 所以predicate_refuted_by判定变大时和约束的时候无法正确的选择节点,动态语句只要使用到分区键都不行 node_count = 2 Table "public.bmsql_new_order" Column | Type | Nullable | Storage | ---------+---------+----------+---------+ no_w_id | integer | not null | plain | no_d_id | integer | not null | plain | no_o_id | integer | not null | plain | Indexes: "bmsql_new_order_pkey" PRIMARY KEY, btree (no_w_id, no_d_id, no_o_id) Foreign-key constraints: "no_order_fkey" FOREIGN KEY (no_w_id, no_d_id, no_o_id) REFERENCES bmsql_oorder(o_w_id, o_d_id, o_id) DISTRIBUTE BY HASH(no_w_id) TO NODE(dn1, dn2) Access method: heap 数据分布 benchmarksql=# execute direct on (dn1) 'select distinct no_w_id from public.bmsql_new_order'; no_w_id --------- 1 5 2 (3 rows) benchmarksql=# execute direct on (dn2) 'select distinct no_w_id from public.
Read more →

Read more →

remote Query # 精确选择数据源,需要从语句的约束条件中计算出具体的执行数据源节点,然后把语句下发的对应的 DN 操作尽可能下推,下推一些操作到对应的DN上执行 remote query当前使用两阶段优化 第一阶段是FQS,对语句进行简单的判断,如果语句可以完全在DN上执行,则直接在这里创建remote plan,然后直接返回,如下例子 benchmarksql=# explain select * from t1; QUERY PLAN ---------------------------------------------------------------------------- Data Node Scan on "__REMOTE_FQS_QUERY__" (cost=0.00..0.00 rows=0 width=0) Primary node/s: dn1 Node/s: dn1, dn2 (3 rows) 第二阶段,FQS判断失败的语句,此时需要进行常规优化,一般是语句需要DN之间的数据发生交换的时候,例如join使用多表, 但是关联条件不是分区键,此时需要把DN的数据读取到 CN 上,然后进行关联, postgres=# explain select * from t1 join t2 on t1.c1 = t2.c1; QUERY PLAN --------------------------------------------------------------------------------------------------- Hash Join (cost=2752.50..5509.65 rows=3000 width=16) Hash Cond: (t2.c1 = t1.c1) -> Data Node Scan on t2 "_REMOTE_TABLE_QUERY_" (cost=0.00..2715.90 rows=3001 width=8) Primary node/s: dn1 Node/s: dn1, dn2, dn3 -> Hash (cost=2715.00..2715.00 rows=3000 width=8) -> Data Node Scan on t1 "_REMOTE_TABLE_QUERY__1" (cost=0.00..2715.00 rows=3000 width=8) Primary node/s: dn1 Node/s: dn1, dn2, dn3 (9 rows) 1.
Read more →

typedef struct SubPlan { pg_node_attr(no_query_jumble) Expr xpr; /* Fields copied from original SubLink: */ SubLinkType subLinkType; /* see above */ /* The combining operators, transformed to an executable expression: */ Node *testexpr; /* OpExpr or RowCompareExpr expression tree */ List *paramIds; /* IDs of Params embedded in the above */ /* Identification of the Plan tree to use: */ int plan_id; /* Index (from 1) in PlannedStmt.subplans */ /* Identification of the SubPlan for EXPLAIN and debugging purposes: */ char *plan_name; /* A name assigned during planning */ /* Extra data useful for determining subplan's output type: */ Oid firstColType; /* Type of first column of subplan result */ int32 firstColTypmod; /* Typmod of first column of subplan result */ Oid firstColCollation; /* Collation of first column of subplan result */ /* Information about execution strategy: */ bool useHashTable; /* true to store subselect output in a hash table (implies we are doing "IN") */ bool unknownEqFalse; /* true if it's okay to return FALSE when the * spec result is UNKNOWN; this allows much * simpler handling of null values */ bool parallel_safe; /* is the subplan parallel-safe?
Read more →