升级gitlab自9.4.5到12.1.3版本

gitlab所在服务器进行了操作系统升级,从ubuntu 14.04升级到18.04,而且gitlab自身很久未进行升级,导致与现有版本有较大差距,升级过程有一定周折,所幸最终还是成功升级。

首先参考此网站进行升级:How to upgrade to latest Gitlab from version less then 10.8

但操作升级的不顺利,版本升级时全提示版本不对,不能升级。

使用apt list -a gitlab-ce*命令时发现其最小版本为10.7.0,于是尝试从这个版本进行升级,发现可以操作:

sudo apt-get install gitlab-ce=10.7.0-ce.0

然后再这个版本基础上再进行大版本升级,最终顺利升级至最新版本。

基于多个SSH服务器构建SSH代理

前一篇文章使用了scp跨两个内网进行文件传输,其实还可以有一种更简单的办法进行处理,就是构建SSH代理。

编辑.ssh目录下的config文件

nano ~/.ssh/config

然后指定不同的服务器,注意其中的ProxyCommand指令:

Host bridge1
  HostName alias1.example.com

Host private1
  ProxyCommand ssh -q bridge1 nc -q0 private1 22

Host private2
  ProxyCommand ssh -q private1 nc -q0 private2 22

这样,就构建了private1、bridge1两个ssh代理,访问private2服务器可以将其当做一个本地服务器直接使用,也可以直接scp进行数据的上传和下载。

参考:http://sshmenu.sourceforge.net/articles/transparent-mulithop.html

全国县市边界数据的处理(1M2017版)

全国地理信息资源目录服务系统上可以下载最新版本(2017年,1:1百万比例尺)的全国各要素基础数据,具体包括:

  • 共77幅DLG数据集,包括全国陆地范围以及台湾岛、海南岛、钓鱼岛、南海诸岛在内的主要岛屿及其临近海域。
  • 包括水系、居民地及设施、公路铁路、行政边界、地名等5个数据集12个数据层。

我们现在就需要其中的行政边界数据,本来以为下载后可以很方便的使用(有点想当然了),经过一番艰苦的处理后,数据终于是可用状态了。

在mac系统下进行了数据处理,使用了gdal/ogr、QGIS3,主要处理过程记录如下。

  1. 将下载下来的77副gdb数据,全部解压到一个目录中,比如1M2017目录,并在其中建立一个shp子目录。
  2. 在shell下,使用ogr2ogr命令,将所有gdb文件转换为一个大的shape文件,注意需要将其中的NAME字段编码转换为UTF8编码(官方是GBK编码)。
  3. 使用ogr2ogr,对合并后的BOUA(面状边界数据)文件根据PAC字段进行再次图形合并(因为默认的分幅会保留大量的正方形),生成output1.shp文件。
  4. output1.shp文件包含了大量了国外数据、海洋数据,这些数据可以通过ogr2ogr再次剔除,即设置PAC字段>100000且不等于250100,然后生成output2.shp文件。
  5. 仔细观察output2.shp文件,发现其中存在大量的拓扑错误(分幅边线的交叉遗留),在QGIS3中使用v.clean工具进行错误检查和处理,生成output3.shp文件。
  6. 对output3.shp文件进行人工错误检查(可借助QGIS3的图形检查工具check validity辅助检查),使用编辑工具(以及高级数字化工具)进行错误修复,主要使用节点编辑工具(删除节点)、多边形合并工具、多边形part删除工具等,最终生成全国(含港澳台)的县级边界数据集boua_cnty.shp。
  7. 使用QGIS3在boua_cnty数据中添加一个虚拟字段pac_city,并将其值定义为floor(PAC/100),然后对其执行dissolve操作,若需要将直辖市也当做一个独立城市边界,则需要单独处理一下四个直辖市的属性(将县区进行合并,主要是天津和重庆),形成全国市级边界数据集boua_city.shp文件。
for i in `ls -d *.gdb`;do ogr2ogr -f "ESRI Shapefile" -lco ENCODING=UTF-8  -append  shp $i;done
ogr2ogr -f "ESRI Shapefile" output1.shp -lco ENCODING=UTF-8 -dialect sqlite -sql "select st_union(geometry) as geometry,PAC,NAME from 'BOUA' group by PAC,NAME order by PAC,NAME" shp/BOUA.shp
ogr2ogr -f "ESRI Shapefile" output2.shp -lco ENCODING=UTF-8 -where "PAC>100000 and PAC<>250100" output1.shp

但这样生成的城市边界仅包括陆地边界,对于内陆型城市,在使用中问题不大,但对于沿海城市,则很多人类活动轨迹可能会超出陆地边界(比如舟山),因此还需要一个融合近海边界的城市边界。手头上有一个2012年版本的含海洋边界的城市边界数据,需要将其海洋边界数据融合到新的全国边界数据集中。

处理过程为:

  1. 对含有海洋边界的数据集bou2012,和最新全国城市边界数据集boua_city,执行difference操作,在QGIS3进行编辑,删除内陆边界中有差异的部分,在沿海边界删除海洋中的小岛(内多边形),同时添加一个虚拟字段pac_city(和boua_city中的字段相同),最终生成海洋城市边界数据集。
  2. 将boua_city数据集和上一步中生成的海洋城市边界数据集执行union操作。
  3. 对union后的数据集,根据pac_city字段执行dissolve操作。
  4. 人工检查最终生成的数据集。

因数据问题,此数据集中不含港澳台的海洋边界。

使用grep查找符合条件文本的前后几行

有的时候,需要在满足查询条件的情况,查询符合条件文本的前后几行。之前一直以为需要用python自行解决,没想到grep里有参数可以简单处理。

比如,在log记录,有的错误日志仅提供了错误内容,正在执行脚本的相关参数需要从上下文中进行推理,这时就可以采用此方法进行处理。

# 显示匹配行的前后3行
grep -3 'ERROR:' weibo.log
grep -C 3 'ERROR:' weibo.log

# 显示匹配行的后4行
grep -A 4 'ERROR:' weibo.log

# 显示匹配行的前2行
grep -B 2 'ERROR:' weibo.log

在ubuntu 18.04上安装最新版greenplum(7.0.alpha)

近期组建了一个新的大数据测试集群,由4个物理机器构成一个测试集群,分别命名为hadoop1-4号机器,想要进行MPP并行数据库的安装与测试工作。服务器物理机安装的操作系统为ubuntu server 18.04版本。开始以为可以采用lanchpad的官方库进行安装,发现greenplum官方目前并未支持ubuntu 18.04,需要从源码编译安装。在尝试编译的过程中遇到了几个错误,最终通过一个变通的方法进行了处理,在此记录一下过程。

简而言之,是greenplum所采用的xerces-c库与ubuntu官方库的版本不一致,导致调用时遇到了DSO missing错误。可以采用禁止gporca的查询优化器方法来避免此错误,同时安装postgis插件也需要禁止raster功能,或者移除官方的xerces-c库,使用greenplum自带的xerces-c库。

下面记录一下第二种方案的编译过程。

一、安装gp-xercesc

git clone https://github.com/greenplum-db/gp-xerces.git
cd gp-xerces
mkdir build
cd build
../configure --prefix=/usr/local
make
sudo make install

二、安装gporca

git clone https://github.com/greenplum-db/gporca.git
cd gporca
cmake -GNinja -H. -Bbuild
sudo ninja install -C build

三、安装gpdb

git clone https://github.com/greenplum-db/gpdb.git
cd gpdb
sudo ./README.ubuntu.bash

此时系统会默认安装libxerces-c-dev库,需要将此库移除以使其正确编译。

sudo apt remove libxerces-c-dev   ###此库会有冲突
./configure --enable-orca --with-perl --with-python --with-libxml --prefix=/usr/local/gpdb
make -j32
sudo make -j32 install
sudo ldconfig

这样可以确保编译通过,且可安装,但在初始化greenplum之前还需要确保:

1、master机器到其他机器可以ssh密钥登陆

2、limits.conf和sysctl.conf已修改,且修改后重新登陆过。

3、在其他各机器执行相同的操作。

上述操作执行完之后,在master节点,指定某一目录作为greenplum的数据目录,比如/data,然后在master节点上建立/data/master目录,在所有节点上建立/data/primary目录。然后:

source /usr/local/gpdb/greenplum_path.sh
cd /data/master
cp /usr/local/gpdb/docs/cli_help/gpconfigs/hostfile_gpinitsystem .
cp /usr/local/gpdb/docs/cli_help/gpconfigs/gpinitsystem_config .

修改这两个配置文件,hostfile记录了greenplum所有机器的hostname,一行一个机器名;gpinitsystem_config记录了greenplum的目录设置和segment设置参数,需进行相应的修改,完成后即可启动数据库。

gpinitsystem -c gpinitsystem_config -h hostfile_gpinitsystem 

使用SSH构建内网隧道

之前一直使用学校提供的vpn工具访问放在学校机房内网的服务器,多数时间是没有问题的,但到重大事件时会提高安全防范级别,这是vpn服务器就会关停,在家里工作就傻眼了。于是就想看看是否有什么工具可以穿透内网,保证我有需要的时候可以随时访问。

搜索了一圈后,发现ssh就能实现这个功能。前提是需要有一个可以访问的外网服务器。

假定,内网服务器为N,外网服务器为W。

  1. 在N服务器上可以使用密钥登陆服务器W,这样可以保证登陆时不需要使用密码。
  2. 在服务器N上安装autossh工具,其主要功能是提高ssh链接稳定性,并在ssh连接断开后自动重连。
  3. 在服务器N上执行:
sudo autossh -M 7291 -gCNR 7290:localhost:22 -i ~/.ssh/id_rsa user@W &

这样就可以通过服务器W的7290端口访问服务器N的22端口:

ssh -p 7290 user@W

当然,用同样方法还可以构建其他应用,比如80端口等。

参考:https://blog.csdn.net/upshi/article/details/78630285

ubuntu 18.04中设置dns server

ubuntu 18.04及之后的版本,发生的一个变化,就是网络地址设置的更改。

在之前的版本,修改ip地址、dns地址等都可以在/etc/network/interface中进行修改,dns可以在/etc/resolv.conf进行修改。而在18.04版本后,ubuntu启动了netplan系统,所有这些修改都使用netplan进行调整,具体配置都放在/etc/netplace/*.yaml文件中:

network:
  version: 2
  renderer: networkd
  ethernets:
    eno1:
      addresses: [ 210.77.77.35/24 ]
      gateway4: 210.77.77.254
      nameservers:
        addresses: [114.114.114.114,210.77.68.240]

参考:https://www.techrepublic.com/article/how-to-set-dns-nameservers-in-ubuntu-server-18-04/

split:分割文本文件

在数据处理时有时需要将一个大的数据集分为几个部分,交给不同机器或不同账号进行处理,之前我都是用sed或vi进行分割,没想到linux有一个专门这样的工具进行处理:split。

split的用法也非常简单,可以按行分割也可以按大小分割。

$ split --help
Usage: split [OPTION]... [FILE [PREFIX]]
Output pieces of FILE to PREFIXaa, PREFIXab, ...;
default size is 1000 lines, and default PREFIX is 'x'.

With no FILE, or when FILE is -, read standard input.

Mandatory arguments to long options are mandatory for short options too.
  -a, --suffix-length=N   generate suffixes of length N (default 2)
      --additional-suffix=SUFFIX  append an additional SUFFIX to file names
  -b, --bytes=SIZE        put SIZE bytes per output file
  -C, --line-bytes=SIZE   put at most SIZE bytes of records per output file
  -d                      use numeric suffixes starting at 0, not alphabetic
      --numeric-suffixes[=FROM]  same as -d, but allow setting the start value
  -e, --elide-empty-files  do not generate empty output files with '-n'
      --filter=COMMAND    write to shell COMMAND; file name is $FILE
  -l, --lines=NUMBER      put NUMBER lines/records per output file
  -n, --number=CHUNKS     generate CHUNKS output files; see explanation below
  -t, --separator=SEP     use SEP instead of newline as the record separator;
                            '\0' (zero) specifies the NUL character
  -u, --unbuffered        immediately copy input to output with '-n r/...'
      --verbose           print a diagnostic just before each
                            output file is opened
      --help     display this help and exit
      --version  output version information and exit

The SIZE argument is an integer and optional unit (example: 10K is 10*1024).
Units are K,M,G,T,P,E,Z,Y (powers of 1024) or KB,MB,... (powers of 1000).

CHUNKS may be:
  N       split into N files based on size of input
  K/N     output Kth of N to stdout
  l/N     split into N files without splitting lines/records
  l/K/N   output Kth of N to stdout without splitting lines/records
  r/N     like 'l' but use round robin distribution
  r/K/N   likewise but only output Kth of N to stdout

GNU coreutils online help: <http://www.gnu.org/software/coreutils/>
Full documentation at: <http://www.gnu.org/software/coreutils/split>
or available locally via: info '(coreutils) split invocation'

简单而言,我将large.csv按照每个2000行进行分割,输入文件名按数字形式命名,则可以:

split -l 2000 -d large.csv

cron脚本中date命令问题

在shell中可以正常执行的命令,转移到cron中让其定时运行发现存在问题,即有错误提示,导致命令不执行。

d=`date -d “1 day ago” ‘+%Y-%m-%d’` && python3 -u regiondata.py –regionfile=region.id –date=$d

此命令问题在于d变量不能获取到,而在shell下执行则没有问题。网上搜索也有同样的问题:

https://unix.stackexchange.com/questions/29578/how-can-i-execute-date-inside-of-a-cron-tab-job

发现解决方案也比较简单,即在%符号前加上\转义,即可执行命令:

d=`date -d “1 day ago” ‘+\%Y-\%m-\%d’` && python3 -u regiondata.py –regionfile=region.id –date=$d