0%

查询表空间状态:
[sql]
sql> select tablespace_name,status from dba_tablespaces;
[/sql]

修改表空间状态为READ ONLY:
[sql]
sql> alter tablespace tablespace_name read only;
[/sql]

表空间置为READ ONLY之后,不再发生任何变化,只需保存一份有效的备份即可,可以使用RMAN,也可以使用OS直接拷贝数据文件来备份只读表空间。

之后日常备份时就可以skip readonly来忽略掉只读表空间的备份,加速备份速度。

但恢复数据库时记得要check readonly,即使没有只读表空间,恢复仍然会成功,但open数据库会出现错误。

如果不使用check readonly,记得要将只读表空间的数据文件拷贝到相应的位置之后再recover数据库。

References:
[1]Oracle Read-only Tablespace(只读表空间)
[2](09)常被人遗忘的只读表空间
[3]Database Backup and Recovery Basics
[4]只读表空间的备份与恢复
[5]READ ONLY Tablespace Restore and Recovery
[6]Backing up, Restoring and Recovering Read Only tablespaces with RMAN
[7]Read Only Tablespaces and BACKUP OPTIMIZATION
[8]Rman管理命令

===
[erq]

python脚本在shell下运行的好好的,作为crontab任务运行就出错,import cx_Oracle的时候出错:

1
ImportError: libclntsh.so.12.1: cannot open shared object file: No such file or directory

明显是库路径的问题。

crontab运行程序时,其环境变量与用户的环境变量是不同的,有自己的变量环境,因此需要为crontab设置正确的环境变量,脚本才能正确运行。

python脚本中使用os.environ或者os.putenv来设置环境变量是没用的,反正在py脚本中正确设置了LD_LIBRARY_PATH变量,仍然无法解决问题。

有这么几个方法来设置crontab的环境变量:

第一种

可以在crontab配置文件中添加环境变量,但是不能用变量,类似$PATH这种,只能照实写。
类似如下:

1
2
3
4
5
6
ORACLE_HOME=/opt/oracle/instantclient_12_1
LD_LIBRARY_PATH=/opt/oracle/instantclient_12_1
PATH=/opt/oracle/instantclient_12_1
TNS_ADMIN=/opt/oracle/instantclient_12_1
SQLPATH=/opt/oracle/instantclient_12_1
NLS_LANG=AMERICAN_AMERICA.AL32UTF8

第二种

写一个bash脚本来中转一下,bash脚本中再调用py脚本,类似如下:

1
2
3
4
#!/bin/bash
export ORACLE_HOME=/opt/oracle/instantclient_12_1
source /home/xxx/.mybashrc
/home/xxx/py/business_notify.py "$@"

第三种

直接在crontab配置任务要执行的命令行上添加环境变量,类似如下:

1
*/10 * * * * LD_LIBRARY_PATH=/opt/oracle/instantclient_12_1 TNS_ADMIN=/opt/oracle/instantclient_12_1 /home/xxx/py/business_notify.py

推荐第一种

一般crontab运行的脚本中尽量不要依赖环境变量,使用绝对路径为佳。

===
[erq]

最近版本的即时客户端已经没有了tnsping这个命令,可以从相应版本的客户端或服务器bin目录中拷贝此文件,或者用脚本简单的替代:

1
2
3
4
tnsping >/dev/null 2>&1 
tnsping() {
sqlplus -L -S x/x@$1 </dev/null grep ORA- (grep -v ORA-01017 echo OK)
}

将此段脚本放入.profile或.bashrc即可。

又或者直接测试一下服务器的1521端口是否正常开放:

1
2
3
4
$ telnet a.b.c.d 1521
Trying a.b.c.d...
Connected to a.b.c.d.
Escape character is '^\]'.

这样就说明oracle监听是正常的。

===
[erq]

当ssh,vnc都不能访问客户机时,serial console可以提供另一种访问客户机的途径。

客户机serial console配置

/etc/inittab文件打开或添加如下行:

1
T0:23:respawn:/sbin/getty -L ttyS0 38400 vt100

/etc/securetty文件中确保列出了ttyS0:

1
ttyS0

/etc/default/grub文件添加:

1
2
3
GRUB_CMDLINE_LINUX='console=tty0 console=ttyS0,38400n8'
GRUB_TERMINAL=serial
GRUB_SERIAL_COMMAND="serial --speed=38400 --unit=0 --word=8 --parity=no --stop=1"

波特率是38400,没有奇偶校验,停止位是1

使用virsh来连接客户机串行控制台比较简单,应该也可以重定向客户机的串行端口到主机。

References:
[1]Debian Linux: Set a Serial Console
[2]Working with the serial console
[3]qemu(-kvm) monitor and serial console over sockets with minicom

===
[erq]

主机通过virtio上的9p文件系统以及文件系统设备,可以将主机上的文件系统导出给客户机来挂载使用

v9fs是plan 9 9p远程文件系统协议的实现

主机配置

在客户机启动命令上新添加fsdev和device选项

1
2
-fsdev local,security_model=passthrough,id=fsdev0,path=/mnt/share 
-device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=hostshare

这样导出了主机的/mnt/share目录供客户机来存取

客户机配置

客户机需要在内核中开启9P文件系统相关选项,可以这样查看:

1
2
3
4
5
6
7
8
9
$ cat /boot/config-$(uname -r) grep 9P
CONFIG_NET_9P=m
CONFIG_NET_9P_VIRTIO=m
CONFIG_NET_9P_RDMA=m
# CONFIG_NET_9P_DEBUG is not set
CONFIG_9P_FS=m
CONFIG_9P_FSCACHE=y
CONFIG_9P_FS_POSIX_ACL=y
CONFIG_9P_FS_SECURITY=y

可以看到9P配置成了内核模块的形式,然后就可以挂载主机的目录来使用了:

1
# mount -t 9p -o trans=virtio\[,version=9p2000.L\] hostshare /mnt/point

hostshare就是主机导出的挂载点的名称,此处将其挂载到客户机的/mnt/point。
version选项是可选的。

References:
[1]Example Sharing Host files with the Guest
[2]Documentation/9psetup
[3]v9fs: Plan 9 Resource Sharing for Linux

===
[erq]

通过rlwrap可以使sqlplus具有具有命令历史回溯和命令行编辑功能,通过提供自动完成字典,可以更进一步使sqlplus具有tab自动补全/完成功能。

德国一个哥们写了rlwrap_ext for oralce可以使sqlplus自动补全sql关键字,oracle视图、表、包等等,比较全面。

下载

可以直接下载最新的版本

1
$ wget http://www.linuxification.at/download/rlwrap-extensions-V12-0.03.tar.gz

安装

1
2
$ sudo tar zxvf rlwrap-extensions-V12-0.03.tar.gz -C /usr/local/share/rlwrap/completions
$ sudo cp /usr/local/share/rlwrap/completions/sql+ /usr/local/bin/

然后使用sql+替代sqlplus就可以了。

References:
[1]rlwrap_ext for oracle

===
[erq]

最常见的原因是process和session数量设置过低。

查看修改process参数

1
2
3
4
5
6
7
8
9
10
> show parameter process

NAME TYPE VALUE
------------------------------------ --------------------------------- -------------------
aq_tm_processes integer 0
db_writer_processes integer 3
gcs_server_processes integer 0
job_queue_processes integer 20
log_archive_max_processes integer 2
processes integer 150

偏低,修改process参数

1
> alter system set processes=1000 scope = spfile;

这里无法直接修改内存值,也就是不能使用scope=both,否则会有提示:

1
ORA-02095: specified initialization parameter cannot be modified

查看修改session参数

查看

1
2
3
4
5
6
7
8
9
10
11
12
> show parameter session
NAME TYPE VALUE
------------------------------------ --------------------------------- --------------------
java_max_sessionspace_size integer 0
java_soft_sessionspace_limit integer 0
license_max_sessions integer 0
license_sessions_warning integer 0
logmnr_max_persistent_sessions integer 1
session_cached_cursors integer 20
session_max_open_files integer 10
sessions integer 170
shared_server_sessions integer

修改

1
> alter system set sessions=1105 scope = spfile;

sessions是个派生值,由processes的值决定,公式sessions=1.1*process + 5

因为修改的是spfile,所以并不会立即生效,只有重新启动oracle,设置才会生效。

===
[erq]

swift已经支持ubuntu,也可以在debian上安装

下载

下载ubuntu 15.10版本的安装包

1
$ wget https://swift.org/builds/swift-2.2-release/ubuntu1510/swift-2.2-RELEASE/swift-2.2-RELEASE-ubuntu15.10.tar.gz

解压重新打包

1
2
3
4
$ tar zxvf swift-2.2-RELEASE-ubuntu15.10.tar.gz
$ cd swift-2.2-RELEASE-ubuntu15.10
$ tar czvf swift-2.2.tar.gz usr
$ sudo alien -v swift-2.2.tar.gz

会生成deb安装包swift_2.2-2_all.deb

安装

1
$ sudo dpkg -i swift_2.2-2_all.deb

测试

新建main.swift文件

1
print("hello swift")

编译

1
$ swiftc main.swift -o main.s

查看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ file main.s
main.s: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked,
interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32,
BuildID\[sha1\]=9ed9fa8e5accc18cd0a4482b465aecf814a2a114, not stripped

$ ldd main.s
linux-vdso.so.1 (0x00007ffe06af4000)
libswiftCore.so => /usr/lib/swift/linux/libswiftCore.so (0x00007fc4d764f000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fc4d72bc000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fc4d6fbd000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fc4d6da7000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fc4d6a03000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fc4d67e5000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fc4d65e1000)
libicuuc.so.55 => /usr/lib/x86_64-linux-gnu/libicuuc.so.55 (0x00007fc4d624d000)
libicui18n.so.55 => /usr/lib/x86_64-linux-gnu/libicui18n.so.55 (0x00007fc4d5dea000)
libbsd.so.0 => /lib/x86_64-linux-gnu/libbsd.so.0 (0x00007fc4d5bd4000)
/lib64/ld-linux-x86-64.so.2 (0x0000557356b81000)
libicudata.so.55 => /usr/lib/x86_64-linux-gnu/libicudata.so.55 (0x00007fc4d411c000)

也可以动态解释执行

1
2
3
4
5
$ swift
Welcome to Swift version 2.2 (swift-2.2-RELEASE). Type :help for assistance.
1> print("hello, swift")
hello, swift
2> :q

===
[erq]

python有两个队列实现,分别是queue.Queue和mulitiprocess.Queue。

queue.Queue是线程安全的,用于线程间数据同步,而mulitiprocess.Queue是用于多进程间数据通讯的。如果在多进程间使用queue.Queue是无法共享数据的,每个进程会有一个单独的队列副本。

因为queue.Queue用于多线程数据同步,而mulitiprocess.Queue用于多进程数据同步。

python3中线程队列的名字为queue,而python2中其名字为Queue。

python中的list和dict不是线程安全的。

task_done与join

queue.Queue有一个join方法可以阻塞当前线程,直到队列中所有的item都处理完成了,所以需要每处理一个队列的item,调用一次队列的task_done方法,当队里的所有元素都标记为处理过了,join方法会从等待中返回。

如果不调用join方法,也就无需调用task_done方法了。

mulitiprocess.Queue并没有join特性,如需要此特性,应该使用multiprocessing.JoinableQueue队列

===
[erq]

配置文件访问无线网络

在/etc/network/interfaces文件可以配置要默认访问的无线热点:

动态获取ip:

1
2
3
4
5
# wireless
auto wlan0
iface wlan0 inet dhcp
wpa-ssid ESSID/SSID
wpa-psk pre-shared-key

配置静态ip:

1
2
3
4
5
6
7
8
9
10
# wireless
auto wlan0
iface wlan0 inet static
address 192.168.1.110
netmask 255.255.255.0
network 192.168.1.0
broadcast 192.168.1.255
gateway 192.168.1.1
wpa-ssid ESSID/SSID
wpa-psk pre-shared-key

重新启动网络服务即可连接到默认的热点。

命令行手动扫描并连接到热点

扫描热点:

1
2
# iwlist wlan0 scan
# iw dev wlan0 scan

连接到热点:

1
# wpa_supplicant -i wlan0 -c <(wpa_passphrase ESSID pre-shared-key) -B

动态获取ip:

1
# dhclient wlan0

设置静态ip:

1
2
# ip addr add 192.168.1.110/24 dev wlan0
# ip route add default via 192.168.1.1

===
[erq]