Oracle RAC notes: log file location

No Comments

Clusterware (grid) log files:
$ORA_CRS_HOME/log/<node_name>/:

  • alert<node_name>.log: you can check status of all services, for example, CSSD, CTSS, CRSD.
  • crsd/crsd.log: CRSD log file.
  • ohasd/ohasd.log: OHASD log file.
  • agent/crsd: sometimes, when you fails to start a resource, you can check this folder.

$ORA_CRS_HOME/log/diag/tnslsnr/<node_name>/:

  • listener_<SCAN name><SCAN number>/alert/log.xml: SCAN listener log file.

DB log files:
$ORACLE_BASE/diag/rdbms/<db_name>/<instance_name>/:

  • alert/log.xml: this db instance log file.
  • trace/alert_<instance_name>.log: this db instance trace log file.

$ORACLE_BASE/diag/tnslsnr/<node_name>/listener/:

  • alert/log.xml: this node instance listener log file.
  • trace/listener.log: this node instance listener trace log file.

–EOF–

Oracle RAC notes: srvctl commands

No Comments

The Server Control utility (srvctl) is used to:

  • start and stop the database and instances
  • manage configuration information
  • move or remove instances and services
  • add services
  • manage configuration information

Some srvctl operations store configuration information in the Oracle Cluster Registry (OCR). And it requires Oracle Clusterware process (CRSD) is up.

Note: you can type “srvctl command (or verb) object (or noun) -h” to get help information.

Some useful commands:
1, display the configuration stored in the OCR: srvctl config database/service/nodeapps/asm/listener.
Example:

oracle@rac1:/home/oracle> srvctl config database -d rac
Database unique name: rac
Database name: rac
Oracle home: /u01/app/oracle/base/product/11.2.0
Oracle user: oracle
Spfile: /u01/oradat/rac/spfilerac.ora
Domain: localdomain
Start options: open
Stop options: immediate
Database role: PRIMARY
Management policy: AUTOMATIC
Server pools: rac
Database instances: rac1,rac2
Disk Groups:
Services:
Database is administrator managed
oracle@rac1:/home/oracle> srvctl config nodeapps -n rac1
-n <node_name> option has been deprecated.
VIP exists.:rac1
VIP exists.: /rac1-vip/<virtual IP>/<netmask>/eth0
GSD exists.
ONS daemon exists. Local port 6100, remote port 6200
eONS daemon exists. Multicast port 23503, multicast IP address <multicast IP>, listening port 2016

2, start/stop database:

srvctl start/stop database -d rac

3, start/stop a node:

srvctl start/stop nodeapps -n node_name

4, display current state of database, instances, services, or node applications: srvctl status.
Example:

oracle@rac1:/home/oracle> srvctl status database -d rac
Instance rac1 is running on node rac1
Instance rac2 is not running on node rac2
oracle@rac1:/home/oracle> srvctl status nodeapps
VIP rac1-vip is enabled
VIP rac1-vip is running on node: rac1
VIP rac2-vip is enabled
VIP rac2-vip is running on node: rac1
Network is enabled
Network is running on node: rac1
Network is not running on node: rac2
GSD is disabled
GSD is not running on node: rac1
GSD is not running on node: rac2
ONS is enabled
ONS daemon is running on node: rac1
ONS daemon is not running on node: rac2
eONS is enabled
eONS daemon is running on node: rac1
eONS daemon is not running on node: rac2


References:
Oracle document: Server Control Utility Reference

–EOF–

Oracle RAC notes: crsctl commands

No Comments

crsctl is a tool to manage Oracle Clusterware (grid).

Note: you can type “crsctl <command> <object> -h” to get help information.

Important: from Oracle document, you couldn’t use crsctl commands on Oracle entities that have names beginning with ora.

Many crsctl cluster aware commands rely on the OHASD (Oracle High Availability Services daemon). Normally it should start automatically when the machine is up. You can check this using “crsctl config crs“.

oracle@rac1:/home/oracle> crsctl config crs
CRS-4622: Oracle High Availability Services autostart is enabled.

P.S. If a command is cluster aware, that is to say, it can be performed remotely. You can log in one node and operate other nodes.

Some useful commands:
1, check/start/stop cluster on all nodes/specific node:

crsctl check cluster
crsctl start cluster
crsctl stop cluster

Example:

# start all nodes (requires root permission)
crsctl start cluster -all

2, Check resources status:

crsctl status resource

3, Display the version of Oracle Clusterware software stored in the binaries on the local node (check files):

crsctl query crs releaseversion

4, Display the latest version of the software that has been successfully started on the specified node (running instance):

crsctl query crs softwareversion

5, Display the voting disks used by Cluster Synchronization Services, the status of the voting disks, and the location of the disks, whether they are stored on Oracle ASM or elsewhere:

crsctl query css votedisk


References:
Oracle document: CRSCTL Utility Reference

–EOF–

Java: static synchronized method vs instance synchronized method

No Comments

  • static synchronized method:需要得到这个类的Class object的锁。
  • instance synchronized method:需要得到这个instance object的锁。

而这两个锁并没有任何关系,也就是说,调用一个类的static synchronized method并不会block住instance synchronized method的调用,反之亦然。

Test code:

public class TestSynchronized {
    public static void main(String[] args) throws Exception {
        final Target target = new Target();
        Thread t1 = new Thread(new Runnable() {
            public void run() {
                System.out.println("static");
                Target.classMethod();
                System.out.println("static");

            }
        });
        Thread t2 = new Thread(new Runnable() {
            public void run() {
                System.out.println("non-static");
                target.instanceMethod();
                System.out.println("non-static");
            }
        });
        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }
}

class Target {
    public static synchronized void classMethod() {
        sleepAndLog("classMethod");
    }

    public synchronized void instanceMethod() {
        sleepAndLog("instanceMethod");
    }

    private static void sleepAndLog(String msg) {
        System.out.println("begin sleeping: " + msg);
        try {
            Thread.sleep(30 * 1000);
        } catch (Exception ex) {}
        System.out.println("finish sleeping: " + msg);
    }
}

Output:

static
non-static
begin sleeping: classMethod
begin sleeping: instanceMethod
finish sleeping: instanceMethod
finish sleeping: classMethod
non-static
static

Reference:

–EOF–

Perl: eq vs ==

No Comments

在Perl中,字符串比较和数字比较是由不同的运算符来完成的:

  • 数字比较运算符: <, >, <=, >=, ==, !=
  • 字符串比较运算符: lt, gt, le, ge, eq, ne
  • cmp: 比较字符串,返回 -1, 0 或者 1。
  • <=>: 比较数字,返回 -1, 0 或者 1。
  • =~:用正则表达式来匹配,匹配的话返回True。
  • !~:和 =~ 相反,不匹配返回True。

我有好几次都用错了,结果浪费了很多时间在调试上面。

Example:

#!/usr/bin/env perl
use strict;
use warnings;

my $num1 = 1;
my $num2 = 1.0;
my $two_numbers = "$num1 and $num2";

my $str1 = "1abc";
my $str2 = "1xyz";
my $two_strings = "$str1 and $str2";

print "Compare two numbers using !=\n";
if ($num1 != $num2) {
    print "$two_numbers are not equal\n";
} else {
    print "$two_numbers are equal\n";
}

print "Compare two strings using !=: get wrong result\n";
if ($str1 != $str2) {
    print "$two_strings are not equal\n";
} else {
    print "$two_strings are equal\n";
}

print "Compare two numbers using ne\n";
if ($num1 ne $num2) {
    print "$two_numbers are not equal\n";
} else {
    print "$two_numbers are equal\n";
}

print "Compare two strings using ne\n";
if ($str1 ne $str2) {
    print "$two_strings are not equal\n";
} else {
    print "$two_strings are equal\n";
}

Output:

Compare two numbers using !=
1 and 1 are equal
Compare two strings using !=: get wrong result
Argument "1xyz" isn't numeric in numeric ne (!=) at compare_operators.pl line 23.
Argument "1abc" isn't numeric in numeric ne (!=) at compare_operators.pl line 23.
1abc and 1xyz are equal
Compare two numbers using ne
1 and 1 are equal
Compare two strings using ne
1abc and 1xyz are not equal

References:

–EOF–

Java: initialization sequence of object

No Comments

Just a note. And I really hate this.

  1. All static data fields are initialized to their default value (0, false, or null).
  2. All static field initializers and static initialization blocks are executed, in the order in which they occur in the class declaration.
  3. All non-static data fields are initialized to their default value (0, false, or null).
  4. All non-static field initializers and non-static initialization blocks are executed, in the order in which they occur in the class declaration.
  5. If the first line of the constructor calls a second constructor, then the body of the second constructor is executed.
  6. The body of the constructor is executed.

Test code:

public class TestInitialization {
    private Test mT1 = new Test("member variable 1");
    {
        System.out.println("non-static block 1");
    }
    private Test mT2 = new Test("member variable 2");
    {
        System.out.println("non-static block 2");
    }
    private static Test sT1 = new Test("static variable 1");
    static {
        System.out.println("static block 1");
    }
    private static Test sT2 = new Test("static variable 2");
    static {
        System.out.println("static block 2");
    }

    public TestInitialization() {
        System.out.println("TestInitialization()");
    }

    public TestInitialization(String msg) {
        this();
        System.out.println("TestInitialization(String msg): msg=" + msg);
    }

    public static void main(String[] args) {
        System.out.println("in main function");
        new TestInitialization("hello");
    }

}

class Test {
    public Test() {
        System.out.println("Test()");
    }

    public Test(String msg) {
        System.out.println("Test(String msg): msg=" + msg);
    }
}

Ouput:

D:\temp>java TestInitialization
Test(String msg): msg=static variable 1
static block 1
Test(String msg): msg=static variable 2
static block 2
in main function
Test(String msg): msg=member variable 1
non-static block 1
Test(String msg): msg=member variable 2
non-static block 2
TestInitialization()
TestInitialization(String msg): msg=hello

Reference:

  • 卓有成效的程序员:第14章 多语言编程
  • Core JavaTM 2 Volume I – Fundamentals, Seventh Edition: Chapter 4. Objects and Classes

–EOF–

Python: scope of variable

No Comments

作用范围:

变量的作用范围规定了在什么范围内可以使用这个变量名。

简单来说,在Python中,本地变量的作用范围就是定义这个变量的代码块以及嵌套的代码块(除非在嵌套的代码块中重新定义这个变量),在上层是不可以使用这个变量的。

查找规则:

LEGBLocal -> Enclosing function locals -> Global (module) -> Built-in (Python)

在解析变量名的时候,解析器首先在本地声明的变量中去找;然后到外部函数去找;然后在全局变量(在Python中,全局变量是对于模块来说的,也可以说是当前文件)中找;最后检查内置的命名空间。

global:

global语句声明一个变量是属于全局命名空间的。在函数中,如果一个变量没有被声明为global,虽然我们可以使用它,但是不能对它进行赋值。

#!/usr/bin/env python

var = 1

def foo():
    var = 2
    print(var)  # 2, only change local variable

foo()
print(var)      # 1, global variable is not changed

def bar():
    global var
    var = 3
    print(var)  # 3, reference to global variable

bar()
print(var)      # 3, global variable has been changed

nonlocal:

global可以把一个变量声明为全局变量,但是如果你需要在嵌套函数中修改外部函数的一个变量,global就不起作用了。这个时候你需要nonlocal。nonlocal把这个变量名绑定到最最最近定义的变量上。和global不同,nonlocal声明的变量必须是已经存在的,不能声明一个新的变量。

#!/usr/bin/env python

def outer1():
    var = "outer"
    def inner():
        var = "inner"
        print(var)      # inner, only change local variable
    inner()
    print(var)          # outer, variable defined in outer is not changed

outer1()

def outer2():
    var = "outer"
    def inner():
        nonlocal var
        var = "inner"
        print(var)      # inner, only change local variable
    inner()
    print(var)          # inner, variable defined in outer is not changed

outer2()

References:

–EOF–

Java: ThreadLocal用法

No Comments

顾名思义,ThreadLocal是为了支持thread-local的变量,它有这样的特点:

  1. 对于同一个线程来说,ThreadLocal是全局的,你可以在这个线程的任何地方得到这个ThreadLocal的值。比如在函数A中设置ThreadLocal的值,然后在函数B中得到这个值。
  2. 对于别的线程来说,ThreadLocal是局部的,你不能这样做:在线程A中设置ThreadLocal的值,然后在线程B中得到这个值。

ThreadLocal类只有三个成员函数:

  • protected Object initialValue() – 返回ThreadLocal变量的初始值。在一线程中,如果在调用set()之前调用get()的时候,initialValue()就会被调用,而且也只会被调用一次。如果在调用get()之前已经调用过set()了,那么initialValue()就不会被调用。
  • public Object get() – 得到这个ThreadLocal变量的值(对于当前线程的)。
  • public void set(Object value) – 设置这个ThreadLocal的变量的值(对于当前线程的)。

用处:

当你需要把一个单线程程序移植到多线程的环境的时候,你可以根据实际情况把一些全局变量用ThreadLocal包装起来,从而实现线程安全。但是不要滥用ThreadLocal:你在函数A设置一个ThreadLocal,然后函数B中使用这个ThreadLocal,也就意味着,B依赖于A。

需要注意的事项:

从JDK的源代码来看,在get的时候,是根据ThreadLocal的reference来找实际的值,那么在set()和get()之间不要去改变ThreadLocal的reference,比如new一个新的ThreadLocal。

    public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null)
                return (T)e.value ;
        }
        return setInitialValue();
    }

一个错误的例子:在多线程环境下,如果调用顺序是线程A调用setValue(oa),线程B调用setValue(ob),线程A调用getValue(),那么将得到一个空值。因为tl的reference已经改变了。

public class ThreadLocalTest {
    static ThreadLocal tl = null;

    public static void setValue(Object o) {
        tl = new  ThreadLocal();
        tl.set(o);
    }

    public static Object getValue() {
        return tl.get();
    }
}

References:

–EOF–

Python: for statement

No Comments

在Python中,for语句不一定会遍历所有元素:基本原理应该是和在Java中的for一样,如果在遍历的时候不小心修改列表,可能会出现问题。所以,如果需要修改列表的话,最好先拷贝一份。

#!/usr/bin/env python

l = range(1, 10)
for i in l:
    print(i)
    l.remove(i)
print(l)

# copy before iterate
l = range(1, 10)
for i in l[:]:
    print(i)
    l.remove(i)
print(l)

输出:

1
3
5
7
9
[2, 4, 6, 8]
1
2
3
4
5
6
7
8
9
[]

–EOF–

Happy New Year!

No Comments

新年快乐!

Older Entries