Read by other session等待事件

今天中午发现福建生产库报负载有点异常,处理思路记录下来:
1、使用top命令查看系统,发现系统负载是比以前要搞(平时都是1以下,今天已经稳定在4左右,总是有部分进城占用cpu比较高,系统cpu等待明显)
1.1)第一反应是有人执行sql导致,抓取占用cpu较高的spid,查询出对应sql,发现都是一些比较简单sql
1.2)查询这些spid的客户端是应用服务器,也就是说不是人为执行,那在一个稳定的系统中,不会出现sql突然改变的原因
2、查询系统是否因为有对象被阻塞导致,查询发现无对象被阻塞
3、查询系统等待事件,发现几十个read by other session等待,都是从一台web的服务器上连接过来
SELECT * FROM v$session WHERE wait_class#<>6;
4、read by other session等待事件比较陌生,幸好伴随有db file sequential read的等待事件,初步怀疑读取数据到内存中等待导致
5、查询资料发现
read by other session Definition: When information is requested from the database, Oracle will first read the data from disk into the database buffer cache. If two or more sessions request the same information, the first session will read the data into the buffer cache while other sessions wait.
In previous versions this wait was classified under the “buffer busy waits” event.
However, in Oracle 10.1 and higher this wait time is now broken out into the “read by other session” wait event. Excessive waits for this event are typically due to several processes repeatedly reading the same blocks, e.g. many sessions scanning the same index or performing full-table scans on the same table. Tuning this issue is a matter of finding and eliminating this contention.
Confio concludes with a summary that “read by other session waits” are very similar to buffer busy waits
When a session waits on the “read by other session” event, it indicates a wait for another session to read the data from disk into the Oracle buffer cache.
If this happens too often the performance of the query or the entire database can suffer. Typically this is caused by contention for “hot” blocks or objects so it is imperative to find out which data is being contended for. Once that is known this document lists several alternative methods for solving the issue.
总结:两个或者多个会话同时需要把硬盘中的对象装载到data buffer中,当其中一个会话把对象装入后,其他会话就处于read by other session等待状态;这个是oracle 10g 从oracle 9i的buffer busy waits中分离出来的,也是需要一种热块现象
6、根据FILE#,BLOCK#查询热块对象
SELECT OWNER, SEGMENT_NAME, SEGMENT_TYPE, TABLESPACE_NAME, A.PARTITION_NAME
FROM DBA_EXTENTS A
WHERE FILE_ID = &FILE_ID
AND &BLOCK_ID BETWEEN BLOCK_ID AND BLOCK_ID + BLOCKS – 1;
7、通过这个对象查询出对应的操作语句
select * from v$sql where upper(sql_text) like ‘%object_name%’;
8、直接查找热点块对象语句

SELECT *
  FROM (SELECT O.OWNER, O.OBJECT_NAME, O.OBJECT_TYPE, SUM(TCH) TOUCHTIME,
          FROM X$BH B, DBA_OBJECTS O
         WHERE B.OBJ = O.DATA_OBJECT_ID
           AND B.TS# > 0
         GROUP BY O.OWNER, O.OBJECT_NAME, O.OBJECT_TYPE
         ORDER BY SUM(TCH) DESC)
 WHERE ROWNUM <= 10
--或者
SELECT E.OWNER, E.SEGMENT_NAME, E.SEGMENT_TYPE
  FROM DBA_EXTENTS E,
       (SELECT *
          FROM (SELECT ADDR, TS#, FILE#, DBARFIL, DBABLK, TCH
                  FROM X$BH
                 ORDER BY TCH DESC)
         WHERE ROWNUM < 11) B
 WHERE E.RELATIVE_FNO = B.DBARFIL
   AND E.BLOCK_ID <= B.DBABLK
   AND E.BLOCK_ID + E.BLOCKS > B.DBABLK;

9、直接查找热点块操作语句

SELECT /*+rule*/
 HASH_VALUE, SQL_TEXT
  FROM V$SQLTEXT
 WHERE (HASH_VALUE, ADDRESS) IN
       (SELECT A.HASH_VALUE, A.ADDRESS
          FROM V$SQLTEXT A,
               (SELECT DISTINCT A.OWNER, A.SEGMENT_NAME, A.SEGMENT_TYPE
                  FROM DBA_EXTENTS A,
                       (SELECT DBARFIL, DBABLK
                          FROM (SELECT DBARFIL, DBABLK
                                  FROM X$BH
                                 ORDER BY TCH DESC)
                         WHERE ROWNUM < 11) B
                 WHERE A.RELATIVE_FNO = B.DBARFIL
                   AND A.BLOCK_ID <= B.DBABLK
                   AND A.BLOCK_ID + A.BLOCKS > B.DBABLK) B
         WHERE A.SQL_TEXT LIKE '%' || B.SEGMENT_NAME || '%'
           AND B.SEGMENT_TYPE = 'TABLE')
 ORDER BY HASH_VALUE, ADDRESS, PIECE;

10、也可以通过awr查询出来相关对象
Segments by Buffer Busy Waits
语句需要通过这些等待对象进行判断
到了1点钟左右,数据库read by other session等待事件消失,数据库恢复正常负载(因为系统还能够承受,所以当时没有采用kill进程的方法)
事后对查询出来的热点块对象和操作语句,已经访问服务器和开发确认的结果为:这个是一个报表功能,但是平时没有人用,所以也没有关注,今天突然被人用了下,导致这个问题发生,他们承诺在升级下个版本中解决这个问题。

Mysql Merge表

MERGE引擎类型允许你把许多结构相同的表合并为一个表。然后,你可以执行查询,从多个表返回的结果就像从一个表返回的结果一样。每一个合并的表必须有同样的表定义。
MERGE存储引擎在下面这种使用场合会最为有用,如果需要把日志纪录不停的录入MySQL数据库,并且每天、每周或者每个月都创建一个单一的表,而且要制作来自多个表的合计查询,MERGE表这时会非常有效。然而,这项功能有局限性。你只能合并MyISAM表而且必须严格遵守相同的表定义的限制。
创建方法如下:
mysql> create table t1(id int not null primary key,name varchar(20)) engine=myisam;
Query OK, 0 rows affected (0.03 sec)
mysql> create table t2(id int not null primary key,name varchar(20)) engine=myisam;
Query OK, 0 rows affected (0.00 sec)
mysql> create table mrg(id int not null primary key,name varchar(20)) engine=merge union(t1,t2) insert_method=first;
Query OK, 0 rows affected (0.00 sec)
测试:
1、在t1中插入数据
mysql> insert into t1 values(1,’tttttt’);
Query OK, 1 row affected (0.03 sec)
mysql> insert into t1 values(2,’tttttt’);
Query OK, 1 row affected (0.00 sec)
2、查询t1表
mysql> select * from t1;
+—-+——–+
| id | name |
+—-+——–+
| 1 | tttttt |
| 2 | tttttt |
+—-+——–+
2 rows in set (0.00 sec)
3、查询mrg表
mysql> select * from mrg;
+—-+——–+
| id | name |
+—-+——–+
| 1 | tttttt |
| 2 | tttttt |
+—-+——–+
2 rows in set (0.00 sec)
4、在t2中插入数据
mysql> insert into t2 values(1,’ssssss’);
Query OK, 1 row affected (0.00 sec)
5、查询t2表
mysql> select * from t2;
+—-+——–+
| id | name |
+—-+——–+
| 1 | ssssss |
+—-+——–+
1 row in set (0.00 sec)
6、查询mrg表
mysql> select * from mrg;
+—-+——–+
| id | name |
+—-+——–+
| 1 | tttttt |
| 2 | tttttt |
| 1 | ssssss |
+—-+——–+
3 rows in set (0.00 sec)
7、mrg表中插入数据并测试
mysql> insert into mrg values(1,’ssssss’);
ERROR 1062 (23000): Duplicate entry ‘1’ for key ‘PRIMARY’
mysql> insert into mrg values(2,’ssssss’);
ERROR 1062 (23000): Duplicate entry ‘2’ for key ‘PRIMARY’
mysql> insert into mrg values(3,’ssssss’);
Query OK, 1 row affected (0.00 sec)
mysql> insert into t2 values(4,’ssssss’);
Query OK, 1 row affected (0.00 sec)
mysql> insert into mrg values(4,’ssssss’);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t1;
+—-+——–+
| id | name |
+—-+——–+
| 1 | tttttt |
| 2 | tttttt |
| 3 | ssssss |
| 4 | ssssss |
说明:因为我们设置的 INSERT_METHOD为FIRST,因此插入数据进入t1表,而t1表中有主键,所以部分数据插入失败
1. 此表类似于SQL中的union机制。
2. 此表结构必须与基本表完全一致,包括列名、顺序。UNION表必须同属一个DATABASE。
3. 基本表类型必须是MyISAM。
4. 可以通过修改.mrg文件来修改MERGE表,每个基本表的名字占一行。注意:修改后要通过FLUSH TABLES刷新表缓存。
5. 对基本表的更改可以直接反映在此表上。
6. INSERT_METHOD的取值可以是: 0 不允许插入 FIRST 插入到UNION中的第一个表 LAST 插入到UNION中的最后一个表。(4.0之后可用)
7. 定义在它上面的约束没有任何作用,约束是由基本表控制的,例如两个基本表中存在着同样的一个Key值,那么在MERGE表中会有两个一样的Key值。

mysql通过substring_index和substring截取字符串

今天朋友问我mysql中有个列如下数值,怎么提出出其中ip地址
BGP-BeiJing-59.151.105.130-AD_read-YeZongKun
BGP-BeiJing-59.151.105.138_140_141-AD_LVS-YeZongKun
我提供sql语句如下:
select SUBSTRING(substring_index(‘BGP-BeiJing-59.151.105.130-AD_read-YeZongKun’,’-‘,3),(length(substring_index(‘BGP-BeiJing-59.151.105.130-AD_read-YeZongKun’,’-‘,2))+2));
SUBSTRING
SUBSTRING(str,pos,len)
SUBSTRING(str FROM pos FOR len)
SUBSTRING(str,pos)
SUBSTRING(str FROM pos)
mysql> SELECT SUBSTRING(‘Quadratically’,5);
-> ‘ratically’
mysql> SELECT SUBSTRING(‘foobarbar’ FROM 4);
-> ‘barbar’
mysql> SELECT SUBSTRING(‘Quadratically’,5,6);
-> ‘ratica’
mysql> SELECT SUBSTRING(‘Sakila’, -3);
-> ‘ila’
mysql> SELECT SUBSTRING(‘Sakila’, -5, 3);
-> ‘aki’
mysql> SELECT SUBSTRING(‘Sakila’ FROM -4 FOR 2);
-> ‘ki’
substring_index
substring_index(str,delim,count)
mysql> SELECT SUBSTRING_INDEX(‘www.mysql.com’, ‘.’, 2);
-> ‘www.mysql’
mysql> SELECT SUBSTRING_INDEX(‘www.mysql.com’, ‘.’, -2);
-> ‘mysql.com’

mysql 二进制文件安装注意事项

执行mysql_secure_installation报错
错误现象:
Enter current password for root (enter for none):
ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘/tmp/mysql.sock’ (2)
错误原因:
mysql_secure_installation ignores –socket
解决方案:
1)ln -s /var/run/mysqld/mysqld.sock /tmp/mysql.sock
2)修改mysql_secure_installation 脚本的do_query 函数(推荐处理方法)
do_query() {
echo “$1” >$command
#sed ‘s,^,> ,’ < $command # Debugging # mysql --defaults-file=$config <$command ----此行修改如下: mysql --defaults-extra-file=$config <$command return $? } 使用mysqld_safe启动msql错误
mysqld_safe启动报错
注意:如果想把错误日志放到专门的日志目录中,需要在my.cnf中添加log-error=path选项
mysql二进制文件安装指导和my.cnf文件

mysql关于log_bin相关命令

mysql> show BINARY logs;
+—————–+———–+
| Log_name | File_size |
+—————–+———–+
| mysqlbin.000001 | 107 |
+—————–+———–+
1 row in set (0.00 sec)
–查看当前bin_log情况
mysql> show master logs;
+—————–+———–+
| Log_name | File_size |
+—————–+———–+
| mysqlbin.000001 | 107 |
+—————–+———–+
1 row in set (0.00 sec)
–查看当前bin_log情况
mysql> show variables like ‘%log_bin%’;
+———————————+——-+
| Variable_name | Value |
+———————————+——-+
| log_bin | ON |
| log_bin_trust_function_creators | OFF |
| sql_log_bin | ON |
+———————————+——-+
3 rows in set (0.00 sec)
–查看log_bin相关配置
mysql> flush logs;
Query OK, 0 rows affected (0.06 sec)
–切换bin_log日志
mysql> PURGE BINARY LOGS TO ‘mysqlbin.000002’;
Query OK, 0 rows affected (0.03 sec)
–删除mysqlbin.000002之前的bin_log,并修改index中相关数据
mysql> PURGE BINARY LOGS BEFORE ‘2011-07-09 12:40:26’;
Query OK, 0 rows affected (0.04 sec)
–删除2011-07-09 12:40:26之前的bin_log,并修改index中相关数据
mysql> PURGE BINARY LOGS BEFORE ‘2011-07-09’;
Query OK, 0 rows affected (0.00 sec)
–删除2011-07-09之前的bin_log,并修改index中相关数据
mysql> set global expire_logs_days=5;
Query OK, 0 rows affected (0.00 sec)
–设置bin_log过期日期
mysql> reset master;
Query OK, 0 rows affected (0.02 sec)
–重设bin_log日志,以前的所有日志将被删除并且重设index中的数据

mysqld_safe启动报错

使用二进制编译文件的mysqld_safe启动报错,如下:
[mysql@ECP-UC-DB1 ~]$ mysqld_safe
110707 21:31:19 mysqld_safe Logging to ‘/opt/mysql/mysqldata/ECP-UC-DB1.err’.
110707 21:31:19 mysqld_safe The file /usr/local/mysql/bin/mysqld
does not exist or is not executable. Please cd to the mysql installation
directory and restart this script from there as follows:
./bin/mysqld_safe&
See http://dev.mysql.com/doc/mysql/en/mysqld-safe.html for more information
解决方法:
su – root
mkdir /usr/local/mysql/bin
ln -s /opt/mysql/product/5.5/bin/mysqld /usr/local/mysql/bin/mysqld
再次执行mysqld_safe
[mysql@ECP-UC-DB1 ~]$ mysqld_safe
110707 21:32:37 mysqld_safe Logging to ‘/opt/mysql/mysqldata/ECP-UC-DB1.err’.
110707 21:32:37 mysqld_safe Starting mysqld daemon with databases from /opt/mysql/mysqldata
启动结果:
mysql 26885 23452 0 21:32 pts/0 00:00:00 /bin/sh /opt/mysql/product/5.5/bin/mysqld_safe
mysql 27653 26885 0 21:32 pts/0 00:00:00 /usr/local/mysql/bin/mysqld –basedir=/opt/mysql/product/5.5 –datadir=/opt/mysql/mysqldata –plugin-dir=/usr/local/mysql/lib/plugin –log-error=/opt/mysql/mysqldata/ECP-UC-DB1.err –open-files-limit=8192 –pid-file=/var/run/mysqld/mysqld.pid –socket=/var/run/mysqld/mysqld.sock –port=3306
问题存在原因:
1、mysqld_safe只认识/usr/local/mysql/bin/mysqld(也许是配置问题)
2、my.cnf只能放置在/etc/下面,不然使用–defaults-file也不能读取my.cnf文件(有疑惑)

mysql 安装并启动多个实例

1、数据库实例目录
drwxrwxrwx 6 mysql mysql 4096 Jul 6 23:25 mysqldata
drwxrwxr-x 5 mysql mysql 4096 Jul 6 23:23 mysqldata1
drwxrwxr-x 5 mysql mysql 4096 Jul 6 23:27 mysqldata2
2、创建实例
/opt/mysql/product/5.5/scripts/mysql_install_db –basedir=/opt/mysql/product/5.5 –datadir=/opt/mysql/mysqldata –user=mysql
/opt/mysql/product/5.5/scripts/mysql_install_db –basedir=/opt/mysql/product/5.5 –datadir=/opt/mysql/mysqldata1 –user=mysql
/opt/mysql/product/5.5/scripts/mysql_install_db –basedir=/opt/mysql/product/5.5 –datadir=/opt/mysql/mysqldata2 –user=mysql
3、修改my.cnf文件
[mysqld_multi]
mysqld = /opt/mysql/product/5.5/bin/mysqld
mysqladmin = /opt/mysql/product/5.5/bin/mysqladmin
user = root
password = passw0rd
[mysqld3306]
port = 3306
socket = /var/run/mysqld/mysqld3306.sock
pid-file = /var/run/mysqld/mysqld3306.pid
basedir = /opt/mysql/product/5.5
datadir = /opt/mysql/mysqldata
[mysqld3307]
port = 3307
socket = /var/run/mysqld/mysqld3307.sock
pid-file = /var/run/mysqld/mysqld3307.pid
basedir = /opt/mysql/product/5.5
datadir = /opt/mysql/mysqldata1
[mysqld3307]
port = 3307
socket = /var/run/mysqld/mysqld3308.sock
pid-file = /var/run/mysqld/mysqld3308.pid
basedir = /opt/mysql/product/5.5
datadir = /opt/mysql/mysqldata2
注:其他无关参数省略,日志等文件路径也不能相同(未写明)
4、启动数据库
mysqld_multi –defaults-file=/etc/mysql/my.cnf start 3306
mysqld_multi –defaults-file=/etc/mysql/my.cnf start 3307
mysqld_multi –defaults-file=/etc/mysql/my.cnf start 3308
5、登录数据库修改root密码
mysql -S /var/run/mysqld/mysqld3306.sock
mysql -S /var/run/mysqld/mysqld3307.sock
mysql -S /var/run/mysqld/mysqld3308.sock
use mysql
UPDATE user SET password=PASSWORD(‘passw0rd’) WHERE user=’root’;
FLUSH PRIVILEGES;
说明:三个库上分别操作
6、关闭数据库
mysqld_multi –defaults-file=/etc/mysql/my.cnf stop 3306
mysqld_multi –defaults-file=/etc/mysql/my.cnf stop 3307
mysqld_multi –defaults-file=/etc/mysql/my.cnf stop 3308
7、全部启动/关闭
mysqld_multi –defaults-file=/etc/mysql/my.cnf start 3306-3308
mysqld_multi –defaults-file=/etc/mysql/my.cnf stop 3306-3308

Data Guard出现gap sequence修复

一、出现gap sequence现象
备库

Fetching gap sequence in thread 1, gap sequence 710-716
Tue May 31 15:02:38 2011
FAL[client]: Failed to request gap sequence
 GAP - thread 1 sequence 710-716
 DBID 3240478808 branch 746916894
FAL[client]: All defined FAL servers have been attempted.
-------------------------------------------------------------
Check that the CONTROL_FILE_RECORD_KEEP_TIME initialization
parameter is defined to a value that is sufficiently large
enough to maintain adequate log switch information to resolve
archivelog gaps.
-------------------------------------------------------------

主库

Tue May 31 13:50:47 2011
FAL[server]: Fail to queue the whole FAL gap
 GAP - thread 1 sequence 710-716
 DBID 3240478808 branch 746916894

二、修复操作
1、查询备库的scn

SQL> SELECT CURRENT_SCN FROM V$DATABASE;
CURRENT_SCN
-----------
    1154337
--在出现意外datafile header scn不一致的时候,需要根据提示归档日志,找出最小scn

2、确定主库是否添加数据文件

SQL> select FILE#,name from v$datafile where CREATION_CHANGE#> =1154337;
no rows selected

确定主库在这个scn之后是否有添加数据文件,如果添加文件,需要手工在备库添加

3、备库停止日志应用

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

4、主库增量备份并传输到备库上
主库进行增量备份

RMAN> BACKUP INCREMENTAL FROM SCN  1154337 DATABASE
FORMAT '/home/oracle/xff_%U' tag 'XIFENFEI';
[oracle@localhost ~]$ scp xff* 192.168.1.30:/home/oracle/rman

说明:主库之前必须要做过rman的全备(没有全备的库,基于scn的增量备份也能够成功)

5、备库上进行恢复

RMAN> CATALOG START WITH '/home/oracle/rman';
RMAN> RECOVER DATABASE NOREDO;

说明:CATALOG START WITH是10g及其以后版本中才存在功能,没有该功能可以采用catalog或者复制主库的控制文件,rman备份放置和主库备份时相同目录实现。

6、主库上创建standby controlfile文件并传输到备库

RMAN> BACKUP CURRENT CONTROLFILE FOR STANDBY
FORMAT '/home/oracle/xff_ctl.bck';
[oracle@localhost ~]$ scp xff_ctl.bck 192.168.1.30:/home/oracle/rman

创建standby controlfile两步可以需要根据实际情况考虑,大多数情况下不需要

7、备库恢复控制文件

RMAN> shutdown;
RMAN> STARTUP NOMOUNT;
RMAN> RESTORE STANDBY CONTROLFILE FROM '/home/oracle/rman/xff_ctl.bck';
RMAN> alter database mount;

8、清空备库日志组

SQL> ALTER DATABASE CLEAR LOGFILE GROUP 1;
注:如果采用了standby log模式,不需要清空,如果清空会出现
SQL> ALTER DATABASE CLEAR LOGFILE GROUP 1;
ALTER DATABASE CLEAR LOGFILE GROUP 1
*
ERROR at line 1:
ORA-19527: physical standby redo log must be renamed
ORA-00312: online log 1 thread 1: '/u01/oradata/xienfei/redo01.log'

说明:如果没有采用standby log模式,有几组需要清空几组

9、备库重设flashback

SQL> ALTER DATABASE FLASHBACK OFF;
SQL> ALTER DATABASE FLASHBACK ON;

10、备库重新接收并应用日志

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;

三、修复成功标志
1、sql中操作
在主库中执行alter system switch logfile;
分别主备库中执行select max(sequence#) from v$archived_log;如果一致标示修复成功

2、通过alert文件
主库

PING[ARC0]: Error 3113 when pinging standby xff.
Tue May 31 14:11:51 2011
Thread 1 advanced to log sequence 719
  Current log# 3 seq# 719 mem# 0: /u01/oradata/xienfei/redo03.log
Tue May 31 14:20:05 2011
Thread 1 advanced to log sequence 720
  Current log# 1 seq# 720 mem# 0: /u01/oradata/xienfei/redo01.log
Tue May 31 14:20:16 2011
ARC0: Standby redo logfile selected for thread 1 sequence 719 for destination LOG_ARCHIVE_DEST_2

备库

ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION
Tue May 31 15:30:37 2011
Attempt to start background Managed Standby Recovery process (xff)
MRP0 started with pid=18, OS id=14704
Tue May 31 15:30:37 2011
MRP0: Background Managed Standby Recovery process started (xff)
Managed Standby Recovery not using Real Time Apply
 parallel recovery started with 2 processes
Media Recovery Log /u01/archive/1_718_746916894.arc
Tue May 31 15:30:43 2011
Completed: ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION
Tue May 31 15:30:52 2011
RFS[1]: Successfully opened standby log 4: '/u01/oradata/xienfei/s_redo1.log'
Media Recovery Log /u01/archive/1_719_746916894.arc
Media Recovery Waiting for thread 1 sequence 720

bash shell 中的比较

文件比较运算符
-e filename 如果 filename存在,则为真 [ -e /var/log/syslog ]
-d filename 如果 filename为目录,则为真 [ -d /tmp/mydir ]
-f filename 如果 filename为常规文件,则为真 [ -f /usr/bin/grep ]
-L filename 如果 filename为符号链接,则为真 [ -L /usr/bin/grep ]
-r filename 如果 filename可读,则为真 [ -r /var/log/syslog ]
-w filename 如果 filename可写,则为真 [ -w /var/mytmp.txt ]
-x filename 如果 filename可执行,则为真 [ -L /usr/bin/grep ]
filename1-nt filename2 如果 filename1比 filename2新,则为真 [ /tmp/install/etc/services -nt /etc/services ]
filename1-ot filename2 如果 filename1比 filename2旧,则为真 [ /boot/bzImage -ot arch/i386/boot/bzImage ]
字符串比较运算符 (请注意引号的使用,这是防止空格扰乱代码的好方法)
-z string 如果 string长度为零,则为真 [ -z “$myvar” ]
-n string 如果 string长度非零,则为真 [ -n “$myvar” ]
string1= string2 如果 string1与 string2相同,则为真 [ “$myvar” = “one two three” ]
string1!= string2 如果 string1与 string2不同,则为真 [ “$myvar” != “one two three” ]
算术比较运算符
num1-eq num2 等于 [ 3 -eq $mynum ]
num1-ne num2 不等于 [ 3 -ne $mynum ]
num1-lt num2 小于 [ 3 -lt $mynum ]
num1-le num2 小于或等于 [ 3 -le $mynum ]
num1-gt num2 大于 [ 3 -gt $mynum ]
num1-ge num2 大于或等于 [ 3 -ge $mynum ]

单网卡绑定多IP导致TNS-12542等错误

今天想在家中访问下公司的oracle数据库,我了解的情况是那台服务器是有内外网ip,内网可以访问数据库。所以按照常理推断我只要配置下listener,外网应该也就可以正常访问
于是我就登陆到服务器上,修改listener.ora文件

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (SID_NAME = PLSExtProc)
      (ORACLE_HOME = /opt/oracle/product/10.2.0/db_1)
      (PROGRAM = extproc)
    )
  )
LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
     (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.11.12)(PORT = 1521))
     (ADDRESS = (PROTOCOL = TCP)(HOST = 211.155.227.172)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))
    )
  )

lsnrctl start 不能正常启动,报错如下:

Error listening on: (DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=211.155.227.172)(PORT=1521)))
TNS-12542: TNS:address already in use
 TNS-12560: TNS:protocol adapter error
  TNS-00512: Address already in use
   Linux Error: 98: Address already in use

根据错误提示,意思是HOST=211.155.227.172这个(地址+端口+协议)已经被占用
第一反应:使用netstat -an|grep 1521没有发现该地址有1521端口启动,说明没有被占用
第二反应:防火墙,通过查看发现防火墙是关闭
通过以上两项查看都没有问题,那我修改下监听端口尝试下,然后我把监听端口改成了1522,监听能够正常启动,并且开始监听1522端口。通过实验证明1522端口是正常的,那问题出在哪里呢?为什么1521不行,我查看下ip地址的设置情况

eth0      Link encap:Ethernet  HWaddr 00:E0:4D:C3:D5:18
          inet addr:192.168.11.12  Bcast:192.168.11.255  Mask:255.255.252.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:5000774 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1610691 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1828268348 (1.7 GiB)  TX bytes:436101782 (415.8 MiB)
eth0:1    Link encap:Ethernet  HWaddr 00:E0:4D:C3:D5:18
          inet addr:211.155.227.172  Bcast:211.155.227.175  Mask:255.255.255.240
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

发现192.168.11.12和211.155.227.172都是绑定在eth0的网卡上,因为监听在192.168.11.12启动了1521端口,所以211.155.227.172上的1521不能起来(因为同一张网卡)
我想既然是公用同一张网卡,那么监听了192.168.11.12:1521,那我用211.155.227.172:1521应该可以正常访问,除掉监听中的(ADDRESS = (PROTOCOL = TCP)(HOST = 211.155.227.172)(PORT = 1522)),然后直接在自己的电脑上修改tns,使用 211.155.227.172地址访问,果然能够访问。
通过这次事件得出结论:单网卡绑定多IP,只要监听主IP地址,其他绑定的IP均可以访问,不需要修改任何监听信息