Oracle笔记(1)——Database和Instance的区别

DatabaseInstance的区别如下:

What is a Database?

We already know that a database is a collection of data. And this data is stored in form of tables at logical level, and in the datafiles at the physical level. There are some other files as well like Redo log files, Control files, Initialization files which stores important information about the database.

What is an Instance?

To view or update data stored in tables/datafiles, Oracle must start a set of background processes, and must allocate some memory to be used during database operation. The background processes and memory allocated by Oracle together make up an Instance.

简言之,Database是存放实际数据的所有文件。为了操作这些文件,就需要有Instance:访问文件的进程和内存。

Oracle 12c For Dummies中关于DatabaseInstance二者之间关系的总结:

✓ An instance can exist without a database. Yes, it’s true. You can start an Oracle instance and not have it access any database files. Why would you do this?
• This is how you create a database. There’s no chicken-or-egg debate here. You first must start an Oracle instance; you create the database from within the instance.
• An Oracle feature called Automatic Storage Management uses an instance but isn’t associated with a database.
✓ A database can exist without an instance but would be useless. It’s just a bunch of magnetic blips on the hard drive.
✓ An instance can access only one database. When you start your instance, the next step is to mount that instance to a database. An instance can mount only one database at a time.
✓ You can set up multiple instances to access the same set of files or one database. Clustering is the basis for the Oracle Real Application Clusters feature. Many instances on several servers accessing one central data- base allows for scalability and high availability.

参考资料:

Oracle 12c For Dummies

database vs instances

Difference between Oracle Instance & Database.

 

Bash quoting简介

Bash quoting可以关闭Bash中具有特殊含义的meta字符的功能:
a)单引号:所有meta字符的功能均被关闭;
b)双引号:大部分meta字符的功能被关闭,除了$等少数字符;
c)反斜线(\):仅跟着\后面的meta字符被关闭。
这样就可以理解为什么解压多个zip文件时,要使用“unzip '*.zip'”而不是“unzip *.zip”。因为第二种会首先把*.zip替换成所有的文件名,而第一种方法不会这样做。

参考资料:
Shell十三问
How do I unzip multiple / many files under Linux?

 

shmmax和shmall

Linux kernel中针对shared memory有两个重要的配置项:shmmaxshmall

shmmax定义了一次分配shared memory的最大长度,单位是byte

# cat /proc/sys/kernel/shmmax
18446744073692774399

shmall定义了一共能分配shared memory的最大长度,单位是page

最大“shared memory” = shmall(cat /proc/sys/kernel/shmall) * pagesize(getconf PAGE_SIZE)

shmmax为例,介绍一下修改值的方法:

(1)现在系统shmmax的值:

# sysctl -a | grep shmmax
kernel.shmmax = 18446744073692774399

(2)修改shmmax的值:

# echo "536870912" > /proc/sys/kernel/shmmax
# sysctl -a | grep shmmax
kernel.shmmax = 536870912

可以看到值发生了变化。但是重启系统以后,shmmax又变回之前的值。如果要让值永久生效,可以使用下列方法:

# echo "kernel.shmmax = 536870912" >>  /etc/sysctl.conf
# sysctl -a | grep shmmax
kernel.shmmax = 18446744073692774399
# sysctl -p
kernel.shmmax = 536870912
# sysctl -a | grep shmmax
kernel.shmmax = 536870912

另外,关于如何设置shmallshmmax的值,也可以参考这个脚本

参考资料:
The Mysterious World of Shmmax and Shmall
Configuring SHMMAX and SHMALL for Oracle in Linux
What is shmmax, shmall, shmmni? Shared Memory Max

 

Haskell笔记 (12)—— 定义新的数据类型(data type)

使用data关键字来定义一种新的数据类型(data type):

data StudentInfo = Student Int String
                    deriving (Show)

StudentInfotype constructor,也是这种新type的名字,所以首字母必须大写。

Studentvalue constructor(有时也称之为data constructor)的名字,它的首字母也必须大写(可以把它看做是首字母大写的函数),作用是用来创建StudentInfo这种type的值。在Student后面的IntStringStudentInfo这种typecomponent(有时也称作fieldparameter,其作用类似于其它编程语言中结构体成员。

type constructor只用在type declarationtype signature中,而value constructor只用在实际的代码中。因此二者的使用是相互独立的,可以让type constructorvalue constructor拥有相同的名字,实际编码中基本也是这样做的:

data Student = Student Int String
                        deriving (Show)

也可以使用type关键字为已有的类型定义一个同义词(type synonym):

type SI = StudentInfo

type synonym也可以为一个冗长的类型取一个短名字,举例如下:

type SI = (Int, String)

Haskell笔记 (11)—— 函数的“type signature”

看一下take函数的type signature

ghci> :type take
take :: Int -> [a] -> [a]

这表明它有两个参数,返回值是一个list。“->”是右相关(right-associative),因此实际上也可以把take函数的type signature写成这样:

ghci> :type take
take :: Int -> ([a] -> [a])

因此也可以这样理解take函数:它有一个Int参数,返回值是另一个函数。这个函数的参数和返回类型是同一个类型的list

 

在RHEL系统上使用“subscription-manager”注册和激活“subscription”

RHEL系统中注册和使用subscription是两个过程:

NOTE: With Red Hat Subscription-Manager, registration and utilization of a subscription is actually a two-part process. First register a system, then apply a subscription.

可以使用下面命令一次完成两个过程:

# subscription-manager register --username <username> --password <password> --auto-attach

在我的RHEL 7.2系统上执行上述命令:

# subscription-manager register --username=xxxx --password=xxxx --auto-attach
Registering to: subscription.rhn.redhat.com:443/subscription
The system has been registered with ID: 333486bb-xxxxxx

Installed Product Current Status:
Product Name: Red Hat Enterprise Linux Server
Status:       Subscribed

然后检查状态:

# subscription-manager list

+-------------------------------------------+
    Installed Product Status
+-------------------------------------------+
Product Name:   Red Hat Enterprise Linux Server
Product ID:     69
Version:        7.2
Arch:           x86_64
Status:         Subscribed
Status Details:
Starts:         06/29/2015
Ends:           06/28/2016

接下来就可以使用“yum install”,“yum update”等命令安装和更新软件了,非常方便。

参考资料:
How to Register and Enable Red Hat Subscription, Repositories and Updates for RHEL 7.0 Server
How to register and subscribe a system to the Red Hat Customer Portal using Red Hat Subscription-Manager
RHEL : Register Subscription

 

Haskell笔记 (10)—— Lazy evaluation

Haskell中对表达式的计算使用的是Lazy evaluation(也称之为nonstrict evaluation):即只有表达式的值真正需要时,才会被计算。Haskell中把用来跟踪还没有计算的表达式的记录称之为trunk

参考自stackoverflow

Mostly because it can be more efficient — values don’t need to be computed if they’re not going to be used. For example, I may pass three values into a function, but depending on the sequence of conditional expressions, only a subset may actually be used. In a language like C, all three values would be computed anyway; but in Haskell, only the necessary values are computed.

It also allows for cool stuff like infinite lists. I can’t have an infinite list in a language like C, but in Haskell, that’s no problem. Infinite lists are used fairly often in certain areas of mathematics, so it can be useful to have the ability to manipulate them.

Lazy evaluation的优点:高效(延迟执行代码),支持像infinite lists这样的cool stuff

 

Mesos笔记 (9)—— Containerizer类代码解析

Containerizer类(定义在src/slave/containerizer/containerizer.hpp )是所有Containerizer的抽象父类。除了默认的构造函数和一个什么都没做的析构函数,其只实现了createresources方法。create方法代码如下(v0.26版本):

Try<Containerizer*> Containerizer::create(
    const Flags& flags,
    bool local,
    Fetcher* fetcher)
{
  if (flags.isolation == "external") {
    LOG(WARNING) << "The 'external' isolation flag is deprecated, "
                 << "please update your flags to"
                 << " '--containerizers=external'.";

    Try<ExternalContainerizer*> containerizer =
      ExternalContainerizer::create(flags);
    if (containerizer.isError()) {
      return Error("Could not create ExternalContainerizer: " +
                   containerizer.error());
    }

    return containerizer.get();
  }

  // TODO(benh): We need to store which containerizer or
  // containerizers were being used. See MESOS-1663.

  // Create containerizer(s).
  vector<Containerizer*> containerizers;

  foreach (const string& type, strings::split(flags.containerizers, ",")) {
    if (type == "mesos") {
      Try<MesosContainerizer*> containerizer =
        MesosContainerizer::create(flags, local, fetcher);
      if (containerizer.isError()) {
        return Error("Could not create MesosContainerizer: " +
                     containerizer.error());
      } else {
        containerizers.push_back(containerizer.get());
      }
    } else if (type == "docker") {
      Try<DockerContainerizer*> containerizer =
        DockerContainerizer::create(flags, fetcher);
      if (containerizer.isError()) {
        return Error("Could not create DockerContainerizer: " +
                     containerizer.error());
      } else {
        containerizers.push_back(containerizer.get());
      }
    } else if (type == "external") {
      Try<ExternalContainerizer*> containerizer =
        ExternalContainerizer::create(flags);
      if (containerizer.isError()) {
        return Error("Could not create ExternalContainerizer: " +
                     containerizer.error());
      } else {
        containerizers.push_back(containerizer.get());
      }
    } else {
      return Error("Unknown or unsupported containerizer: " + type);
    }
  }

  if (containerizers.size() == 1) {
    return containerizers.front();
  }

  Try<ComposingContainerizer*> containerizer =
    ComposingContainerizer::create(containerizers);

  if (containerizer.isError()) {
    return Error(containerizer.error());
  }

  return containerizer.get();
}

默认情况下,containerizerstypemesos,所以会调用MesosContainerizer::create来生成containerizer。关于resources方法,参考Mesos笔记 (5)—— 资源