使用脚本备份还原 postgresql

定期备份

#!/bin/sh
. /etc/profile

dt=$(date +%Y-%m-%d-%H%M)
pg_dump -F c -Z 9 -d exampleDb > /var/local/pg_dump/exampleDb.all.$dt.dump

还原

pg_restore -d exampleDb exampleDb.all.dump

服务器迁移还原脚本

sudo -u postgres bash -c "psql -c \"ALTER USER postgres WITH PASSWORD 'postgres';\""
sudo -u postgres bash -c "psql -c \"CREATE USER exampleDb WITH PASSWORD 'exampleDb';\""
sudo -u postgres bash -c "psql -c \"CREATE DATABASE exampleDb OWNER exampleDb;\""
sudo -u postgres bash -c "psql -c \"GRANT ALL PRIVILEGES ON DATABASE exampleDb to exampleDb;\""
cp postgresql.conf /etc/postgresql/9.4/main
cp pg_hba.conf /etc/postgresql/9.4/main
sudo -u postgres pg_restore -d exampleDb exampleDb.all.dump

离线获取 Docker 镜像

在内网中使用 docker 源,标准的方式是使用 harbor。如果是小量的只需要几个镜像,我们可以使用 docker save 和 docker load 的命令,将外部的容器镜像导入内部。下面介绍一下用法,最后还附带一个一键保存、还原所有镜像的脚本。

保存单个镜像

  1. 环境准备

    • 服务器node01、node02
    • node01可以访问外网,node02不能访问外网,但node01与node02之间是互通的
    • node01和node02均已成功安装并启动Docker
  2. 在node01上,从远程仓库获取镜像

    docker pull nginx
    	
    Using default tag: latest
    latest: Pulling from library/nginx
    8176e34d5d92: Pull complete
    5b19c1bdd74b: Pull complete
    4e9f6296fa34: Pull complete
    Digest: sha256:4771d09578c7c6a65299e110b3ee1c0a2592f5ea2618d23e4ffe7a4cab1ce5de
    Status: Downloaded newer image for nginx:latest
    
  3. 归档

    docker save -o nginx.tar library/nginx
    

    docker save : 将指定镜像保存成 tar 归档文件。 -o :输出到的文件。

  4. 将保存好的nginx.tar上传至服务器node02上

    scp nginx.tar root@node02:/tmp
    
  5. 登录node02,加载nginx.tar

    docker load -i /tmp/nginx.tar
    
    014cf8bfcb2d: Loading layer [==================================================>]  58.46MB/58.46MB
    832a3ae4ac84: Loading layer [==================================================>]  53.91MB/53.91MB
    e89b70d28795: Loading layer [==================================================>]  3.584kB/3.584kB
    Loaded image: nginx:latest
    

    docker load : 加载指定的tar归档文件格式的镜像。-i :指定要读取的tar归档文件格式的镜像。

批量保存镜像

如果需要保存比较多的镜像,这种笨重的方式显然不合适,我找到了这个脚本,一键打包/加载所有镜像,非常好用。

下载链接:hydra1983/docker_images.sh

源码备份如下:

#!/bin/bash

readonly DB_FILE="$(pwd)/images.db"
readonly IMG_DIR="$(pwd)/images"

save-images() {
  echo "Create ${DB_FILE}"
  echo "$(docker images|grep -v 'IMAGE ID'|awk '{printf("%s %s %s\n", $1, $2, $3)}'|column -t)" > "${DB_FILE}"
  
  echo "Read ${DB_FILE}"
  local images
  while read -r image; do
     images+=("$image"); 
  done <<< "$(cat ${DB_FILE})"

  echo "Create ${IMG_DIR}"
  if [[ ! -d "${IMG_DIR}" ]]; then
    mkdir "${IMG_DIR}"
  fi
  
  local name tag id
  for image in "${images[@]}"; do
    name=$(echo $image|awk '{print $1}')
    tag=$(echo $image|awk '{print $2}')
    id=$(echo $image|awk '{print $3}')
        
    if [[ "${id}" != "" ]]; then
      local imgPath="${IMG_DIR}/${id}.dim"

      if [[ ! -f "${imgPath}" ]] ; then
        echo "[DEBUG] save ${id} ${name}:${tag} to ${imgPath}"
        (time  docker save -o "${imgPath}" ${name}:${tag}) 2>&1 | grep real
      else
        echo "[DEBUG] ${id} ${name}:${tag} already saved"
      fi
    fi    
  done
}

load-images() {
  if [[ ! -f "${DB_FILE}" ]]; then
    echo "No ${DB_FILE} to read"
    exit 0
  fi

  if [[ ! -d "${IMG_DIR}" ]]; then
    echo "No ${IMG_DIR} to load images"
    exit 0
  fi

  echo "Read ${DB_FILE}"
  local images
  while read -r image; do
     images+=("$image"); 
  done <<< "$(cat ${DB_FILE})"

  local name tag id
  for image in "${images[@]}"; do
    name=$(echo $image|awk '{print $1}')
    tag=$(echo $image|awk '{print $2}')
    id=$(echo $image|awk '{print $3}')
        
    if [[ "${id}" != "" ]]; then
      local imgPath="${IMG_DIR}/${id}.dim"

      if [[ "$(docker images|grep ${id} | grep ${name} | grep ${tag})" == "" ]]; then        
        if [[ "$(docker images|grep ${id})" == "" ]]; then
          echo "[DEBUG] load ${id} ${name}:${tag} from ${imgPath}"
          docker load -i "${imgPath}"
        else
          echo "[DEBUG] tag ${id} as ${name}:${tag}"
          docker tag ${id} ${name}:${tag}
        fi
      else
        echo "[DEBUG] ${id} ${name}:${tag} already loaded"
      fi
    fi
  done
}

$@

参考资料


传统存储介绍

什么是存储

存储就是根据不同的应用环境通过采取合理、安全、有效的方式将数据保存到某些介质上并能保证有效的访问。

  • 保存
  • 访问

我们一般从这三分方面了解存储:

  • 存储设备
  • 存储技术
  • 对外接口

计算机存储系统的层次图

这个图事大学时候的课本内容,我就不多讲了。计算机存储层次之所以是这个样子,是因为人性的贪婪。

怎么说呢,我们对存储系统始终有三个基本要求,即:

  • 速度快
  • 存储容量大
  • 成本低

寄存器

用于CPU内部各单元之间的周转,是CPU内部用来创建和储存CPU运算结果和其它运算结果的地方,拥有非常高的读写速度。

寄存器和cpu速度相当,空间比较小在kb级别。

CPU内部的寄存器有很多种类型。

  • 数据寄存器
  • 地址寄存器
  • 指令寄存器 …

CPU对存储器中的数据进行处理时,往往先把数据取到内部寄存器中,而后再作处理。外部寄存器是计算机中其它一些部件上用于暂存数据的寄存器,它与CPU之间通过“端口”交换数据,外部寄存器具有寄存器和内存储器双重特点。通用寄存器的数据宽度决定了处理器一次可以运行的数据量。

高速缓存Cache

缓存是为了弥补高速设备和低速设备的鸿沟而引入的中间层,最终起到加快访问速度的作用,它将一些经常使用的数据缓存到内存或者各种储存介质中,当再次使用时可以不用去数据库中查询,减少与数据库的交互,提高性能。

缓存又分为一级缓存、二级缓存、三级缓存,它们的作用范围不同:

  • 一级缓存是session级别的。也就是只有在同一个session里缓存才起作用,当这个session关闭后这个缓存就不存在了。比如在一个事务中同时查询同一个对象,则不会两次去数据库中查询。
  • 二级缓存是sessionFactory级别的。其缓存对同一个sessionFactory生产出来的session都有效。 我们通常使用其他的一些开源组件,比如 hibernate 经常使用的就是 EhCache,这个缓存在整个应用服务器中都会有效的,主要是为了存储一些比较稳定的数据,如权限,只有在用户修改了权限且重新登录时才能生效。
  • 三级缓存(如果有的话)是为读取二级缓存后未命中的数据设计的—种缓存,进一步提高CPU的效率。

注意:只有一级缓存是在CPU中的,一级缓存的读取需要2-4个时钟周期;二级缓存的读取需要10个左右的时钟周期;而三级缓存需要30-40个时钟周期,但是容量一次增大。


php laravel 框架中的 try catch

嗯,平时不怎么习惯使用 try catch。今天用起来竟然发现不生效。无法理解。

经过一番折腾之后,发现其实 ide 已经有做很好的提示了!

在类名前面添加斜杠即可:

这个问题不仅是 Exception 这个类而已,所有PHP自带的类都需要添加\


X86、X86_64、amd64、i386、i686区别

x86

intel的开发的一种32位指令集,从386开始时代开始的,一直沿用至今,是一种cisc指令集,所有intel早期的cpu,amd早期的cpu都支持这种指令集。

x84_64/amd64

实际上,x86_64,x64,AMD64基本上是同一个东西。

x86 CPU开始迈向64位的时候,AMD比 Intel 率先制造出了商用的兼容 x86 的CPU,AMD称之为AMD64。

而后 Intel 也开始支持 AMD64 的指令集,换了个名字,叫x86_64,表示是x86 指令集的64扩展。

i386

i386 适用于intel和AMD所有32位的cpu。

intel平台包括8086,80286,80386,80486,奔腾系列(1.2.3.4)、赛扬系列,Pentium D 系列以及centrino P-M,core duo 等.

i686

i686 仍然属于 i386 体系,不过相对于386 CPU的特性作了指令优化。

i686 的软件包能在奔腾二代以上的cpu上执行,但基本不能在此之先的cpu如486上执行。而i386的软件包既可在i386的电脑上执行,也可在后面所有的cpu上执行(但不能发挥cpu的最佳性能)。