0%

cassandra集群以前运行于本地机房,现在需要扩展到云端,云主机添加为集群的新数据中心。因为并不是公有云,所有没有启动SSL认证和加密。

本地机房与云机房通过专线连接,并且本地只有两个互联ip地址可用。本地机房原集群内节点只使用私有网络地址,无法被云端访问。云端主机使用私有地址,云平台将私有地址映射到专线可以访问的“公有地址”,这里并不是真正的“公有地址”,仍然是一个大的私有网络,不过本地机房和云机房通过这些地址可以互访,所有这里也叫做“公有地址”

因此集群的本地机房节点通过NAT映射,将私有地址的7000和9042端口映射到公有地址,从而可以被云主机访问,同时做了端口回流,保证本地机房其他机器也可以通过公有地址访问节点。
如果不做或不能做端口回流,应该也可以使用iptables/nftables在集群内节点以及需要访问集群的客户机器上添加nat转换规则,从公有ip转换到对应的私有ip,这个没试。

这样本地机房和云机房的节点都有私有地址和映射后的公有地址,cassandra集群节点需要使用公有地址进行互访,但cassandra都无法直接监听公有地址。这需要配置cassandra.yaml,设置listen_address和rpc_address为私有地址,设置broadcast_address和broadcast_rpc_address为公有ip地址,但是listen_on_broadcast_address设置为false,因为各个节点并不能在公有ip上监听。这样当跨数据中心时使用公有ip通讯,但在本地网络内部可以使用私有网络。

cassandra-rackdc.properties配置文件可以打开prefer_local选项,这样可以优先使用本地网络,降低网络延迟。

配置实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
listen_address: 192.168.136.250
broadcast_address: 59.206.31.152
rpc_address: 192.168.136.250
broadcast_rpc_address: 59.206.31.152

seed_provider:
# Addresses of hosts that are deemed contact points.
# Cassandra nodes use this list of hosts to find each other and learn
# the topology of the ring. You must change this if you are running
# multiple nodes!
- class_name: org.apache.cassandra.locator.SimpleSeedProvider
parameters:
# seeds is actually a comma-delimited list of addresses.
# Ex: "<ip1>,<ip2>,<ip3>"
- seeds: "59.206.31.152,10.160.4.196,10.160.4.197"

这样本地数据中心和云数据中心就可以通过公有ip相互通讯了。
备注:rpc并不是必须的,只使用cql是可行的。

References:
[1]Using multiple network interfaces

brew upgrade升级了openssh以后,每次登录远程服务器都提示:

1
load pubkey "/Users/xxx/.ssh/id_rsa": invalid format

因为客户端根本就没存储公钥啊,为什么要读取公钥?公钥放在服务器端了啊

客户端重新生成对应的公钥,满足openssh的无理要求就可以了:

1
$ ssh-keygen -f ~/.ssh/id_rsa -y > ~/.ssh/id_rsa.pub

以前也没这问题。

因为某云在某个网络内没有debian安装源,所以只能使用本地源。
debian支持的软件包很多,amd64架构的dvd iso竟然有16张之多,bd格式iso则只有4张,这里使用dvd格式的iso。

首先,下载debian 10.1.0 amd64架构的dvd iso,http方式只能下载前三个iso,下载其他iso需要使用jigdo方式即时下载在线制作iso文件。

debian系统安装jigdo-file使用jigdo-lite命令,输入iso的jigdo文件url即可下载制作iso镜像。debian 10.1.0 dvd iso的jigdo下载地址在此
因为需要安装的包postgresql-11-postgis-2.5不在前三张dvd,所以使用jigdo下载了第四张dvd镜像。

然后,将四张dvd iso分别挂载到/media目录的挂载点:

1
2
3
4
# mount /path/to/debian-10.1.0-amd64-DVD-1.iso /media/cdrom1/
# mount /path/to/debian-10.1.0-amd64-DVD-2.iso /media/cdrom2/
# mount /path/to/debian-10.1.0-amd64-DVD-3.iso /media/cdrom3/
# mount /path/to/debian-10.1.0-amd64-DVD-4.iso /media/cdrom4/

也可以添加到/etc/fstab:

1
2
3
4
/srv/debsrcs/debian-10.1.0-amd64-DVD-1.iso/media/cdrom1udf,iso9660 loop 0 0
/srv/debsrcs/debian-10.1.0-amd64-DVD-2.iso/media/cdrom2udf,iso9660 loop 0 0
/srv/debsrcs/debian-10.1.0-amd64-DVD-3.iso/media/cdrom3udf,iso9660 loop 0 0
/srv/debsrcs/debian-10.1.0-amd64-DVD-4.iso/media/cdrom4udf,iso9660 loop 0 0

然后

1
# mount -a

编辑/etc/apt/sources.list文件,添加如下行:

1
2
3
4
deb \[ trusted=yes \] file:/media/cdrom1/ buster main contrib 
deb \[ trusted=yes \] file:/media/cdrom2/ buster main contrib
deb \[ trusted=yes \] file:/media/cdrom3/ buster main contrib
deb \[ trusted=yes \] file:/media/cdrom4/ buster main contrib

最后,apt update后正常安装软件即可,如果要安装的软件还是找不到,可能需要下载更多的dvd iso镜像。

使用rman convert database将oracle 10g 10.2.0.4 for windows x64环境下的数据库转换到oracle 10g 10.2.0.4 for linux x64环境下。

**注意:**无法使用standby备库来进行转换。

1、以只读方式打开数据库

1
2
3
SQL> shutdown immediate
SQL> startup mount
SQL> alter database open read only;

2、检查可转换性和标示外部对象。

使用DBMS_TDB.CHECK_DB检查数据库状态,是否可以顺利转换到目标平台:

1
2
3
4
5
6
7
8
9
SQL> set serveroutput on
SQL> declare
    db_ready boolean;
  begin
    /* db_ready is ignored, but with SERVEROUTPUT set to ON any 
     * conditions preventing transport will be output to console */
    db_ready := dbms_tdb.check_db('Linux x86 64-bit', dbms_tdb.skip_none);
  end;
/

DBMS_TDB.CHECK_DB返回TRUE表示可以转换到目标平台,返回FALSE则不可以,同时会输出不可已转换的原因。

使用DBMS_TDB.CHECK_EXTERNAL标识外部对象。

1
2
3
4
5
6
7
8
9
10
SQL> set serveroutput on
SQL> declare
     external boolean;
  begin
    /* value of external is ignored, but with SERVEROUTPUT set to ON
     * dbms_tdb.check_external displays report of external objects
     * on console */
    external := dbms_tdb.check_external;
  end;
/

如果有外部对象会在输出中显示出来。

3、转换数据库

可以在源数据库,也可以在目标数据库进行数据文件的转换。这里选择在目标数据库进行数据文件转换,这样可以减少源数据库的停止服务时间。

在源数据库执行rman convert database:

1
2
3
4
5
6
$ rman target sys/passwd@dbinst
RMAN> CONVERT DATABASE ON TARGET PLATFORM
CONVERT SCRIPT 'D:\\rman\\convertscript.rman'
TRANSPORT SCRIPT 'D:\\rman\\transportscript.sql'
new database 'orcl'
FORMAT 'D:\\rman\\%U';

命令执行完成会生成一个transport脚本用于在目标平台上创建数据库,一个pfile文件包含源数据库相同的参数配置,还生成一个convert脚本用于在目标平台上转换数据文件。

注意:在windows平台上只能使用windows系统路径名,包括FORMAT参数使用的路径,在linux平台上做数据库转换时,根据linux平台上oracle数据库的目录结构布局来相应修改生成的convertscript.rman,pfile和transportscript.sql。

3.1 convertscript.rman
生成的转换脚本类似如下:

1
2
3
4
5
6
7
8
9
10
11
RUN {

CONVERT DATAFILE 'E:\\ORACLE\\PRODUCT\\10.2.0\\DB_1\\DATABASE\\DIGITALSCANDATA.DAT'
FROM PLATFORM 'Microsoft Windows x86 64-bit'
FORMAT 'D:\\RMAN\\DATA_D-ORCL_I-1276927241_TS-DIGITALSCANDATA_FNO-38_HDV216EA';


CONVERT DATAFILE 'E:\\ORACLE\\PRODUCT\\10.2.0\\DB_1\\DATABASE\\DIGITALSCANDATA01.DAT'
FROM PLATFORM 'Microsoft Windows x86 64-bit'
FORMAT 'D:\\RMAN\\DATA_D-ORCL_I-1276927241_TS-DIGITALSCANDATA_FNO-39_HEV216EA';
...

根据目标平台文件系统布局,修改为:

1
2
3
4
5
6
7
8
9
10
11
RUN {

CONVERT DATAFILE '/mnt/data/database/DIGITALSCANDATA.DAT'
FROM PLATFORM 'Microsoft Windows x86 64-bit'
FORMAT '/u01/oradata/orcl/DATA_D-ORCL_I-1276927241_TS-DIGITALSCANDATA_FNO-38_HDV216EA';


CONVERT DATAFILE '/mnt/data/database/DIGITALSCANDATA01.DAT'
FROM PLATFORM 'Microsoft Windows x86 64-bit'
FORMAT '/u01/oradata/orcl/DATA_D-ORCL_I-1276927241_TS-DIGITALSCANDATA_FNO-39_HEV216EA';
...

/mnt/data/database目录下为从源库直接拷贝过来待转换的数据文件,转换完成的数据文件存储到/u01/oradata/orcl/目录下。

3.2 pfile
生成的INIT文件:

1
2
3
4
5
6
7
8
9
10
# Please change the values of the following parameters:

control_files = "D:\\RMAN\\CF_D-ORCL_ID-1276927241_00V216EA"

db_recovery_file_dest = "D:\\RMAN\\flash_recovery_area"

db_recovery_file_dest_size= 2147483648

audit_file_dest = "D:\\RMAN\\ADUMP"
...

相应修改为:

1
2
3
4
5
6
7
8
9
10
# Please change the values of the following parameters:

control_files = "/u01/oradata/orcl/CF_D-ORCL_ID-1276927241_00V216EA"

db_recovery_file_dest = "/u01/app/oracle/flash_recovery_area"

db_recovery_file_dest_size= 2147483648

audit_file_dest = "/u01/app/oracle/admin/orcl/adump"
...

3.3 transportscript.sql
生成的建库脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
-- The following commands will create a new control file and use it
-- to open the database.
-- Data used by Recovery Manager will be lost.
-- The contents of online logs will be lost and all backups will
-- be invalidated. Use this only if online logs are damaged.

-- After mounting the created controlfile, the following SQL
-- statement will place the database in the appropriate
-- protection mode:
-- ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE PERFORMANCE

STARTUP NOMOUNT PFILE='D:\\RMAN\\INIT_00V216EA_1_0.ORA'
CREATE CONTROLFILE REUSE SET DATABASE "ORCL" RESETLOGS FORCE LOGGING ARCHIVELOG
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 8
MAXLOGHISTORY 14616
LOGFILE
GROUP 1 'D:\\RMAN\\ARCH_D-ORCL_ID-1276927241_S-517_T-1_A-1017328065_00V216EA' SIZE 50M,
GROUP 2 'D:\\RMAN\\ARCH_D-ORCL_ID-1276927241_S-515_T-1_A-1017328065_00V216EA' SIZE 50M,
GROUP 3 'D:\\RMAN\\ARCH_D-ORCL_ID-1276927241_S-516_T-1_A-1017328065_00V216EA' SIZE 50M
DATAFILE
'D:\\RMAN\\DATA_D-ORCL_I-1276927241_TS-SYSTEM_FNO-1_IKV216EF',
...

相应修改为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
STARTUP NOMOUNT PFILE='/u01/app/oracle/admin/orcl/pfile/INIT_00V216EA_1_0.ORA'
CREATE CONTROLFILE REUSE SET DATABASE "ORCL" RESETLOGS FORCE LOGGING ARCHIVELOG
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 8
MAXLOGHISTORY 14616
LOGFILE
GROUP 1 '/u01/oradata/orcl/ARCH_D-ORCL_ID-1276927241_S-517_T-1_A-1017328065_00V216EA' SIZE 50M,
GROUP 2 '/u01/oradata/orcl/ARCH_D-ORCL_ID-1276927241_S-515_T-1_A-1017328065_00V216EA' SIZE 50M,
GROUP 3 '/u01/oradata/orcl/ARCH_D-ORCL_ID-1276927241_S-516_T-1_A-1017328065_00V216EA' SIZE 50M
DATAFILE
'/u01/oradata/orcl/DATA_D-ORCL_I-1276927241_TS-SYSTEM_FNO-1_IKV216EF',
...

3.4 实施转换

首先,将源数据库的数据文件全部拷贝到目标数据库(因为只拷贝数据文件,可以从standby备库拷贝),然后根据数据文件所在的路径相应的修改convert脚本,然后使用rman执行转换脚本,转换后的数据文件存储在format指定的位置。

目标平台必须要有一个已经存在的数据库,因为rman需要连接到target数据库才能工作:

1
2
$ rman target / nocatalog
RMAN> @CONVERTSCRIPT.RMAN

然后,根据目标平台环境修改生成的pfile文件参数
最后,执行transportscript.sql生成目标数据库。使用utlirp.sql和utlrp.sql脚本重新编译目标平台数据的PL/SQL模块。
先关闭已有的数据库,oracle实例每次只能启动一个数据库:

1
2
$ sqlplus / as sysdba;
SQL> @TRANSPORTSCRIPT.SQL

脚本最后最自动调用utlirp.sql和utlrp.sql编译模块。

其中遇到了错误:

1
2
ORA-27102: out of memory
Linux-x86_64 Error: 28: No space left on device

是因为内核参数kernel.shmall设置为了2097152,oracle最大只能使用2097152*4096=8GB的系统内存,而INIT文件中设置的SGA大小超过了10GB,重新设置kernel.shmall为4194304可以最大允许16GB,问题解决。

数据库的sys用户是由本地密码文件验证的,数据库转换时并没有涉及到sys用户,因此需要本地重新为sys用户新建一个密码文件:

1
$ orapwd file=$ORACLE_HOME/dbs/orapw$ORACLE_SID password=passwd_for_sys force=y

至此,数据库转换完成,最后以OPEN RESETLOGS方式打开新数据库。

References:
[1]15 RMAN Cross-Platform Transportable Databases and Tablespaces
[2]使用RMAN Convert Database命令实现跨平台的数据库迁移

oracle 10g已经太老了,直接在debian buster上安装是不可以的。但可以迂回一下,先在debian squeeze上安装,然后将安装好的oracle文件打包拷贝到debian buster相同的目录结构下,并且使用相同的用户和组权限。

一、安装

1、安装squeeze及支持组件

下载squeeze最后的版本6.0.10,脱机安装完毕后,编辑/etc/apt/sources.list使用以下源:

1
deb http://archive.debian.org/debian squeeze main contrib non-free

其他镜像源都已不可用,只有此归档源可以。

安装支持组件

1
$ sudo apt-get install build-essential ia32-libs ia32-libs-dev libc6 libc6-i386 libc6-dev libc6-dev-i386 rpm libstdc++5 libaio1 gcc-multilib xauth unzip

创建符号链接

1
2
3
# ln -sf /usr/bin/awk /bin/awk
# ln -sf /usr/bin/rpm /bin/rpm
# ln -sf /usr/bin/basename /bin/basename

2、创建用户和组

1
2
3
4
5
6
7
8
9
# groupadd oinstall
# groupadd dba
# adduser oracle
# usermod -g oinstall -G dba oracle
//# useradd -g oinstall -G dba oracle
//# passwd oracle
# groupadd nobody
# id oracle
uid=1001(oracle) gid=1001(oinstall) groups=1001(oinstall),1002(dba)

3、修改内核参数
添加文件/etc/sysctl.d/oracle.conf:

1
2
3
4
5
6
7
8
9
10
11
12
fs.file-max = 65536
fs.aio-max-nr = 1048576
# semaphores: semmsl, semmns, semopm, semmni
kernel.sem = 250 32000 100 128
# (Oracle recommends total machine Ram -1 byte)
kernel.shmmax = 2147483648
kernel.shmall = 4194304
kernel.shmmni = 4096
net.ipv4.ip_local_port_range = 1024 65000
# dba group
vm.hugetlb_shm_group = 1002
vm.nr_hugepages = 64

4、修改资源限制
添加文件/etc/security/limits.d/oracle.conf:

1
2
3
4
5
6
oracle soft nproc 2047
oracle hard nproc 16384
oracle soft nofile 1024
oracle hard nofile 65536
oracle soft memlock 204800
oracle hard memlock 204800

5、准备目录结构

1
2
3
4
5
6
7
#mkdir -p /u01/app/oracle
#chown -R oracle:oinstall /u01

#chmod -R 775 /u01/app/oracle

#usermod -d /u01/app/oracle oracle
#usermod -s /bin/bash oracle

从其他用户主目录拷贝.profile,.bashrc,.bash_logout文件到oracle用户主目录

6、安装10.2.0.1
通过X11 forward远程安装,安装路径设定为/u01/app/oracle/product/10.2.0/db_1
只安装软件,不创建数据库,忽略ins_emdb.mk错误继续安装

1
2
3
4
$ ssh -XC oracle@host
$ gunzip 10201_database_linux_x86_64.cpio.gz
$ cpio -idmv < 10201_database_linux_x86_64.cpio
$ database/runInstaller -ignoreSysPrereqs

7、升级10.2.0.4

1
2
$ unzip p6810189_10204_Linux-x86-64.zip
$ Disk1/runInstaller -ignoreSysPrereqs

升级时选择同一个实例,即OraDb10g_home1

二、移植

1、在squeeze上打包

1
2
$ tar zcvf /tmp/oracle.tar.gz /u01
$ tar zcvf /tmp/oracle_conf.tar.gz /etc/oratab /etc/oraInst.loc /usr/local/bin/ /etc/sysctl.d/oracle.conf /etc/security/limits.d/oracle.conf

2、buster上创建用户组

1
2
3
4
5
6
7
#groupadd oinstall
#groupadd dba
# adduser oracle
# usermod -g oinstall -G dba oracle
//# useradd -g oinstall -G dba oracle
//# passwd oracle
#groupadd nobody

3、准备目录结构

1
2
3
4
5
6
7
8
#mkdir -p /u01/app/oracle
#chown -R oracle:oinstall /u01
#chown -R oracle:oinstall /u01/app
#chown -R oracle:oinstall /u01/app/oracle
#chmod -R 775 /u01/app/oracle

#usermod -d /u01/app/oracle oracle
#usermod -s /bin/bash oracle

4、buster上还原oracle
将oracle.tar.gz和oracle_conf.tar.gz拷贝到/tmp目录,以oracle用户执行

1
$ tar zxvf /tmp/oracle.tar.gz -C /

以root用户执行:

1
# tar zxvf /tmp/oracle_conf.tar.gz -C /

5、oracle用户配置
.bashrc添加如下环境变量

1
2
3
4
5
6
7
8
9
export ORACLE_SID=orcl
export ORACLE_UNQNAME=orcl
export ORACLE_OWNER=oracle
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/10.2.0/db_1
export PATH=$ORACLE_HOME/bin:$PATH
export TNS_ADMIN=$ORACLE_HOME/network/admin
export SQLPATH=$ORACLE_HOME/scripts
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH

安装完成,经测试可以正常创建数据库,正常使用。

References:
[1]OracleDB

The Linux terminals that are provided by the console device drivers include line-mode terminals, block-mode terminals, and full-screen mode terminals.

On a full-screen mode terminal, pressing any key immediately results in data being sent to the terminal. Also, terminal output can be positioned anywhere on the screen. This feature facilitates advanced interactive capability for terminal-based applications like the vi editor. It works in raw mode default,can set to cbreak mode also.

On a line-mode terminal, the user first types a full line, and then presses Enter to indicate that the line is complete. The device driver then issues a read to get the completed line, adds a new line, and hands over the input to the generic TTY routines. It works in cooked mode default.

The terminal that is provided by the 3270 terminal device driver is a traditional IBM® mainframe block-mode terminal. Block-mode terminals provide full-screen output support and users can type input in predefined fields on the screen. Other than on typical full-screen mode terminals, no input is passed on until the user presses Enter. The terminal that is provided by the 3270 terminal device driver provides limited support for full-screen applications. For example, the ned editor is supported, but not vi.

References:
[1]Terminal mode
[2]Confusion about raw vs. cooked terminal modes?
[3]cooked mode
[4]What goes into the terminal’s ‘cbreak’ and ‘raw’ modes

insert usb stick, the device name of usb stick is /dev/disk2

1
2
3
4
5
6
7
8
$ diskutil list #find device name of usb stick
/dev/disk2 (external, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *32.2 GB disk2
1: EFI TAILS 8.6 GB disk2s1
$ diskutil unmountdisk /dev/disk2
$ sudo dd if=tails-amd64-4.3.img of=/dev/disk2 bs=64m
$ diskutil eject /dev/disk2

dnscrypt-proxy内建doh服务器,可以为本机或外部提供doh服务

本地使用

先生成自签证书

1
$ openssl req -x509 -nodes -newkey rsa:2048 -days 5000 -sha256 -keyout localhost.pem -out localhost.pem

编辑/usr/local/etc/dnscrypt-proxy.toml,添加

1
2
3
4
5
\[local_doh\]
listen_addresses = \['127.0.0.1:3000'\]
path = "/dns-query"
cert_file = "localhost.pem"
cert_key_file = "localhost.pem"

重启dnscrypt-proxy服务

1
$ sudo brew services restart dnscrypt-proxy

打开firefox浏览器,访问https://127.0.0.1:3000/dns-query并接受自签证书
然后输入about:config配置如下选项:

1
2
3
4
5
network.trr.custom_uri = https://127.0.0.1:3000/dns-query
network.trr.uri = https://127.0.0.1:3000/dns-query
network.trr.resolvers = \[{ "name": "local", "url": "https://127.0.0.1:3000/dns-query" }\]
network.trr.mode = 3
network.security.esni.enabled = true

重新启动firefox,访问Browsing Experience Security Check检查浏览器设置结果。

References:
[1]Local DoH

使用ssl_preread分流请求时,真正的服务程序无法获取到真实的客户ip,这时候可以借助proxy_protocol来获取真实的客户ip地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
http {
proxy_headers_hash_bucket_size 6400; #添加此行
include mime.types;
default_type application/octet-stream;

log_format main '$proxy_protocol_addr - $remote_user \[$time_local\] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"'; #修改此行,用$proxy_protocol_addr替换$remote_addr
...

server {
listen 8443 ssl http2 proxy_protocol default_server;#此行添加proxy_protocol指令
...
# ssl preread for request certs
stream {
map $ssl_preread_alpn_protocols $tls_port {
~\\bacme-tls/1\\b 10443;
default 8443;
}
server {
listen 443;
listen \[::\]:443;
proxy_pass 127.0.0.1:$tls_port;
proxy_protocol on; #添加此行
ssl_preread on;
}
}

这样access日志就可以获取到真实的客户ip地址($proxy_protocol_addr)了,但是nginx的error日志格式无法改变,只能更改日志级别,因此preread之后的错误日志就没办法了。