python数据类型和变量

[TOC]

在Python中,能够直接处理的数据类型有以下几种:

整数

Python可以处理任意大小的整数,当然包括负整数,在程序中的表示方法和数学上的写法一模一样,例如:1100-80800,等等。

计算机由于使用二进制,所以,有时候用十六进制表示整数比较方便,十六进制用0x前缀和0-9,a-f表示,例如:0xff000xa5b4c3d2,等等。

浮点数

浮点数也就是小数,之所以称为浮点数,是因为按照科学记数法表示时,一个浮点数的小数点位置是可变的,比如,1.23x109和12.3x108是完全相等的。浮点数可以用数学写法,如1.233.14-9.01,等等。但是对于很大或很小的浮点数,就必须用科学计数法表示,把10用e替代,1.23x109就是1.23e9,或者12.3e8,0.000012可以写成1.2e-5,等等。

整数和浮点数在计算机内部存储的方式是不同的,整数运算永远是精确的(除法难道也是精确的?是的!),而浮点数运算则可能会有四舍五入的误差。

字符串

字符串是以单引号'或双引号"括起来的任意文本,比如'abc'"xyz"等等。请注意,''""本身只是一种表示方式,不是字符串的一部分,因此,字符串'abc'只有abc这3个字符。如果'本身也是一个字符,那就可以用""括起来,比如"I'm OK"包含的字符是I'm,空格,OK这6个字符。

如果字符串内部既包含'又包含"怎么办?可以用转义字符\来标识,比如:

1
'I\'m \"OK\"!'

表示的字符串内容是:

1
2
I'm "OK"!

转义字符\可以转义很多字符,比如\n表示换行,\t表示制表符,字符\本身也要转义,所以\\表示的字符就是\,可以在Python的交互式命令行用print()打印字符串看看:

1
2
3
4
5
6
7
8
>>> print('I\'m ok.')
I'm ok.
>>> print('I\'m learning\nPython.')
I'm learning
Python.
>>> print('\\\n\\')
\
\

如果字符串里面有很多字符都需要转义,就需要加很多\,为了简化,Python还允许用r''表示''内部的字符串默认不转义,可以自己试试:

1
2
3
4
5
>>> print('\\\t\\')
\ \
>>> print(r'\\\t\\')
\\\t\\

如果字符串内部有很多换行,用\n写在一行里不好阅读,为了简化,Python允许用'''...'''的格式表示多行内容,可以自己试试:

1
2
3
4
5
6
>>> print('''line1
... line2
... line3''')
line1
line2
line3

上面是在交互式命令行内输入,注意在输入多行内容时,提示符由>>>变为...,提示你可以接着上一行输入,注意...是提示符,不是代码的一部分:

1
2
3
4
5
6
7
8
9
10
11
┌────────────────────────────────────────────────────────┐
│Command Prompt - python _ □ x │
├────────────────────────────────────────────────────────┤
│>>> print('''line1 │
│... line2 │
│... line3''') │
│line1 │
│line2 │
│line3 │
│ │
│>>> _

当输入完结束符```` 和括号)`后,执行该语句并打印结果。

如果写成程序并存为.py文件,就是:

1
2
3
4
print('''line1
line2
line3''')

多行字符串'''...'''还可以在前面加上r使用

1
2
3
4
5
# -*- coding: utf-8 -*-

print(r'''hello,\n
world''')

布尔值

布尔值和布尔代数的表示完全一致,一个布尔值只有TrueFalse两种值,要么是True,要么是False,在Python中,可以直接用TrueFalse表示布尔值(请注意大小写),也可以通过布尔运算计算出来:

1
2
3
4
5
6
7
8
9
>>> True
True
>>> False
False
>>> 3 > 2
True
>>> 3 > 5
False

布尔值可以用andornot运算。

and运算是与运算,只有所有都为Trueand运算结果才是True

1
2
3
4
5
6
7
8
9
>>> True and True
True
>>> True and False
False
>>> False and False
False
>>> 5 > 3 and 3 > 1
True

or运算是或运算,只要其中有一个为Trueor运算结果就是True

1
2
3
4
5
6
7
8
9
>>> True or True
True
>>> True or False
True
>>> False or False
False
>>> 5 > 3 or 1 > 3
True

not运算是非运算,它是一个单目运算符,把True变成FalseFalse变成True

1
2
3
4
5
6
7
>>> not True
False
>>> not False
True
>>> not 1 > 2
True

布尔值经常用在条件判断中,比如:

1
2
3
4
5
if age >= 18:
print('adult')
else:
print('teenager')

空值

空值是Python里一个特殊的值,用None表示。None不能理解为0,因为0是有意义的,而None是一个特殊的空值。

此外,Python还提供了列表、字典等多种数据类型,还允许创建自定义数据类型,我们后面会继续讲到。

变量

变量的概念基本上和初中代数的方程变量是一致的,只是在计算机程序中,变量不仅可以是数字,还可以是任意数据类型。

变量在程序中就是用一个变量名表示了,变量名必须是大小写英文、数字和_的组合,且不能用数字开头,比如:

1
2
a = 1

变量a是一个整数。

1
2
t_007 = 'T007'

变量t_007是一个字符串。

1
2
Answer = True

变量Answer是一个布尔值True

在Python中,等号=是赋值语句,可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量,例如:

1
2
3
4
5
6
7
# -*- coding: utf-8 -*-

a = 123 # a是整数
print(a)
a = 'ABC' # a变为字符串
print(a)

这种变量本身类型不固定的语言称之为动态语言,与之对应的是静态语言。静态语言在定义变量时必须指定变量类型,如果赋值的时候类型不匹配,就会报错。例如Java是静态语言,赋值语句如下(// 表示注释):

1
2
3
int a = 123; // a是整数类型变量
a = "ABC"; // 错误:不能把字符串赋给整型变量

和静态语言相比,动态语言更灵活,就是这个原因。

请不要把赋值语句的等号等同于数学的等号。比如下面的代码:

1
2
3
x = 10
x = x + 2

如果从数学上理解x = x + 2那无论如何是不成立的,在程序中,赋值语句先计算右侧的表达式x + 2,得到结果12,再赋给变量x。由于x之前的值是10,重新赋值后,x的值变成12

最后,理解变量在计算机内存中的表示也非常重要。当我们写:

1
2
a = 'ABC'

时,Python解释器干了两件事情:

  1. 在内存中创建了一个'ABC'的字符串;
  2. 在内存中创建了一个名为a的变量,并把它指向'ABC'

也可以把一个变量a赋值给另一个变量b,这个操作实际上是把变量b指向变量a所指向的数据,例如下面的代码:

1
2
3
4
5
6
7
# -*- coding: utf-8 -*-

a = 'ABC'
b = a
a = 'XYZ'
print(b)

最后一行打印出变量b的内容到底是'ABC'呢还是'XYZ'?如果从数学意义上理解,就会错误地得出ba相同,也应该是'XYZ',但实际上b的值是'ABC',让我们一行一行地执行代码,就可以看到到底发生了什么事:

执行a = 'ABC',解释器创建了字符串'ABC'和变量a,并把a指向'ABC'

执行b = a,解释器创建了变量b,并把b指向a指向的字符串'ABC'

执行a = 'XYZ',解释器创建了字符串’XYZ’,并把a的指向改为'XYZ',但b并没有更改:

所以,最后打印变量b的结果自然是'ABC'了。

常量

所谓常量就是不能变的变量,比如常用的数学常数π就是一个常量。在Python中,通常用全部大写的变量名表示常量:

1
2
PI = 3.14159265359

但事实上PI仍然是一个变量,Python根本没有任何机制保证PI不会被改变,所以,用全部大写的变量名表示常量只是一个习惯上的用法,如果你一定要改变变量PI的值,也没人能拦住你。

最后解释一下整数的除法为什么也是精确的。在Python中,有两种除法,一种除法是/

1
2
3
>>> 10 / 3
3.3333333333333335

/除法计算结果是浮点数,即使是两个整数恰好整除,结果也是浮点数:

1
2
3
>>> 9 / 3
3.0

还有一种除法是//,称为地板除,两个整数的除法仍然是整数:

1
2
3
>>> 10 // 3
3

你没有看错,整数的地板除//永远是整数,即使除不尽。要做精确的除法,使用/就可以。

因为//除法只取结果的整数部分,所以Python还提供一个余数运算,可以得到两个整数相除的余数:

1
2
3
>>> 10 % 3
1

无论整数做//除法还是取余数,结果永远是整数,所以,整数运算结果永远是精确的。

Python基础

[TOC]

Python简介

Python由荷兰数学和计算机科学研究学会的Guido van Rossum 于1990 年代初设计,作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言,随着版本的不断更新和语言新功能的添加,逐渐被用于独立的、大型项目的开发。
Python解释器易于扩展,可以使用C或C++(或者其他可以通过C调用的语言)扩展新的功能和数据类型。Python 也可用于可定制化软件中的扩展程序语言。Python丰富的标准库,提供了适用于各个主要系统平台的源码或机器码。

Python的语法比较简单,采用缩进方式,写出来的代码就像下面的样子:

1
2
3
4
5
6
# print absolute value of an integer:
a = 100
if a >= 0:
print(a)
else:
print(-a)

#开头的语句是注释,注释是给人看的,可以是任意内容,解释器会忽略掉注释。其他每一行都是一个语句,当语句以冒号:结尾时,缩进的语句视为代码块。

缩进有利有弊。好处是强迫你写出格式化的代码,但没有规定缩进是几个空格还是Tab。按照约定俗成的管理,应该始终坚持使用4个空格的缩进。

缩进的另一个好处是强迫你写出缩进较少的代码,你会倾向于把一段很长的代码拆分成若干函数,从而得到缩进较少的代码。

缩进的坏处就是“复制-粘贴”功能失效了,这是最坑爹的地方。当你重构代码时,粘贴过去的代码必须重新检查缩进是否正确。此外,IDE很难像格式化Java代码那样格式化Python代码。

最后,请务必注意,Python程序是大小写敏感的,如果写错了大小写,程序会报错。

Git 使用指南

[TOC]

Git 使用指南

git命令 版本控制

Git 简介

Git是目前世界上最先进的分布式版本控制系统。

如果你是小白,可以先看廖雪峰的官方教程

git操作流程图

专用名词

  • Workspace: 工作区
  • Index / Stage: 暂存区
  • Repository: 仓库区 ( 本地版本库 )
  • Remote: 远程仓库 ( 远程仓库 / 远程版本库 )

代码库

在当前目录新建一个Git代码库

1
git init

新建一个目录,将其初始化为Git代码库

1
git init [project-name]

克隆代码库

1
git clone [url]

Git 配置

Git的配置文件为 .git/config ,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。

显示当前Git配置

1
git config --list

编辑Git配置文件

1
git config -e [--global] 

设置代码时的用户信息 建议设置此项,后面的操作会很方便

1
git config [--global] user.name "[name]"
1
git config [--global] user.email "[email address]"

增加/删除文件

操作之前先执行 git status 查看一下状态

添加文件到暂存区 建议使用这种方式进行操作

1
git add [file1] [file2] ...

添加所有改动到暂存区

1
git add .

删除工作区文件,并且将这次删除放入暂存区

1
git rm [file1] [file2] ...

停止追踪指定文件,但该文件会保留在工作区

1
git rm --cached [file]

代码提交

操作之前先执行 git status 查看一下状态

提交暂存区到仓库区

1
git commit -m [message]

提交暂存区的指定文件到仓库区

1
git commit [file1] [file2] ... -m [message]

重做上一次commit,并包括指定文件的新变化

1
git commit --amend [file1] [file2] ...

分支

列出所有本地分支

1
git branch

列出所有远程分支

1
git branch -r

列出所有本地分支和远程分支

1
git branch -a

新建一个分支,但依然停留在当前分支

1
git branch [branch-name]

新建一个分支,并切换到该分支

1
git checkout -b [branch]

切换到指定分支,并更新工作区

1
git checkout [branch-name]

合并指定分支到当前分支

1
git merge [branch]

删除本地分支

1
git branch -d [branch-name]

删除远程分支

1
2
3
git push origin --delete [branch-name]
或者
git branch -dr [remote/branch]

查看信息

查看改动的文件

1
git status

查看当前分支的版本日志

1
git log

查看单行日志

1
git log --pretty=oneline

显示暂存区和工作区的差异

1
git diff

显示今天写了多少行代码

1
git diff --shortstat "@{0 day ago}"

标签

列出现有标签

1
git tag

创建一个含附注类型的标签

1
git tag -a v0.5.0 -m 'version 0.5.0'

查看相应标签的版本信息,同时显示打标签时的提交对象

1
git show v0.5.0

push 单个 tag

1
2
3
4
git push origin [tagname]

eg:
git push origin v1.0 #将本地v1.0的tag推送到远端服务器

push 所有 tag , 如果不起作用,在 Git 控制台确认账号是否有权限推送 Tag

1
git push origin --tags

删除本地标签

1
git tag -d [tagName]

删除远程标签

1
git push origin :refs/tags/[tagName]

远程同步

下载远程仓库的所有变动

1
git fetch [remote]

显示所有远程仓库

1
git remote -v

拉取远程仓库的变化,并与本地分支合并

1
git pull [remote] [branch]

上传本地指定分支到远程仓库

1
git push [remote] [branch]

强行推送当前分支到远程仓库,即使有冲突 谨慎使用

1
git push [remote] --force

推送所有分支到远程仓库

1
git push [remote] --all

Git 证书问题

临时生效,退出shell后失效

1
export GIT_SSL_NO_VERIFY=true 

永久生效

1
echo 'export GIT_SSL_NO_VERIFY=true' >> ~/.bashrc 

win10 出现证书问题

1
git config --global http.sslVerify false

撤销

恢复暂存区的指定文件到工作区

1
git checkout [file]

恢复某个commit的指定文件到暂存区和工作区

1
git checkout [commit] [file]

恢复暂存区的所有文件到工作区

1
git checkout .

重置暂存区的指定文件,与上一次commit保持一致,但工作区不变

1
git reset [file]

重置暂存区与工作区,与上一次commit保持一致

1
git reset --hard

回滚到指定版本

1
git reset --hard [commitId]

重建版本库

1
2
3
4
5
6
rm -rf .git
git init
git add .
git commit -a 'git init first commit'
git remote add origin <github_repo_url>
git push -f -u origin master

添加远程仓库

1
2
3
4
5
6
cd existing_folder
git init
git remote add origin git@git.sg-ai.com:ywguo/Test.git
git add .
git commit -m "Initial commit"
git push -u origin master

如何创建公钥

  1. 首先启动一个Git Bash窗口(非Windows用户直接打开终端)

  2. 执行:

    cd ~/.ssh

    如果返回“… No such file or directory”,说明没有生成过SSH Key,直接进入第4步。否则进入第3步备份!

  3. 备份:

    mkdir key_backup
    mv id_isa* key_backup

  4. 生成新的Key:(引号内的内容替换为你自己的邮箱)

    ssh-keygen -t rsa -C “your_email@youremail.com

输出显示:

>Generating public/private rsa key pair. Enter file in which to save the key 
(/Users/your_user_directory/.ssh/id_rsa):<press enter>

直接回车,不要修改默认路劲。

>Enter passphrase (empty for no passphrase):<enter a passphrase>
Enter same passphrase again:<enter passphrase again>

设置一个密码短语,在每次远程操作之前会要求输入密码短语!闲麻烦可以直接回车,不设置。

  1. 成功:

    Your identification has been saved in /Users/your_user_directory/.ssh/id_rsa.
    Your public key has been saved in /Users/your_user_directory/.ssh/id_rsa.pub.
    The key fingerprint is:
    … …

  2. 提交公钥:

    6.1 找到.ssh文件夹,用文本编辑器打开“id_rsa.pub”文件,复制内容到剪贴板。

    6.2 打开 https://github.com/settings/ssh ,点击 Add SSH Key 按钮,粘贴进去保存即可。

git设置用户名密码

设置 git 用户名/邮箱

1
2
git config --global user.name [username]
git config --global user.email [email]

但是这个仅仅是设置用户名密码,如果你的Git 源每次操作需要你输入用户名/密码验证,你依然需要每次设置,那么该如何办呢?

git 保存用户名密码

这里主要是配置一个 config 项

有两个方法,基本上原理都是一样,都是修改 .git/config 文件

1.使用如下命令,修改 config 文件即可保存

1
2
echo "[credential]" >> .git/config
echo " helper = store" >> .git/config

2.直接修改 .git/config 文件

在 Linux/mac 下可以直接使用 vim 工具修改 config 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
ubuntu@VM-7-212-ubuntu:~/kernel-code/kernel-netfilter-sample-code$ vim .git/config

##修改成如下

[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
[remote "origin"]
url = https://github.com/Miss-you/kernel-netfilter-sample-code.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
##主要是后面这两行,如果不想保存,则删除即可
[credential]
helper = store

##保存

这样就可以保存用户名密码,不用每次都输入了!

git config 查看配置

使用 git config --list 查看已设配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
feiqianyousadeMacBook-Pro:xt_GTPU yousa$ git config --list
core.excludesfile=/Users/yousa/.gitignore_global
user.name=Miss-you
user.email=snowfly1993@gmail.com
core.repositoryformatversion=0
core.filemode=true
core.bare=false
core.logallrefupdates=true
core.ignorecase=true
core.precomposeunicode=true
remote.origin.url=https://github.com/Miss-you/xt_GTPU.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
branch.master.remote=origin
branch.master.merge=refs/heads/master

git设置代理

1
2
3
4
5
6
7
8
9
10
11
12
# set socks proxy
git config --global http.proxy socks5://127.0.0.1:1080
git config --global https.proxy socks5://127.0.0.1:1080

# set http proxy
git config --global http.proxy http://127.0.0.1:8001
git config --global https.proxy https://127.0.0.1:1080


# unset
git config --global --unset http.proxy
git config --global --unset https.proxy

操作规范

提交到仓库 description 需要有意义命名

1
git commit -m [description]

分支请及时合并清理

1
2
3
4
git merge [branch]
git push [remote] [branch]
git branch -d [branch-name]
git push origin --delete [branch-name]

请谨慎提交大文件,例如保存切割的图片文件夹

1
git commit -m ["description"]

推送dev分支操作,本地运行项目正常再推送代码

1
2
3
4
git push [remote] [branch]

1. 检查命令行是否出现 `error` 字样的内容,如果出现请及时修改
2. 浏览器上按 `F12` 或者 `右键 -> 检查(N)` 查看`console` 输出是否有明显的 `404 500` 错误,如果有请及时解决
  • 友情提示: 目前只是现在工作中用到的命令整理,如果没有您需要的,请自行 google

  • 文档持续更新中,欢迎大家拍砖 …

openLDAP安装说明

[TOC]

安装 openLDAP 准备

  • 完成各个相互通信的节点的域名解析(DNS)
  • 完成 NFS 将master节点 home目录挂载到其他节点同一路径下
  • 服务器IP、域名、主机名:172.16.10.10 maste.example.com master
  • 关闭防火墙

搭建 LDAP 服务器

  • yum 下载安装
1
$ yum install openldap* migrationtools -y
  • 设置 LDAP 管理密码
1
2
3
4
$ slappasswd
New password:
Re-enter new password:
{SSHA}b28RwTpbqZ5/kxro785tKExdK4uyOX7T ///此密码自行妥善保存
  • 进入配置目录
1
$ cd /etc/openldap/slapd.d/cn=config
  • 编辑文件
1
2
$ vim olcDatabase={2}hdb.ldif

1
2
3
4
5
6
7
替换dc=my-domain,dc=com
olcSuffix: dc=sg-ai,dc=com
olcRootDN: cn=Manager,dc=sg-ai,dc=com
在文档底部加上:
olcRootPW: {SSHA}b28RwTpbqZ5/kxro785tKExdK4uyOX7T
olcTLSCertificateFile: /etc/pki/tls/certs/sg-ai.pem
olcTLSCertificateKeyFile: /etc/pki/tls/certs/sg-aikey.pem
1
$ vim olcDatabase={1}monitor.ldif

同样替换dc=my-domain,dc=com
olcAccess: {0}to * by dn.base=”gidNumber=0+uidNumber=0,cn=peercred,cn=external, cn=auth” read by dn.base=”cn=Manager,dc=linuxhelp,dc=com” read by * none

  • 测试配置文件是否成功
1
$ slaptest -u

显示如下为成功

1
2
3
 5737a49a ldif_read_file: checksum error on "/etc/openldap/slapd.d/cn=config/olcDatabase={1}monitor.ldif"
5737a49a ldif_read_file: checksum error on "/etc/openldap/slapd.d/cn=config/olcDatabase={2}hdb.ldif"
config file testing succeeded
  • 启动 LDAP 服务器
1
$ systemctl start slapd
  • 设置 LDAP 为开机启动
1
$ systemctl enable slapd
  • 配置 LDAP 数据库
1
2
cp /usr/share/openldap-servers/DB_CONFIG.example /var/lib/ldap/DB_CONFIG
chown -R ldap:ldap /var/lib/ldap/
  • 加入 LDAP 方案
1
2
3
4
$ ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
SASL/EXTERNAL authentication started
$ ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/nis.ldif
$ ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
  • 生成证书文件
1
openssl req -new -x509 -nodes -out /etc/pki/tls/certs/sg-ai.pem -keyout /etc/pki/tls/certs/sg-aikey.pem -days 365

按照提示填写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Generating a 2048 bit RSA private key
...........................................+++
.............................................................................................................+++
writing new private key to '/etc/pki/tls/certs/linuxhelpkey.pem'
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [XX]:
State or Province Name (full name) []:
Locality Name (eg, city) [Default City]:
Organization Name (eg, company) [Default Company Ltd]:sgkj
Organizational Unit Name (eg, section) []:sg
Common Name (eg, your name or your server's hostname) []:master.sg-ai.com
Email Address []:

  • 确认生成证书运行的命令
1
ls -l /etc/pki/tls/certs/*.pem
  • 进入 /usr/share/migrationtools/ 目录修改 “migratinos_common.ph” 文件
1
2
$ cd /usr/share/migrationtools/
$ vim migrate_common.ph

修改第 71 行和 74 行为
$DEFAULT_MAIL_DOMAIN = “example.com”;
$DEFAULT_BASE = “dc=example,dc=com”;
修改第 90 行为:
$EXTENDED_SCHEMA = 1;

  • 创建 base.ldif 文件
1
vim /root/base.ldif

写入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
dn: dc=sg-ai,dc=com
objectClass: top
objectClass: dcObject
objectclass: organization
o: sg-ai com
dc: sg-ai

dn: cn=Manager,dc=sg-ai,dc=com
objectClass: organizationalRole
cn: Manager
description: Directory Manager

dn: ou=People,dc=sg-ai,dc=com
objectClass: organizationalUnit
ou: People

dn: ou=Group,dc=sg-ai,dc=com
objectClass: organizationalUnit
ou: Group
  • 创建用户
1
2
3
4
$ useradd test003
$ useradd test004
$ passwd test003
$ passwd test003
  • 将新建用户的信息填写到自建的.ldif文件中
1
2
3
4
5
6
7
8
9
$ tail /etc/passwd >>  /root/passwd
$ vim /root/passwd
test003:x:1001:1001::/home/test003:/bin/bash
test004:x:1002:1002::/home/test004:/bin/bash

$ tail /etc/group >>/root/group
$ vim /root/group
test003:x:1001:
test004:x:1002:
  • 将这些文件转换为 ldif 格式
1
2
$ ./migrate_passwd.pl /root/passwd /root/users.ldif
$ ./migrate_group.pl /root/group /root/groups.ldif
  • 将这些文件导入 LDAP 数据库中
1
2
3
$ ldapadd -x -W -D "cn=Manager,dc=sg-ai,dc=com" -f /root/base.ldif
$ ldapadd -x -W -D "cn=Manager,dc=sg-ai,dc=com" -f /root/users.ldif
$ ldapadd -x -W -D "cn=Manager,dc=sg-ai,dc=com" -f /root/groups.ldif
  • 检查导入数据库后的情况
1
2
$ ldapsearch -x cn=test003 -b dc=example,dc=com
$ ldapsearch -x -b 'dc=sg-ai,dc=com' '(objectclass=*)'

搭建 LDAP 客户机

  • 安装
1
yum install openldap-clients nss-pam-ldapd authconfig -y
  • 设置 LDAP 认证
1
$ authconfig-tui
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
User Information ???????Authentication
[ ] Cache Information ??[ ] Use MD5 Passwords
[*] Use LDAP ????????????[*] Use Shadow Passwords
[ ] Use NIS ???????????????[*] Use LDAP Authentication
[ ] Use IPAv2 ???????????[ ] Use Kerberos
[ ] Use Winbind ????????[ ] Use Fingerprint reader
[ ] Use Winbind Authentication
[*] Local authorization is sufficient


- 选中Use LDAP 和 Use LDAP Authentication即可
用Tab键切换到Next,回车。


[*] Use TLS
Server: ldap://master
Base DN: dc=sg-ai,dc=com

  • Use TLS可以不用选中
  • 测试运行正确与否
1
getent passwd test003

正确显示为:
test003:x:1001:1001::/home/test003:/bin/bash

MongoDB

[TOC]

MongoDB 是一个基于分布式文件存储的数据库。由 C++ 语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。

MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

install

下载完安装包,并解压 tgz

1
2
3
4
curl -O https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-3.0.6.tgz    # 下载
tar -zxvf mongodb-linux-x86_64-3.0.6.tgz # 解压

mv mongodb-linux-x86_64-3.0.6/ /usr/local/mongodb # 将解压包拷贝到指定目录

MongoDB 的可执行文件位于 bin 目录下,所以可以将其添加到 PATH 路径中:

1
export PATH=/usr/local/mongodb/bin:$PATH

docker

这年头有了docker之后,运行MongoDB简直不能太简单了,非常适合开发使用。

1
2
docker pull mongodb:3.4
docker run --name mongodb-dev -p 27017:27017 -v /srv/monggo/mongodb:/data/db -e MONGO_INITDB_ROOT_USERNAME=admin -e MONGO_INITDB_ROOT_PASSWORD=password -d mongo:3.4

mongodb shell

MongoDB Shell是MongoDB自带的交互式Javascript shell,用来对MongoDB进行操作和管理的交互式环境,在MongoDB安装目录下的bin目录,执行mongo命令文件。

当你进入mongoDB后台后,它默认会链接到 test 文档(数据库):

1
2
3
4
5
6
docker exec -it mongodb-dev bash
mongo
use admin
db.auth('admin','password')
exit
exit

下面是一些常见命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 切换到admin database
use admin

# auth
db.auth("admin", "sg-ai")

# show database name
show dbs
show tables
show collections
db.tablename.find()
db.tablename.find([query] , [fields])
db.tablename.find({},{})
db.tablename.find({},{"pid": 1, "id": 1})
db.mytable1.find({"userName": "superman"},{})
db.mytable1.remove({"userName": "superman"},{})
db.mytable2.find()

# createUser and backup
db.createUser({ "user" : "alex", "pwd" : "superman", "roles" : [ { role: "readWrite", db: "finance" } ] })
# mongodump --authenticationDatabase=databasename -u alex -p superman -d tablename -o /data/db/backup

adminMongo

adminMongo 是一个链接MongoDB数据库的可视化工具,开发使用效果极佳。

adminMongo_dbview

run

adminMongo 默认使用 http://0.0.0.0:1234 , 运行之前先安装npm。

1
2
3
git clone -b master --depth 1 https://github.com/mrvautin/adminMongo.git
cd adminMongo && npm install
npm start

backup/restore

数据备份有多重要自然不用多说,下面简要介绍一下导入导出的命令:

导出mongodump:

1
mongodump --authenticationDatabase=database -u username -p password -d auth-database -o /data/db/backup

导入mongorestore:

1
mongorestore --drop -u admin -p superman --authenticationDatabase=admin -d mydatabase /data/db/backup/mydata

导入导出都可以按照database或者collection来操作,具体看帮助。

初识memcached

[TOC]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
memcached:

memcached is a high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load.


缓存服务器:
缓存:cache,无持久存储功能;
bypass缓存
k/v cache,仅支持存储流式化数据;

LiveJournal旗下的Danga Interactive研发,

特性:
k/v cache:仅可序列化数据;存储项:k/v;
智能性一半依赖于客户端(调用memcached的API开发程序),一半依赖于服务端;
分布式缓存:互不通信的分布式集群;
分布式系统请求路由方法:取模法,一致性哈希算法;
算法复杂度:O(1)
清理过期缓存项:
缓存耗尽:LRU
缓存项过期:惰性清理机制

安装配置:
由CentOS 7 base仓库直接提供:
监听的端口:
11211/tcp, 11211/udp

主程序:/usr/bin/memcached
配置文件:/etc/sysconfig/memcached
Unit File:memcached.service

协议格式:memcached协议
文本格式
二进制格式

命令:
统计类:stats, stats items, stats slabs, stats sizes
存储类:set, add, replace, append, prepend
命令格式:<command name> <key> <flags> <exptime> <bytes>
<cas unique>
检索类:get, delete, incr/decr
清空:flush_all

示例:
telnet> add KEY <flags> <expiretime> <bytes> \r
telnet> VALUE

memcached程序的常用选项:
-m <num>:Use <num> MB memory max to use for object storage; the default is 64 megabytes.
-c <num>:Use <num> max simultaneous connections; the default is 1024.
-u <username>:以指定的用户身份来运行进程;
-l <ip_addr>:监听的IP地址,默认为本机所有地址;
-l <ip_addr>:监听的IP地址,默认为本机所有地址;
-p <num>:监听的TCP端口, the default is port 11211.
-U <num>:Listen on UDP port <num>, the default is port 11211, 0 is off.
-M:内存耗尽时,不执行LRU清理缓存,而是拒绝存入新的缓存项,直到有多余的空间可用时为止;
-f <factor>:增长因子;默认是1.25;
-t <threads>:启动的用于响应用户请求的线程数;

memcached默认没有认证机制,可借用于SASL进行认证;
SASL:Simple Authentication Secure Layer

API:
php-pecl-memcache
php-pecl-memcached
python-memcached
libmemcached
libmemcached-devel

命令行工具:
memcached-tool SERVER:PORT COMMAND

Markdown 语法(Typora)

Typora For Markdown 语法

[TOC]

数学表达式

要启用这个功能,首先到Preference->Editor中启用。然后使用$符号包裹Tex命令,例如:$lim_{x \to \infty} \ exp(-x)=0$将产生如下的数学表达式:

$$\lim_{x \to \infty} \exp(-x)=0$$

下标

下标使用~包裹,例如:H~2~O将产生H2O, 即水的分子式。

上标

上标使用^包裹,例如:y^2^=4将产生表达式 y^2^ = 4

插入表情:happy:

使用:happy:输入表情:happy:,使用:sad:输入表情:sad:,使用:cry:输入表情:cry:等。以此类推!

下划线

用HTML的语法<u>Underline</u>将产生下划线Underline.

删除线

GFM添加了删除文本的语法,这是标准的Markdown语法木有的。使用~~包裹的文本将会具有删除的样式,例如~删除文本~将产生删除文本的样式。

代码

  • 使用`包裹的内容将会以代码样式显示,例如
1
使用`printf()`

则会产生printf()样式。

  • 输入~~~或者```然后回车,可以输入代码块,并且可以选择代码的语言。例如:

  • ```java
    public Class HelloWorld{
      System.out.println("Hello World!");
    }
    ​```
    
    1
    2
    3
    4
    5
    6
    7

    将会产生

    ~~~java
    public Class HelloWorld{
    System.out.println("Hello World!");
    }
    ### 强调 使用两个*号或者两个_包裹的内容将会被强调。例如
    1
    2
    **使用两个*号强调内容**
    __使用两个下划线强调内容__
    将会输出 **使用两个*号强调内容** __使用两个下划线强调内容__ Typroa 推荐使用两个*号。 ### 斜体 在标准的Markdown语法中,*和_包裹的内容会是斜体显示,但是GFM下划线一般用来分隔人名和代码变量名,因此我们推荐是用星号来包裹斜体内容。如果要显示星号,则使用转义:
    1
    \*
    ### 插入图片 我们可以通过拖拉的方式,将本地文件夹中的图片或者网络上的图片插入。 ![drag and drop image](http://typora.io/img/drag-img.gif)

插入URL连接

使用尖括号包裹的url将产生一个连接,例如:<www.baidu.com>将产生连接:<www.baidu.com>.

如果是标准的url,则会自动产生连接,例如:www.google.com

目录列表Table of Contents(TOC)

输入[toc]然后回车,将会产生一个目录,这个目录抽取了文章的所有标题,自动更新内容。

水平分割线

使用***或者---,然后回车,来产生水平分割线。


标注

我们可以对某一个词语进行标注。例如

1
2
某些人用过了才知道[^注释]
[^注释]:Somebody that I used to know.

将产生:

某些人用过了才知道[^注释]
[^注释]: Somebody that I used to know.

把鼠标放在注释上,将会有提示内容。

表格

1
2
3
4
5
|姓名|性别|毕业学校|工资|
|:---|:---:|:---:|---:|
|杨洋|男|重庆交通大学|3200|
|峰哥|男|贵州大学|5000|
|坑货|女|北京大学|2000|

将产生:

姓名 性别 毕业学校 工资
杨洋 重庆交通大学 3200
峰哥 贵州大学 5000
坑货 北京大学 2000
其中代码的第二行指定对齐的方式,第一个是左对齐,第二个和第三个是居中,最后一个是右对齐。

数学表达式块

输入两个美元符号,然后回车,就可以输入数学表达式块了。例如:

1
$$\mathbf{V}_1 \times \mathbf{V}_2 =  \begin{vmatrix} \mathbf{i} & \mathbf{j} & \mathbf{k} \\\frac{\partial X}{\partial u} &  \frac{\partial Y}{\partial u} & 0 \\\frac{\partial X}{\partial v} &  \frac{\partial Y}{\partial v} & 0 \\\end{vmatrix}$$

将会产生:

$$\mathbf{V}_1 \times \mathbf{V}_2 = \begin{vmatrix} \mathbf{i} & \mathbf{j} & \mathbf{k} \\frac{\partial X}{\partial u} & \frac{\partial Y}{\partial u} & 0 \\frac{\partial X}{\partial v} & \frac{\partial Y}{\partial v} & 0 \\end{vmatrix}$$

任务列表

使用如下的代码创建任务列表,在[]中输入x表示完成,也可以通过点击选择完成或者没完成。

1
2
3
4
- [ ] 吃饭
- [ ] 逛街
- [ ] 看电影
- [ ] 约泡
  • 吃饭

  • 逛街

  • 看电影

  • 约泡

列表

输入+, -, *,创建无序的列表,使用任意数字开头,创建有序列表,例如:

1
2
3
4
**无序的列表**
* tfboys
* 杨洋
* 我爱你

无序的列表

  • tfboys
  • 杨洋
  • 我爱你
1
2
3
4
**有序的列表**
1. 苹果
6. 香蕉
10. 我都不喜欢

有序的列表

  1. 苹果
  2. 香蕉
  3. 我都不喜欢

块引用

使用>来插入块引用。例如:

1
>这是一个块引用!

将产生:

这是一个块引用!

标题

使用#表示一级标题,##表示二级标题,以此类推,有6个标题。

MySQL

[TOC]

MySQL or MariaDB

MySQL 是最流行的关系型数据库管理系统,在 WEB 应用方面 MySQL 是最好的 RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之一。

run

用docker可以快速运行一个mariadb。

1
docker run -v /mnt/mariadb:/var/lib/mysql --name mariadb -e MYSQL_ROOT_PASSWORD=alex -p 3306:3306 -d mariadb:5.5.60

detail

在本教程中,会让大家快速掌握 MySQL 的基本知识,并轻松使用 MySQL 数据库。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643

MariaDB or MySQL:

层次模型 --> 网状模型 --> (Codd) 关系模型

DBMS --> RDBMS

CRUD:Insert, Select, Update, Delete

RDBMS:
范式:第一范式、第二范式、第三范式;

表:row, column;

关系运算:
选择
投影
连接

数据库:表、索引、视图(虚表)、SQL、存储过程、存储函数、触发器、事件调度器;
DDL:CREATE,ALTER,DROP
DML:INSERT/UPDATE/DELETE/SELECT

约束:
主键约束:惟一、非空;一张表只能有一个;PRIMARY KEY;
惟一键约束:惟一,可以存在多个;UNIQUE KEY;
外键约束:参考性约束;FOREIGN KEY;
检查性约束:check;

三层模型:
物理层 --> SA
逻辑层 --> DBA
视图层 --> Coder

实现:
Oracle, DB2, Sybase, Infomix, SQL Server;
MySQL, MariaDB, PostgreSQL, SQLite;

MySQL:
2000, 开源,GPL;
2001, InnoDB, 支持事务,支持行级锁;MySQL 4.0
2005, MySQL 5.0,游标、存储过程、触发器、视图和事务;

MariaDB:5.5.x --> 10.x

特性:
插件式存储引擎
单进程多线程

安装MySQL:
OS Vendor:rpm
MySQL:
source code:cmake
binary package:
i686, x86_64;
glibc VERSION
prepackage:rpm, deb
os, arch,

服务端程序:
mysqld, mysqld_safe, mysqld_multi
客户端程序:
mysql, mysqldump, mysqlbinlog, mysqldmin, ...
非客户端类程序:
myisamchk, myisampack, ...

ini风格的配置文件,为多个程序同时提供配置;

配置文件:
读取多处的多个配置文件,而且会以指定的次序的进行;

# my_print_defaults

Default options are read from the following files in the given order:
/etc/mysql/my.cnf /etc/my.cnf ~/.my.cnf

不同的配置文件中出现同一参数且拥有不同值时,后读取将为最终生效值;

修改默认读取的配置文件(mysqld_safe命令):
--defaults-file=file_name

于读取的默认配置文件之外再加载一个文件:
--defaults-extra-file=path

配置文件格式:ini风格的配置文件,能够为mysql的各种应用程序提供配置信息:
[mysqld]
[mysqld_safe]
[mysqld_multi]
[server]
[mysql]
[mysqldump]
[client]
...

PARAMETER = VALUE

PARAMETER:
innodb_file_per_table
innodb-file-per-table

程序文件:
服务端程序:mysqld_safe, mysqld_multi
客户端程序:mysql, mysqldump, mysqladmin
工具程序:myisampack, ...

mysql --> mysql protocol --> mysqld
mysql:交互式CLI工具;命令化运行;

mysql [options] db_name

常用选项:
--host=host_name, -h host_name:服务端地址;
--user=user_name, -u user_name:用户名;
--password[=password], -p[password]:用户密码;
--port=port_num, -P port_num:服务端端口;
--protocol={TCP|SOCKET|PIPE|MEMORY}:
本地通信:基于本地回环地址进行请求,将基于本地通信协议;
Linux:SOCKET
Windows:PIPE,MEMORY
非本地通信:使用非本地回环地址进行的请求; TCP协议;
--socket=path, -S path
--database=db_name, -D db_name:
--compress, -C:数据压缩传输
--execute=statement, -e statement:非交互模式执行SQL语句;
--vertical, -E:查询结果纵向显示;

命令:
客户端命令:于客户端执行;
服务端命令:SQL语句,需要一次性完整地发往服务端;语句必须有结束符;

? (\?) Synonym for `help'.
clear (\c) Clear the current input statement.
connect (\r) Reconnect to the server. Optional arguments are db and host.
delimiter (\d) Set statement delimiter.
edit (\e) Edit command with $EDITOR.
ego (\G) Send command to mysql server, display result vertically.
exit (\q) Exit mysql. Same as quit.
go (\g) Send command to mysql server.
help (\h) Display this help.
nopager (\n) Disable pager, print to stdout.
notee (\t) Don't write into outfile.
pager (\P) Set PAGER [to_pager]. Print the query results via PAGER.
print (\p) Print current command.
prompt (\R) Change your mysql prompt.
quit (\q) Quit mysql.
rehash (\#) Rebuild completion hash.
source (\.) Execute an SQL script file. Takes a file name as an argument.
status (\s) Get status information from the server.
system (\!) Execute a system shell command.
tee (\T) Set outfile [to_outfile]. Append everything into given outfile.
use (\u) Use another database. Takes database name as argument.
charset (\C) Switch to another charset. Might be needed for processing binlog with multi-byte charsets.
warnings (\W) Show warnings after every statement.
nowarning (\w) Don't show warnings after every statement.

mysql命令的使用帮助:
# man mysql
# mysql --help --verbose

sql脚本运行:
mysql [options] [DATABASE] < /PATH/FROM/SOME_SQL_SCRIPT


mysqld服务器程序:工作特性的定义方式
命令行选项
配置文件参数

服务器参数/变量:设定MySQL的运行特性;
mysql> SHOW [GLOBAL | SESSION] VARIABLES [like_or_where];
状态(统计)参数/变量:保存MySQL运行过程中的统计数据或状态数据;
mysql> SHOW [GLOBAL | SESSION] STATUS [like_or_where];

显示单个变量设定值的方法:
mysql> SELECT @@[global.|session.]system_var_name

%:匹配任意长度的任意字符;
_:匹配任意单个字符;

变量/参数级别:
全局:为所有会话设定默认;
会话:跟单个会话相关;会话建立会从全局继承;

服务器变量的调整方式:
运行时修改:
global:仅对修改后新建立的会话有效;
session:仅对当前会话有效,且立即生效;
通过配置文件修改:
重启后生效;

运行时修改服务器变量值操作方法:
mysql> HELP SET

SET [GLOBAL | SESSION] system_var_name = expr
SET [@@global. | @@session. | @@]system_var_name = expr

安装完成后的安全初始化:
mysql_secure_installation

运行前常修改的参数:
innodb_file_per_table=ON
skip_name_resolve=ON
sql_safe_updates=ON
...

SQL接口:

SQL:ANSI SQL
SQL-86, SQL-89, SQL-92, SQL-99, SQL-03, ...

MySQL的数据类型:
字符型
数值型
日期时间型
内建类型

字符型:
CHAR(#), BINARY(#):定长型;CHAR不区分字符大小写,而BINARY区分;
VARCHAR(#), VARBINARY(#):变长型
TEXT:TINYTEXT,TEXT,MEDIUMTEXT,LONGTEXT
BLOB:TINYBLOB,BLOB,MEDIUMBLOB, LONGBLOB
Binary Large OBject
数值型:
浮点型:近似
FLOAT
DOUBLE
REAL
BIT
整型:精确
INTEGER:TINYINT,SMALLINT,MEDIUMINT,INT,BIGINT
DECIMAL
日期时间型:
日期:DATE
时间:TIME
日期j时间:DATETIME
时间戳:TIMESTAMP
年份:YEAR(2), YEAR(4)
内建:
ENUM:枚举
ENUM('Sun','Mon','Tue','Wed')
SET:集合

类型修饰符:
字符型:NOT NULL,NULL,DEFALUT ‘STRING’,CHARACET SET ‘CHARSET’,COLLATION ‘collocation'
整型:NOT NULL, NULL, DEFALUT value, AUTO_INCREMENT, UNSIGNED
日期时间型:NOT NULL, NULL, DEFAULT

help 'Data Types'

SQL MODE:定义mysqld对约束等违反时的响应行为等设定;
常用的MODE:
TRADITIONAL
STRICT_TRANS_TABLES
STRICT_ALL_TABLES

修改方式:
mysql> SET GLOBAL sql_mode='MODE';
mysql> SET @@global.sql_mode='MODE';

SQL:DDL,DML
DDL:Data Defination Language
mysql> HELP Data Definition

CREATE, ALTER, DROP
DATABASE, TABLE
INDEX, VIEW, USER
FUNCTION, FUNCTION UDF, PROCEDURE, TABLESPACE, TRIGGER, SERVER

DML: Data Manipulation Language
mysql> HELP Data Manipulation

INSERT/REPLACE, DELETE, SELECT, UPDATE

数据库:
CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_name CHARACTER SET [=] charset_name COLLATE [=] collation_name

ALTER {DATABASE | SCHEMA} [db_name] CHARACTER SET [=] charset_name COLLATE [=] collation_name

DROP {DATABASE | SCHEMA} [IF EXISTS] db_name

表:
CREATE
(1) CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
(create_definition,...)
[table_options]
[partition_options]

CREATE TABLE [IF NOT EXISTS] tble_name (col_name data_typ|INDEX|CONSTRAINT);

table_options:
ENGINE [=] engine_name

查看支持的所有存储引擎:
mysql> SHOW ENGINES;

查看指定表的存储引擎:
mysql> SHOW TABLE STATUS LIKE clause;

ROW_FORMAT [=] {DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}

(2) CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
[(create_definition,...)]
[table_options]
[partition_options]
select_statement

直接创建表,并将查询语句的结果插入到新创建的表中;

(3) CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name
{ LIKE old_tbl_name | (LIKE old_tbl_name) }

复制某存在的表的结构来创建新的空表;

DROP:
DROP [TEMPORARY] TABLE [IF EXISTS] tbl_name [, tbl_name];

ALTER:
ALTER TABLE tbl_name
[alter_specification [, alter_specification] ...]

可修改内容:
(1) table_options
(2) 添加定义:ADD
字段、字段集合、索引、约束
(3) 修改字段:
CHANGE [COLUMN] old_col_name new_col_name column_definition [FIRST|AFTER col_name]
MODIFY [COLUMN] col_name column_definition [FIRST | AFTER col_name]
(4) 删除操作:DROP
字段、索引、约束

表重命名:
RENAME [TO|AS] new_tbl_name

查看表结构定义:
DESC tbl_name;

查看表定义:
SHOW CREATE TABLE tbl_name

查看表属性信息:
SHOW TABLE STATUS [{FROM | IN} db_name] [LIKE 'pattern' | WHERE expr]

索引:数据结构
创建:
CREATE [UNIQUE|FULLTEXT|SPATIAL] INDEX index_name [index_type] ON tbl_name (index_col_name,...)

查看:
SHOW {INDEX | INDEXES | KEYS} {FROM | IN} tbl_name [{FROM | IN} db_name] [WHERE expr]

删除:
DROP INDEX index_name ON tbl_name

索引类型:
聚集索引、非聚集索引:索引是否与数据存在一起;
主键索引、辅助索引
稠密索引、稀疏索引:是否索引了每一个数据项;
BTREE(B+)、HASH、R Tree、FULLTEXT
BTREE:左前缀;

EXPLAIN:分析查询语句的执行路径;

视图:VIEW
虚表:存储下来的SELECT语句;

创建:
CREATE VIEW view_name [(column_list)] AS select_statement

修改:
ALTER VIEW view_name [(column_list)] AS select_statement

删除:
DROP VIEW [IF EXISTS] view_name [, view_name] ...

DML:
INSERT/REPLACE,DELETE,UPDATE,SELECT

INSERT:
单行插入
批量插入

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
{VALUES | VALUE} ({expr | DEFAULT},...),(...),...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]



Or:

INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name
SET col_name={expr | DEFAULT}, ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]

Or:

INSERT [LOW_PRIORITY | HIGH_PRIORITY] [IGNORE]
[INTO] tbl_name [(col_name,...)]
SELECT ...
[ ON DUPLICATE KEY UPDATE
col_name=expr
[, col_name=expr] ... ]

DELETE:

DELETE FROM tbl_name [WHERE where_condition] [ORDER BY ...] [LIMIT row_count]

注意:一定要有限制条件,否则将清空整个表;
限制条件:
[WHERE where_condition]
[ORDER BY ...] [LIMIT row_count]

UPDATE:

UPDATE table_reference SET col_name1={expr1|DEFAULT} [, col_name2={expr2|DEFAULT}] ...
[WHERE where_condition]
[ORDER BY ...]
[LIMIT row_count]

注意:一定要有限制条件,否则将修改整个表中指定字段的数据;
限制条件:
[WHERE where_condition]
[ORDER BY ...] [LIMIT row_count]


注意:sql_safe_updates变量可阻止不带条件更新操作;

SELECT:

Query Cache:缓存查询的执行结果;
key:查询语句的hash值;
value:查询语句的执行结果;

SQL语句的编写方式:
SELECT name FROM tbl2;
select name from tbl2;

查询执行路径:
请求-->查询缓存:命中后返回;
请求-->查询缓存-->解析器-->预处理器-->优化器-->查询执行引擎-->存储引擎-->缓存-->响应


SELECT语句的执行流程:
FROM --> WHERE --> Group By --> Having --> Order BY --> SELECT --> Limit

单表查询:

SELECT
[ALL | DISTINCT | DISTINCTROW ]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr [, select_expr ...]
[FROM table_references
[WHERE where_condition]
[GROUP BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_condition]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]

用法:
SELECT col1, col2, ... FROM tble_name;
SELECT col1, col2, ... FROM tble_name WHERE clause;
SELECT col1, col2, ... FROM tble_name [WHERE clause] GROUP BY col_name [HAVING clause];
分组的目的在于聚合计算:avg, max, min, count, sum,

DISTINCT:数据去重;
SQL_CACHE:显式指定缓存查询语句的结果;
SQL_NO_CACHE:显式指定不缓存查询语句的结果;

query_cache_type服务器变量有三个值:
ON:启用;
SQL_NO_CACHE:不缓存;默认符合缓存条件都缓存;
OFF:关闭;
DEMAND:按需缓存;
SQL_CACHE:缓存;默认不缓存;

字段可以使用别名 :
col1 AS alias1, col2 AS alias2, ...

WHERE子句:指明过滤条件以实现“选择”功能;
过滤条件:布尔型表达式;

[WHERE where_condition]
算术操作符:+, -, *, /, %
比较操作符:=, <>, !=, <=>, >, >=, <, <=

IS NULL, IS NOT NULL
区间:BETWEEN min AND max
IN:列表;
LIKE:模糊比较,%和_;
RLIKE或REGEXP

逻辑操作符:
AND, OR, NOT, XOR

GROUP BY:根据指定的字段把查询的结果进行“分组”以用于“聚合”运算;
avg(), max(), min(), sum(), count()

HAVING:对分组聚合后的结果进行条件过滤;

ORDER BY:根据指定的字段把查询的结果进行排序;
升序:ASC
降序:DESC

LIMIT:对输出结果进行数量限制
[LIMIT {[offset,] row_count | row_count OFFSET offset}]


多表查询:
连接操作:
交叉连接:笛卡尔乘积;
内连接:
等值连接:让表之间的字段以等值的方式建立连接;
不等值连接:
自然连接
自连接
外连接:
左外连接:
FROM tb1 LEFT JOIN tb2 ON tb1.col = tb2.col
右外连接:
FROM tb1 RIGHT JOIN tb2 ON tb1.col = tb2.col

子查询:在查询中嵌套查询;

用于WHERE子句中的子查询;
(1) 用于比较表达式中的子查询:子查询仅能返回单个值;
(2) 用于IN中的子查询:子查询可以返回一个列表值;
(3) 用于EXISTS中的子查询:
用于FROM子句中的子查询;
SELECT tb_alias.col1, ... FROM (SELECT clause) AS tb_alias WHERE clause;

联合查询:将多个查询语句的执行结果相合并;
UNION
SELECT clause UNION SELECT cluase;


练习:导入hellodb.sql生成数据库
(1) 在students表中,查询年龄大于25岁,且为男性的同学的名字和年龄;
(2) 以ClassID为分组依据,显示每组的平均年龄;
(3) 显示第2题中平均年龄大于30的分组及平均年龄;
(4) 显示以L开头的名字的同学的信息;
(5) 显示TeacherID非空的同学的相关信息;
(6) 以年龄排序后,显示年龄最大的前10位同学的信息;
(7) 查询年龄大于等于20岁,小于等于25岁的同学的信息;用三种方法;



练习:导入hellodb.sql,以下操作在students表上执行
1、以ClassID分组,显示每班的同学的人数;
2、以Gender分组,显示其年龄之和;
3、以ClassID分组,显示其平均年龄大于25的班级;
4、以Gender分组,显示各组中年龄大于25的学员的年龄之和;


练习:导入hellodb.sql,完成以下题目:
1、显示前5位同学的姓名、课程及成绩;
2、显示其成绩高于80的同学的名称及课程;
3、求前8位同学每位同学自己两门课的平均成绩,并按降序排列;
4、显示每门课程课程名称及学习了这门课的同学的个数;


思考:
1、如何显示其年龄大于平均年龄的同学的名字?
2、如何显示其学习的课程为第1、2,4或第7门课的同学的名字?
3、如何显示其成员数最少为3个的班级的同学中年龄大于同班同学平均年龄的同学?
4、统计各班级中年龄大于全校同学平均年龄的同学。


存储引擎:
表类型:表级别概念,不建议在同一个库中的表上使用不同的ENGINE;

CREATE TABLE ... ENGINE[=]STORAGE_ENGINE_NAME ...
SHOW TABLE STATUS

常见的存储引擎:
MyISAM, Aria, InnoDB, MRG_MYISAM, CSV, BLACKHOLE, MEMORY, PERFORMANCE_SCHEMA, ARCHIVE, FEDERATED

InnoDB:InnoBase
Percona-XtraDB, Supports transactions, row-level locking, and foreign keys

数据存储于“表空间(table space)"中:
(1) 所有InnoDB表的数据和索引存储于同一个表空间中;
表空间文件:datadir定义的目录中
文件:ibdata1, ibdata2, ...
(2) innodb_file_per_table=ON,意味着每表使用单独的表空间文件;
数据文件(数据和索引,存储于数据库目录): tbl_name.ibd

表结构的定义:在数据库目录,tbl_name.frm

事务型存储引擎,适合对事务要求较高的场景中;但较适用于处理大量短期事务;
基于MVCC(Mutli Version Concurrency Control)支持高并发;支持四个隔离级别,默认级别为REPEATABLE-READ;间隙锁以防止幻读;
使用聚集索引(主键索引);
支持”自适应Hash索引“;
锁粒度:行级锁;间隙锁;

总结:
数据存储:表空间;
并发:MVCC,间隙锁,行级锁;
索引:聚集索引、辅助索引;
性能:预读操作、内存数据缓冲、内存索引缓存、自适应Hash索引、插入操作缓存区;
备份:支持热备;

MyISAM:

支持全文索引(FULLTEXT index)、压缩、空间函数(GIS);
不支持事务
锁粒度:表级锁
崩溃无法保证表安全恢复

适用场景:只读或读多写少的场景、较小的表(以保证崩溃后恢复的时间较短);

文件:每个表有三个文件,存储于数据库目录中
tbl_name.frm:表格式定义;
tbl_name.MYD:数据文件;
tbl_name.MYI:索引文件;

特性:
加锁和并发:表级锁;
修复:手动或自动修复、但可能会丢失数据;
索引:非聚集索引;
延迟索引更新;
表压缩;

行格式:
{DEFAULT|DYNAMIC|FIXED|COMPRESSED|REDUNDANT|COMPACT}

其它的存储引擎:
CSV:将CSV文件(以逗号分隔字段的文本文件)作为MySQL表文件;
MRG_MYISAM:将多个MyISAM表合并成的虚拟表;
BLACKHOLE:类似于/dev/null,不真正存储数据;
MEMORY:内存存储引擎,支持hash索引,表级锁,常用于临时表;
FEDERATED: 用于访问其它远程MySQL服务器上表的存储引擎接口;

MariaDB额外支持很多种存储引擎:
OQGraph、SphinxSE、TokuDB、Cassandra、CONNECT、SQUENCE、...

搜索引擎:
lucene, sphinx
lucene:Solr, Elasticsearch


并发控制:
锁:Lock

锁类型 :
读锁:共享锁,可被多个读操作共享;
写锁:排它锁,独占锁;

锁粒度:
表锁:在表级别施加锁,并发性较低;
行锁:在行级另施加锁,并发性较高;

锁策略:在锁粒度及数据安全性之间寻求一种平衡机制;

存储引擎:级别以及何时施加或释放锁由存储引擎自行决定;
MySQL Server:表级别,可自行决定,也允许显式请求;

锁类别:
显式锁:用户手动请求的锁;
隐式锁:存储引擎自行根据需要施加的锁;

显式锁的使用:
(1) LOCK TABLES

LOCK TABLES tbl_name read|write, tbl_name read|write, ...

UNLOCK TABLES

(2) FLUSH TABLES
FLUSH TABLES tbl_name,... [WITH READ LOCK];

UNLOCK TABLES;

(3) SELECT cluase
[FOR UPDATE | LOCK IN SHARE MODE]



回顾:
连接查询:内连接、外连接;
存储引擎:InnoDB, MyISAM
InnoDB:
表空间文件:
(1) 所有表空间使用同一个文件;
(2) 每表使用单独的表空间;
事务日志:
事务日志组:2+ files
事务日志组镜像:1
MyISAM:
表级锁
tbl.frm, tbl.MYD, tbl.MYI
全文索引、空间索引
锁:
LOCK TABLES
FLUSH TABLES WITH READ LOCK
UNLOCK TABLES

MySQL(2)



事务:
事务:一组原子性的SQL查询、或者是一个或多个SQL语句组成的独立工作单元;

事务日志:
innodb_log_files_in_group
innodb_log_group_home_dir
innodb_log_file_size
innodb_mirrored_log_groups

ACID测试:
A:AUTOMICITY,原子性;整个事务中的所有操作要么全部成功执行,要么全部失败后回滚;
C:CONSISTENCY,一致性;数据库总是应该从一个一致性状态转为另一个一致性状态;
I:ISOLATION,隔离性;一个事务所做出的操作在提交之前,是否能为其它事务可见;出于保证并发操作之目的,隔离有多种级别;
D:DURABILITY,持久性;事务一旦提交,其所做出的修改会永久保存;

自动提交:单语句事务
mysql> SELECT @@autocommit;
+------------------------+
| @@autocommit |
+------------------------+
| 1 |
+------------------------+

mysql> SET @@session.autocommit=0;

手动控制事务:
启动:START TRANSACTION
提交:COMMIT
回滚:ROLLBACK

事务支持savepoints:
SAVEPOINT identifier
ROLLBACK [WORK] TO [SAVEPOINT] identifier
RELEASE SAVEPOINT identifier

事务隔离级别:
READ-UNCOMMITTED:读未提交 --> 脏读;
READ-COMMITTED:读提交--> 不可重复读;
REPEATABLE-READ:可重复读 --> 幻读;
SERIALIZABLE:串行化;

mysql> SELECT @@session.tx_isolation;
+----------------------------------+
| @@session.tx_isolation |
+----------------------------------+
| REPEATABLE-READ |
+----------------------------------+

查看InnoDB存储引擎的状态信息:
SHOW ENGINE innodb STATUS;






MySQL用户和权限管理
用户账号:user@host
user:账户名称;
host:此账户可通过哪些客户端主机请求创建连接线程;
%:任意长度牟任意字符;
_:任意单个字符;

MySQL权限类别:
库级别:
表级别:
字段级别:
管理类:
程序类:

管理类:
CREATE USER
RELOAD
LOCK TABLES
REPLICATION CLIENT, REPLICATION SLAVE
SHUTDOWN
FILE
SHOW DATABASES
PROCESS
SUPER

程序类:
FUNCTION,PROCEDURE,TRIGGER

操作:CREATE,ALTER,DROP,EXECUTE

库和表级别:
CREATE,ALTER,DROP
INDEX
CREATE VIEW
SHOW VIEW
GRANT
OPTION:能够把自己获得的权限生成一个副本转赠给其它用户;

数据操作:
表:
INSERT/DELETE/UPDATE/SELECT

字段:
SELECT(col1,col2,...)
UPDATE(col1,col2,...)
INSERT(col1,col2,...)

所有权限:ALL, ALL PRIVILEGES

元数据数据库(数据字典):mysql
授权:
db, host, user
tables_priv, column_priv, procs_priv, proxies_priv


MySQL用户管理:
'user'@'host';
host:
IP
主机名
NETWORK
%, _

skip_name_resolve={ON|OFF}

创建用户:
CREATE USER 'user'@'host' [IDENTIFIED BY [PASSWORD] 'password'] [,'user'@'host' [IDENTIFIED BY [PASSWORD] 'password']...]

重命名:RENAME USER
RENAME USER old_user TO new_user[, old_user TO new_user] ...

删除用户:
DROP USER 'user'@'host' [, 'user'@'host'] ...

修改用户密码:
(1) SET PASSWORD [FOR 'user'@'host'] = PASSWORD('cleartext password');
(2) UPDATE mysql.user SET Password=PASSWORD('cleartext password') WHERE User='USERNAME' AND Host='HOST';
(3) mysqladmin -uUSERNAME -hHOST -p password 'NEW_PASS'

生效:FLUSH PRIVILEGES

忘记管理员密码的解决办法:
(1) 启动mysqld进程时,使用--skip-grant-tables和--skip-networking选项;
CentOS 7:mariadb.service
CentOS 6:/etc/init.d/mysqld
(2) 通过UPDATE命令修改管理员密码;
(3) 以正常 方式启动mysqld进程;

授权:GRANT
GRANT priv_type [(column_list)] [, priv_type [(column_list)]] ...
ON [object_type] priv_level
TO user_specification [, user_specification] ...
[REQUIRE {NONE | ssl_option [[AND] ssl_option] ...}]
[WITH with_option ...]

object_type:
TABLE
| FUNCTION
| PROCEDURE

priv_level:
*
| *.*
| db_name.*
| db_name.tbl_name
| tbl_name
| db_name.routine_name


ssl_option:
SSL
| X509
| CIPHER 'cipher'
| ISSUER 'issuer'
| SUBJECT 'subject'

with_option:
GRANT OPTION
| MAX_QUERIES_PER_HOUR count
| MAX_UPDATES_PER_HOUR count
| MAX_CONNECTIONS_PER_HOUR count
| MAX_USER_CONNECTIONS count

查看授权:SHOW GRANTS
SHOW GRANTS [FOR 'user'@'host']

取消授权:REVOKE
REVOKE priv_type [(column_list)][, priv_type [(column_list)]] ...
ON [object_type] priv_level
FROM 'user'@'host' [, 'user'@'host'] ...

REVOKE ALL PRIVILEGES, GRANT OPTION
FROM user [, user] ...

练习:授权一个仅能够通过ssl连接的用户账号,而后完成连接测试;



查询缓存:

缓存:k/v
key:查询语句的hash值
value:查询语句的执行结果

如何判断缓存是否命中:
通过查询语句的哈希值判断:哈希值考虑的因素包括
查询本身、要查询数据库、客户端使用的协议版本、...

哪些查询可能不会被缓存?
查询语句中包含UDF
存储函数
用户自定义变量
临时表
mysql系统表或者是包含列级别权限的查询
有着不确定结果值的函数(now());

查询缓存相关的服务器变量:
query_cache_limit:能够缓存的最大查询结果;(单语句结果集大小上限)
有着较大结果集的语句,显式使用SQL_NO_CACHE,以避免先缓存再移出;
query_cache_min_res_unit:内存块的最小分配单位;缓存过小的查询结果集会浪费内存空间;
较小的值会减少空间浪费,但会导致更频繁地内存分配及回收操作;
较大值的会带来空间浪费;
query_cache_size:查询缓存空间的总共可用的大小;单位是字节,必须是1024的整数倍;
query_cache_strip_comments
query_cache_type:缓存功能启用与否;
ON:启用;
OFF:禁用;
DEMAND:按需缓存,仅缓存SELECT语句中带SQL_CACHE的查询结果;
query_cache_wlock_invalidate:如果某表被其它连接锁定,是否仍然可以从查询缓存中返回查询结果;默认为OFF,表示可以;ON则表示不可以;

状态变量:
mysql> SHOW GLOBAL STATUS LIKE 'Qcache%';
+-------------------------+----------+
| Variable_name | Value |
+-------------------------+----------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 16759688 |
| Qcache_hits | 0 |
| Qcache_inserts | 0 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 0 |
| Qcache_queries_in_cache | 0 |
| Qcache_total_blocks | 1 |
+-------------------------+----------+

命中率:
Qcache_hits/Com_select


回顾:事务、权限和用户
事务:ACID测试、事务隔离级别
用户:user@host
权限:
管理类、程序类、数据类;
GRANT,REVOKE


MySQL(4)

MySQL的索引:

索引:提取索引的创建在的表上字段中的数据,构建出一个独特的数据结构;

索引的作用:加速查询操作;
表中数据子集:把表中某个或某些字段的数据提取出来另存为一个特定数据结构组织的数据;
某个字段或某些字段:WHERE子句中用到的字段;

索引类型:B+ TREE,HASH
B+ TREE:顺序存储,每一个叶子结点到根结点的距离相同;左前缀索引,适合于范围类型的数据查询;

适用于B+ TREE索引的查询类型:全键值、键值范围或键前缀;
全值匹配:精确匹配某个值;
WHERE CLOUMN = 'value';
匹配最左前缀:只精确起头的部分;
WEHRE COLUMN LIKE 'PREFIX%';
匹配范围值:
精确匹配某一列,范围匹配另一列;
只用访问索引的查询:覆盖索引;
index(Name)
SELECT Name FROM students WHERE Name LIKE 'L%';

不适用B+ TREE索引:
如查条件不是从最左侧列开始,索引无效;
index(age,name), WHERE name='Jerry';, WHERE age>30;
不能跳过索引中的某列;
index(name,age,gender)
WHERE second_name='black' and age > 30;
如果查询中的某个列是为范围查询,那么其右侧的列都无法再使用索引优化查询;

Hash索引:基于哈希表实现,特别适用于值的精确匹配查询;

适用场景:
只支持等值比较查询,例如=, IN(), <=>

不用场景:
所有非精确值查询;MySQL仅对memory存储引擎支持显式的hash索引;

索引优点:
降低需要扫描的数据量,减少了IO次数;
可以帮助避免排序操作,避免使用临时表;
帮助将随机IO转为顺序IO;

高性能索引策略:
(1) 在WHERE中独立使用列,尽量避免其参与运算;
WHERE age > 30 ;
(2) 左前缀索引:索引构建于字段的最左侧的多少个字符,要通过索引选择性来评估
索引选择性:不重复的索引值和数据表的记录总数的比值;
(3) 多列索引:
AND连接的多个查询条件更适合使用多列索引,而非多个单键索引;
(4) 选择合适的索引列次序:选择性最高的放左侧;

EXPLAIN来分析索引有效性:

EXPLAIN [explain_type] SELECT select_options

explain_type:
EXTENDED
| PARTITIONS

输出结果:
id: 1
select_type: SIMPLE
table: students
type: const
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: const
rows: 1
Extra:

id:当前查询语句中,第个SELECT语句的编号;

复杂的查询的类型主要三种:
简单子查询
用于FROM中的子查询
联合查询

注意:联合查询的分析结果会出现一个额外的匿名临时表;

select_type:查询类型:
简单查询:SIMPLE
复杂查询:
简单子查询:SUBQUERY
用于FROM中的子查询:DERIVED
联合查询中的第一个查询:PRIMARY
联合查询中的第一个查询之后的其它查询:UNION
联合查询生成的临时表:UNION RESULT

table:查询针对的表;

type:关联类型,或称为访问类型,即MySQL如何去查询表中的行
ALL:全表扫描;
index:根据索引的顺序进行的全表扫描;但同时如果Extra列出现了"Using index”表示使用了覆盖索引;
range:有范围限制地根据索引实现范围扫描;扫描位置始于索引中的某一项,结束于另一项;
ref:根据索引返回的表中匹配到某单个值的所有行(匹配给定值的行不止一个);
eq_ref:根据索引返回的表中匹配到某单个值的单一行,仅返回一个行,但需要与某个额外的参考值比较,而不是常数;
const,system:与某个常数比较,且只返回一行;

possiable_keys:查询中可能会用到的索引;

key:查询中使用的索引;

key_len:查询中用到的索引长度;

ref:在利用key字段所显示的索引完成查询操作时所引用的列或常量值;

rows:MySQL估计出的为找到所有的目标项而需要读取的行数;

Extra:额外信息
Using index:使用了覆盖索引进行的查询;
Using where:拿到数据后还要再次进行过滤;
Using temporary:使用了临时表以完成查询;
Using filesort:对结果使用了一个外部索引排序;



日志:
查询日志:general_log
慢查询日志:log_slow_queries
错误日志:log_error, log_warnings
二进制日志:binlog
中继日志:relay_log
事务日志:innodb_log

1、查询日志
记录查询语句,日志存储位置:
文件:file
表:table (mysql.general_log)

general_log={ON|OFF}
general_log_file=HOSTNAME.log
log_output={FILE|TABLE|NONE}

2、慢查询日志
慢查询:运行时间超出指定时长的查询;
long_query_time
存储位置:
文件:FILE
表:TABLE,mysql.slog_log

log_slow_queries={ON|OFF}
slow_query_log={ON|OFF}
slow_query_log_file=
log_output={FILE|TABLE|NONE}
log_slow_filter=admin,filesort,filesort_on_disk,full_join,full_scan,query_cache,query_cache_miss,tmp_table,tmp_table_on_disk
log_slow_rate_limit
log_slow_verbosity

3、错误日志
记录信息:
(1) mysqld启动和关闭过程 输出的信息;
(2) mysqld运行中产生的错误信息;
(3) event scheduler运行时产生的信息;
(4) 主从复制架构中,从服务器复制线程启动时产生的日志;

log_error=
log_warnings={ON|OFF}

4、二进制日志
用于记录引起数据改变或存在引起数据改变的潜在可能性的语句(STATEMENT)或改变后的结果(ROW),也可能是二者混合;
功用:“重放”

binlog_format={STATEMENT|ROW|MIXED}
STATEMENT:语句;
ROW:行;
MIXED:混编;

查看二进制日志文件列表:
SHOW MASTER|BINARY LOGS;

查看当前正在使用的二进制日志文件:
SHOW MASTER STATUS;

查看二进制 日志文件中的事件:
SHOW BINLOG EVENTS [IN 'log_name'] [FROM pos] [LIMIT [offset,] row_count]

服务器变量:
log_bin=/PATH/TO/BIN_LOG_FILE
sql_log_bin={ON|OFF}
max_binlog_size=1073741824
sync_binlog={1|0}

mysqlbinlog:
YYYY-MM-DD hh:mm:ss

--start-datetime=
--stop-datetime=

-j, --start-position=#
--stop-position=#

--user, --host, --password

二进制日志事件格式:
# at 553
#160831 9:56:08 server id 1 end_log_pos 624 Query thread_id=2 exec_time=0 error_code=0
SET TIMESTAMP=1472608568/*!*/;
BEGIN
/*!*/;

事件发生的日期时间:#160831 9:56:08
事件发生的服务器id:server id 1
事件的结束位置:end_log_pos 624
事件的类型:Query
事件发生时所在服务器执行此事件的线程的ID: thread_id=2
语句的时间戳与将其写入二进制日志文件中的时间差:exec_time=0
错误代码:error_code=0
事件内容:SET TIMESTAMP=1472608568/*!*/;

中继日志:
从服务器上记录下来从主服务器的二进制日志文件同步过来的事件;


事务日志:
事务型存储引擎innodb用于保证事务特性的日志文件:

redo log
undo log


备份和恢复(数据):

备份:存储的数据副本;
原始数据:持续改变;
恢复:把副本应用到线上系统;
仅能恢复至备份操作时刻的数据状态;

时间点恢复:
binary logs;

为什么备份?
灾难恢复:硬件故障(冗余)、软件故障(bug)、自然灾害、黑客攻击、误操作、...
测试;

备份时应该注意事项:
能容忍最多丢失多少数据;
恢复数据需要在多长时间内完成;
需要恢复哪些数据;

做恢复演练:
测试备份的可用性;
增强恢复操作效率;
...

备份类型:
备份的数据的集范围:
完全备份和部分备份
完全备份:整个数据集;
部分备份:数据集的一部分,比如部分表;

完全备份、增量备份、差异备份:
完全备份
增量备份:仅备份自上一次完全备份或 增量备份以来变量的那部数据;
差异备份:仅备份自上一次完全备份以来变量的那部数据;

物理备份、逻辑备份:
物理备份:复制数据文件进行备份;
逻辑备份:从数据库导出数据另存在一个或多个文件中;

根据数据服务是否在线:
热备:读写操作均可进行的状态下所做的备份;
温备:可读但不可写状态下进行的备份;
冷备:读写操作均不可进行的状态下所做的备份;

备份需要考虑因素:
锁定资源多长时间?
备份过程的时长?
备份时的服务器负载?
恢复过程的时长?

备份策略:
完全+差异
完全+增量

备份手段:物理、逻辑

备份什么?
数据
二进制日志、InnoDB的事务日志;
代码(存储过程、存储函数、触发器、事件调度器)
服务器的配置文件


备份工具:
mysqldump:mysql服务自带的备份工具;逻辑备份工具;
完全、部分备份;
InnoDB:热备;
MyISAM:温备;
cp/tar
lvm2:快照(请求一个全局锁),之后立即释放锁,达到几乎热备的效果;物理备份;
注意:不能仅备份数据文件;要同时备份事务日志;
前提:要求数据文件和事务日志位于同一个逻辑卷;
xtrabackup:
由Percona提供,开源工具,支持对InnoDB做热备,物理备份工具;
完全备份、部分备份;
完全备份、增量备份;
完全备份、差异备份;
mysqlhotcopy
select:
备份:SELECT cluase INTO OUTFILE 'FILENAME';
恢复:CREATE TABLE
导入:LOAD DATA

回顾:索引、日志、备份
索引:B+ TREE,有序数据;范围查询,左前缀;
EXPLAIN SELECT clause;

日志:二进制日志、慢查询日志、查询日志、错误日志、事务日志、中继日志;

备份:
完全/部分,热备/温备/冷备,完全/差异/增量,物理/逻辑

MySQL(05)

备份策略:
完全+差异+binlog
完全+增量+binlog

备份,多久一次?
数据变化量;
可用的备份存储空间;


mysqldump:
逻辑备份、完全备份、部分备份;
二次封装工具:
mydumper
phpMyAdmin

Usage:
mysqldump [OPTIONS] database [tables]
OR mysqldump [OPTIONS] --databases [OPTIONS] DB1 [DB2 DB3...]
OR mysqldump [OPTIONS] --all-databases [OPTIONS]

MyISAM存储引擎:支持温备,备份时要锁定表;
-x, --lock-all-tables:锁定所有库的所有表,读锁;
-l, --lock-tables:锁定指定库所有表;

InnoDB存储引擎:支持温备和热备;
--single-transaction:创建一个事务,基于此快照执行备份;

其它选项:
-R, --routines:存储过程和存储函数;
--triggers
-E, --events

--master-data[=#]
1:记录为CHANGE MASTER TO语句,此语句不被注释;
2:记录为CHANGE MASTER TO语句,此语句被注释;

--flush-logs:锁定表完成后,即进行日志刷新操作;

作业:备份脚本


基于lvm2的备份:

前提:数据目录位于逻辑卷,包含了数据文件和事务日志;

(1) 请求锁定所有表;
mysql> FLUSH TABLES WITH READ LOCK;

(2) 记录二进制文件事件位置;
mysql> FLUSH LOGS;
mysql> SHOW MASTER STATUS;

mysql -e 'SHOW MASTER STATUS;' >> /PATH/TO/SOME_POS_FILE

(3) 创建快照卷
lvcreate -L # -s -p r - SNAM-NAME /dev/VG-NAME/LV-NAME

(4) 释放锁
mysql> UNLOCK TABLES

(5) 挂载快照卷,并执行备份,备份完成后删除快照卷;

(6) 周期性备份二进制日志;

percona:
InnoDB --> XtraDB (mariadb)
Innobackup --> Xtrabackup

Xtrabackup:
MyISAM:温备,不支持增量备份;
InnoDB:热备,增量;

物理备份,速率快、可靠;备份完成后自动校验备份结果集是否可用;还原速度快;

Usage: [innobackupex [--defaults-file=#] --backup | innobackupex [--defaults-file=#] --prepare] [OPTIONS]

The innobackupex tool is a Perl script that acts as a wrapper for the xtrabackup C program.

完全备份:


完全+binlog(总结):
备份:innobackupex --user --password= --host= /PATH/TO/BACKUP_DIR
准备:innobackupex --apply-log /PATH/TO/BACKUP_DIR
恢复:innobackupex --copy-back
注意:--copy-back需要在mysqld主机本地进行,mysqld服务不能启动;
innodb_log_file_size可能要重新设定;

总结:完全+增量+binlog
备份:完全+增量+增量+...
完全+差异
准备:
innobackupex --apply-log --redo-only BASEDIR
innobackupex --apply-log --redo-only BASEDIR --incremental-dir=INCREMENTAL-DIR

恢复:
innobackupex --copy-back BASEDIR

备份单库:
--databases

注意:未尽的内容,请参考官方文档;

总结:
mysqldump+binlog
lvm2+cp/tar+binlog
xtrabackup(innodb)+binlog

博客作业:mysqldump和xtrabackup的使用;

回顾:mysqldump, xtrabackup
mysqldump:
--lock-all-tables
--lock-tables
--single-transaction
--databases, --all-databases
--routines, --trigger
xtrabackup:innobackupex
--user, --host, --password, --port, --socket
--apply-log
--redo-only
--copy-back



MySQL Replication:

Master/Slave
Master: write/read
Slaves: read

为什么?
冗余:promte(提升为主),异地灾备
人工
工具程序:MHA
负载均衡:转移一部分“读”请求;
支援安全的备份操作;
测试;
...

主/从架构:
异步复制:
半同步复制:
一主多从;
一从一主;
级联复制;
循环复制;
双主复制;

一从多主:
每个主服务器提供不同的数据库;


配置:
时间同步;
复制的开始位置:
从0开始;
从备份中恢复到从节点后启动的复制;
主从服务器mysqld程序版本不一致?

主服务器:
配置文件my.cnf
server_id=#
log_bin=log-bin

启动服务:
mysql> GRANT REPLICATION SLAVE,REPLICATION CLIENT ON *.* TO 'USERNAME'@'HOST' IDENTIFIED BY 'YOUR_PASSWORD';
mysql> FLUSH PRIVILEGES;

从服务器:
配置文件my.cnf
server_id=#
relay_log=relay-log

启动服务:
mysql> CHANGE MASTER TO MASTER_HOST='HOST',MASTER_USER='USERNAME',MASTER_PASSWORD='YOUR_PASSWORD',MASTER_LOG_FILE='BINLOG',MASTER_LOG_POS=#;
mysql> START SLAVE [IO_THREAD|SQL_THREAD];

mysql> SHOW SLAVE STATUS;

课外作业:基于SSL的复制的实现;


主主复制:
互为主从:两个节点各自都要开启binlog和relay log;
1、数据不一致;
2、自动增长id;
定义一个节点使用奇数id
auto_increment_offset=1
auto_increment_increment=2
另一个节点使用偶数id
auto_increment_offset=2
auto_increment_increment=2

配置:
1、server_id必须要使用不同值;
2、均启用binlog和relay log;
3、存在自动增长id的表,为了使得id不相冲突,需要定义其自动增长方式;

服务启动后执行如下两步:
4、都授权有复制权限的用户账号;
5、各把对方指定为主节点;

复制时应该注意的问题:
1、从服务设定为“只读”;
在从服务器启动read_only,但仅对非SUPER权限的用户有效;

阻止所有用户:
mysql> FLUSH TABLES WITH READ LOCK;

2、尽量确保复制时的事务安全
在master节点启用参数:
sync_binlog = ON

如果用到的是InnoDB存储引擎:
innodb_flush_logs_at_trx_commit=ON
innodb_support_xa=ON

3、从服务器意外中止时尽量避免自动启动复制线程


4、从节点:设置参数
sync_master_info=ON

sync_relay_log_info=ON

半同步复制
支持多种插件:/usr/lib64/mysql/plugins/

需要安装方可使用:
mysql> INSTALL PLUGIN plugin_name SONAME 'shared_library_name';

半同步复制:
semisync_master.so
semisync_slave.so

主节点:
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

MariaDB [mydb]> SHOW GLOBAL VARIABLES LIKE 'rpl_semi%';
+------------------------------------+-------+
| Variable_name | Value |
+------------------------------------+-------+
| rpl_semi_sync_master_enabled | OFF |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_no_slave | ON |
+------------------------------------+-------+

MariaDB [mydb]> SET GLOBAL rpl_semi_sync_master_enabled=ON;

从节点:
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

MariaDB [mydb]> SHOW GLOBAL VARIABLES LIKE 'rpl_semi%';
+---------------------------------+-------+
| Variable_name | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled | OFF |
| rpl_semi_sync_slave_trace_level | 32 |
+---------------------------------+-------+

MariaDB [mydb]> STOP SLAVE IO_THREAD;
MariaDB [mydb]> SHOW GLOBAL VARIABLES LIKE 'rpl_semi%';
MariaDB [mydb]> START SLAVE IO_THREAD;

判断方法:
主节点:
MariaDB [mydb]> SELECT @@global.rpl_semi_sync_master_clients;

复制过滤器:

仅复制有限一个或几个数据库相关的数据,而非所有;由复制过滤器进行;

有两种实现思路:

(1) 主服务器
主服务器仅向二进制日志中记录有关特定数据库相关的写操作;
问题:其它库的point-recovery将无从实现;

binlog_do_db=
binlog_ignore_db=

(2) 从服务器
从服务器的SQL THREAD仅重放关注的数据库或表相关的事件,并将其应用于本地;
问题:网络IO和磁盘IO;

Replicate_Do_DB=
Replicate_Ignore_DB=
Replicate_Do_Table=
Replicate_Ignore_Table=
Replicate_Wild_Do_Table=
Replicate_Wild_Ignore_Table=

作业:基于SSL复制的实现
前提:启用SSL功能;

复制的监控和维护:
(1) 清理日志:PURGE
PURGE { BINARY | MASTER } LOGS { TO 'log_name' | BEFORE datetime_expr };

(2) 复制监控
MASTER:
SHOW MASTER STATUS;
SHOW BINLOG EVENTS;
SHOW BINARY LOGS;

SLAVE:
SHOW SLAVE STATUS;

判断从服务器是否落后于主服务器:
Seconds_Behind_Master: 0

(3) 如何确定主从节点数据是否一致?
通过表的CHECKSUM检查;
使用percona-tools中pt-table-checksum;

(4) 主人数据不一致时的修复方法?
重新复制;

主从复制的读写分离:
mysql-proxy --> atlas
amoeba

AliSQL:

mysqlrouter:
语句透明路由服务;
MySQL Router 是轻量级 MySQL 中间件,提供应用与任意 MySQL 服务器后端的透明路由。MySQL Router 可以广泛应用在各种用案例中,比如通过高效路由数据库流量提供高可用性和可伸缩的 MySQL 服务器后端。Oracle 官方出品。

作业:简单复制、双主复制及半同步复制;









master/slave:
切分:
垂直切分:切库,把一个库中的多个表分组后放置于不同的物理服务器上;
水平切分:切表,分散其行至多个不同的table partitions中;
range, list, hash

sharding(切片):
数据库切分的框架:
cobar
gizzard
Hibernat Shards
HiveDB
...

qps: queries per second
tps: transactions per second

MHA:
manager: 10.1.0.6

master: 10.1.0.67
slave1: 10.1.0.68
slave2: 10.1.0.69


博客作业:
MHA,以及zabbix完成manager启动;

Java简要介绍

[TOC]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
Java:
Sun, Green Project, Oak, James Gosling;
1995:Java 1.0, Write once, Run Anywhere;
1996:JDK(Java Development Kit),包含类库、开发工具(javac)、JVM(SUN Classic VM)
JDK 1.0, Applet, AWT
1997:JDK 1.1
1998: JDK 1.2
Sun分拆Java技术为三个方向:
J2SE:Standard Edition
J2EE:Enterprise Edition
J2ME:Mobile Edition

代表性技术:EJB,java plugin, Swing, JIT(Just In Time,即时编译)

2000:JDK 1.3
HotSpot VM
2002:JDK 1.4

2006:Sun开源了Java技术,GPL,建立一个称为OpenJDK组织;
Java 2 SE, Java 2 EE, Java 2 ME

2011:JDK 1.7
2014:JDK 1.8
2016:JDK 1.9

Java代码的运行:
*.java(source code) --> javac --> *.class(bytecode)
jvm:class loader,加载程序的类文件,及程序的类文件依赖到的其它的类文件而后运行; 整个运行表现为一个jvm进程;
threads;

java技术体系:
Java编程语言
Java Class文件格式
Java API
Java VM
class loader
执行引擎

JVM运行时区域:
方法区:线程共享; 用于存储被JVM加载的class信息、常量、静态变量、方法等;
堆:是jvm所管理的内存中占用空间最大的一部分;也是GC管理的主要区域;存储对象;
Java栈:线程私有,存储 线程自己的局部变量;
PC寄存器:线程私有的内存空间,程序的指令指针;
本地方法栈:

安装JDK
了解当前的java环境:
~]# java -version

OpenJDK:
java-VERSION-openjdk:
The OpenJDK runtime environment.
java-VERSION-openjdk-headless:
The OpenJDK runtime environment without audio and video support.
java-VERSION-openjdk-devel:
The OpenJDK development tools.

CentOS 7:
VERSION:1.6.0, 1.7.0, 1.8.0
java-1.8.0-openjdk-devel
注意:多版本并存时,可使用 alternatives命令设定默认使用的版本;

Oracle JDK:
安装相应版本的rpm包;
jdk-VERSION-OS-ARCH.rpm
例如:jdk-1.8.0_25-linux-x64.rpm

注意:安装完成后,要配置JAVA_HOME环境变量,指向java的安装路径;
OpenJDK:
JAVA_HOME=/usr
Oracle JDK:
JAVA_HOME=/usr/java/jdk_VERSION



Java 2 EE:
CGI: Common Gateway Interface

Servlet:
类库;web app;
Servlet container, Servlet Engine

JSP: Java Server Page
<html>
<title>TITLE</title>
<body>
<h1>...</h1>
<%
... java code...
%>
</body>
</html>

.jsp -->jasper--> .java --> javac --> .class --> jvm

注意:基于jasper将静态输出的数据转为java代码进行输出;

JSP Container:
JSP + Servlet Container

Java Web Server:JWS
ASF:JServ

Tomcat 3.x
Tomcat 4.x
Catalina

http://tomcat.apache.org/

商业实现:
WebSphere, WebLogic, Oc4j, Glassfish, Geronimo, JOnAS, JBoss, ...
开源实现:
Tomcat, Jetty, Resin, ...

Tomcat: Java 2 EE技术体系的不完整实现;

JVM常用的分析工具:
jps:用来查看运行的所有jvm进程;
jinfo:查看进程的运行环境参数,主要是jvm命令行参数;
jstat:对jvm应用程序的资源和性能进行实时监控;
jstack:查看所有线程的运行状态;
jmap:查看jvm占用物理内存的状态;
jconsole:
jvisualvm:

官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/

jps:Java virutal machine Process Status tool,
jps [-q] [-mlvV] [<hostid>]
-q:静默模式;
-v:显示传递给jvm的命令行参数;
-m:输出传入main方法的参数;
-l:输出main类或jar完全限定名称;
-V:显示通过flag文件传递给jvm的参数;
[<hostid>]:主机id,默认为localhost;

jinfo:输出给定的java进程的所有配置信息;
jinfo [option] <pid>
-flags:to print VM flags
-sysprops:to print Java system properties
-flag <name>:to print the value of the named VM flag

jstack:查看指定的java进程的线程栈的相关信息;
jstack [-l] <pid>
jstack -F [-m] [-l] <pid>
-l:long listings,会显示额外的锁信息,因此,发生死锁时常用此选项;
-m:混合模式,既输出java堆栈信息,也输出C/C++堆栈信息;
-F:当使用“jstack -l PID"无响应,可以使用-F强制输出信息;

jstat:输出指定的java进程的统计信息
jstat -help|-options
jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

# jstat -options
-class:class loader
-compiler:JIT
-gc:gc
-gccapacity:统计堆中各代的容量
-gccause:
-gcmetacapacity
-gcnew:新生代
-gcnewcapacity
-gcold:老年代
-gcoldcapacity
-gcutil
-printcompilation

[<interval> [<count>]]
interval:时间间隔,单位是毫秒;
count:显示的次数;

-gc:
S0C :S0 总大小
S1C :S1 总大小
S0U :S0 已用大小
S1U :S1 已用大小
EC :Eden区总大小
EU :Eden区已用大小
OC :老年代总大小
OU :老年代已用大小
MC :Metaspace 总大小
MU :Metaspace 已用大小
CCSC :CompressedClassSpace总大小
CCSU :CompressedClassSpace已用大小
YGC :Young GC 次数
YGCT :Young GC 消耗总时间
FGC :FullGC 次数
FGCT :FullGC 消耗总时间
GCT :GC总消耗时间

参考文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html

jmap:Memory Map, 用于查看堆内存的使用状态;
jhat:Java Heap Analysis Tool
jmap [option] <pid>

查看堆空间的详细信息:
jmap -heap <pid>

查看堆内存中的对象的数目:
jmap -histo[:live] <pid>
live:只统计活动对象;

保存堆内存数据至文件中,而后使用jvisualvm或jhat进行查看:
jmap -dump:<dump-options> <pid>
dump-options:
live dump only live objects; if not specified, all objects in the heap are dumped.
format=b binary format
file=<file> dump heap to <file>

tomcat简要介绍

[TOC]

Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,Tomcat 实际上运行JSP 页面和Servlet.它还是一个Servlet和JSP容器.Tomcat: Java 2 EE技术体系的不完整实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
Tomcat:
使用java语言编写:

Tomcat的核心组件:server.xml
<Server>
<Service>
<connector/>
<connector/>
...
<Engine>
<Host>
<Context/>
<Context/>
...
</Host>
<Host>
...
</Host>
...
</Engine>
</Service>
</Server>

每一个组件都由一个Java“类”实现,这些组件大体可分为以下几个类型:
顶级组件:Server
服务类组件:Service
连接器组件connector:http, https, ajp
容器类:Engine, Host, Context
被嵌套类:valve, logger, realm, loader, manager, ...
集群类组件:listener, cluster, ...

安装Tomcat:
Base Repo:
tomcat, tomcat-lib, tomcat-admin-webapps, tomcat-webapps, tomcat-docs-webapp

Tomcat binary release:
# tar xf apache-tomcat-VERSION.tar.gz -C /usr/local/
# cd /usr/local
# ln -sv apache-tomcat-VERSION tomcat


/etc/profile.d/tomcat.sh
export CATALINA_BASE=/usr/local/tomcat
export PATH=$CATALINA_BASE/bin:$PATH

tomcat程序环境:

tomcat的目录结构
bin:脚本,及启动时用到的类;
conf:配置文件目录;
lib:库文件,Java类库,jar;
logs:日志文件目录;
temp:临时文件目录;
webapps:webapp的默认目录;
work:工作目录;

rpm包安装的程序环境:
配置文件目录:/etc/tomcat
主配置文件:server.xml
webapps存放位置:/var/lib/tomcat/webapps/
examples
manager
host-manager
docs
Unit File:tomcat.service
环境配置文件:/etc/sysconfig/tomcat

tomcat的配置文件:
server.xml:主配置文件;
web.xml:每个webapp只有“部署”后才能被访问,它的部署方式通常由web.xml进行定义,其存放位置为WEB-INF/目录中;此文件为所有的webapps提供默认配置;
context.xml:每个web都可以专用的配置文件,它通常由专用的配置文件context.xml来定义,其存放位置为WEB-INF/目录中;此文件为所有的webapps提供默认配置;
tomcat-users.xml:用户认证的账号和密码文件;
catalina.policy:当使用-security选项启动tomcat时,用于为tomcat设置安全策略;
catalina.properties:Java属性的定义文件,用于设定类加载器路径,以及一些与JVM调优相关参数;
logging.properties:日志系统相关的配置;

# catalina.sh --help
debug Start Catalina in a debugger
debug -security Debug Catalina with a security manager
jpda start Start Catalina under JPDA debugger
run Start Catalina in the current window
run -security Start in the current window with security manager
start Start Catalina in a separate window
start -security Start in a separate window with security manager
stop Stop Catalina, waiting up to 5 seconds for the process to end
stop n Stop Catalina, waiting up to n seconds for the process to end
stop -force Stop Catalina, wait up to 5 seconds and then use kill -KILL if still running
stop n -force Stop Catalina, wait up to n seconds and then use kill -KILL if still running
configtest Run a basic syntax check on server.xml - check exit code for result
version What version of tomcat are you running?

JSP WebAPP的组织结构:
/: webapps的根目录
index.jsp:主页;
WEB-INF/:当前webapp的私有资源路径;通常用于存储当前webapp的web.xml和context.xml配置文件;
META-INF/:类似于WEB-INF/;
classes/:类文件,当前webapp所提供的类;
lib/:类文件,当前webapp所提供的类,被打包为jar格式;

webapp归档格式:
.war:webapp
.jar:EJB的类打包文件;
.rar:资源适配器类打包文件;
.ear:企业级webapp;

部署(deploy)webapp的相关操作:
deploy:将webapp的源文件放置于目标目录(网页程序文件存放目录),配置tomcat服务器能够基于web.xml和context.xml文件中定义的路径来访问此webapp;将其特有的类和依赖的类通过class loader装载至JVM;
部署有两种方式:
自动部署:auto deploy
手动部署:
冷部署:把webapp复制到指定的位置,而后才启动tomcat;
热部署:在不停止tomcat的前提下进行部署;
部署工具:manager、ant脚本、tcd(tomcat client deployer)等;
undeploy:反部署,停止webapp,并从tomcat实例上卸载webapp;
start:启动处于停止状态的webapp;
stop:停止webapp,不再向用户提供服务;其类依然在jvm上;
redeploy:重新部署;

手动提供一测试类应用,并冷部署:
# mkidr -pv /usr/local/tomcat/webapps/test/{classes,lib,WEB-INF}
创建文件/usr/local/tomcat/webapps/test/index.jsp
<%@ page language="java" %>
<%@ page import="java.util.*" %>
<html>
<head>
<title>Test Page</title>
</head>
<body>
<% out.println("hello world");
%>
</body>
</html>

tomcat的两个管理应用:
manager
host-manager

tomcat的常用组件配置:

Server:代表tomcat instance,即表现出的一个java进程;监听在8005端口,只接收“SHUTDOWN”。各server监听的端口不能相同,因此,在同一物理主机启动多个实例时,需要修改其监听端口为不同的端口;

Service:用于实现将一个或多个connector组件关联至一个engine组件;

Connector组件:
负责接收请求,常见的有三类http/https/ajp;

进入tomcat的请求可分为两类:
(1) standalone : 请求来自于客户端浏览器;
(2) 由其它的web server反代:来自前端的反代服务器;
nginx --> http connector --> tomcat
httpd(proxy_http_module) --> http connector --> tomcat
httpd(proxy_ajp_module) --> ajp connector --> tomcat

属性:
port="8080"
protocol="HTTP/1.1"
connectionTimeout="20000"

address:监听的IP地址;默认为本机所有可用地址;
maxThreads:最大并发连接数,默认为150;
enableLookups:是否启用DNS查询功能;
acceptCount:等待队列的最大长度;
secure:
sslProtocol:

Engine组件:Servlet实例,即servlet引擎,其内部可以一个或多个host组件来定义站点; 通常需要通过defaultHost来定义默认的虚拟主机;

属性:
name=
defaultHost="localhost"
jvmRoute=

Host组件:位于engine内部用于接收请求并进行相应处理的主机或虚拟主机,示例:
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
</Host>

常用属性说明:
(1) appBase:此Host的webapps的默认存放目录,指存放非归档的web应用程序的目录或归档的WAR文件目录路径;可以使用基于$CATALINA_BASE变量所定义的路径的相对路径;
(2) autoDeploy:在Tomcat处于运行状态时,将某webapp放置于appBase所定义的目录中时,是否自动将其部署至tomcat;

示例:
<Host name="tc1.magedu.com" appBase="/appdata/webapps" unpackWARs="true" autoDeploy="true">
</Host>

# mkdir -pv /appdata/webapps
# mkdir -pv /appdata/webapps/ROOT/{lib,classes,WEB-INF}
提供一个测试页即可;

Context组件:
示例:
<Context path="/PATH" docBase="/PATH/TO/SOMEDIR" reloadable=""/>

Valve组件:
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t &quot;%r&quot; %s %b" />

Valve存在多种类型:
定义访问日志:org.apache.catalina.valves.AccessLogValve
定义访问控制:org.apache.catalina.valves.RemoteAddrValve

<Valve className="org.apache.catalina.valves.RemoteAddrValve" deny="172\.16\.100\.67"/>



LNMT:Linux Nginx MySQL Tomcat
Client (http) --> nginx (reverse proxy)(http) --> tomcat (http connector)

location / {
proxy_pass http://tc1.magedu.com:8080;
}

location ~* \.(jsp|do)$ {
proxy_pass http://tc1.magedu.com:8080;
}

LAMT:Linux Apache(httpd) MySQL Tomcat
httpd的代理模块:
proxy_module
proxy_http_module:适配http协议客户端;
proxy_ajp_module:适配ajp协议客户端;

Client (http) --> httpd (proxy_http_module)(http) --> tomcat (http connector)
Client (http) --> httpd (proxy_ajp_module)(ajp) --> tomcat (ajp connector)
Client (http) --> httpd (mod_jk)(ajp) --> tomcat (ajp connector)

proxy_http_module代理配置示例:
<VirtualHost *:80>
ServerName tc1.magedu.com
ProxyRequests Off
ProxyVia On
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / http://tc1.magedu.com:8080/
ProxyPassReverse / http://tc1.magedu.com:8080/
<Location />
Require all granted
</Location>
</VirtualHost>

proxy_ajp_module代理配置示例:
<VirtualHost *:80>
ServerName tc1.magedu.com
ProxyRequests Off
ProxyVia On
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / ajp://tc1.magedu.com:8009/
ProxyPassReverse / ajp://tc1.magedu.com:8009/
<Location />
Require all granted
</Location>
</VirtualHost>

课外实践:client --> nginx --> httpd --> tomcat
proxy_http_module)(http) --> tomcat (http connector)
Client (http) --> httpd (proxy_ajp_module)(ajp) --> tomcat (ajp connector)
Client (http) --> httpd (mod_jk)(ajp) --> tomcat (ajp connector)

proxy_http_module代理配置示例:
<VirtualHost *:80>
ServerName tc1.magedu.com
ProxyRequests Off
ProxyVia On
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / http://tc1.magedu.com:8080/
ProxyPassReverse / http://tc1.magedu.com:8080/
<Location />
Require all granted
</Location>
</VirtualHost>

proxy_ajp_module代理配置示例:
<VirtualHost *:80>
ServerName tc1.magedu.com
ProxyRequests Off
ProxyVia On
ProxyPreserveHost On
<Proxy *>
Require all granted
</Proxy>
ProxyPass / ajp://tc1.magedu.com:8009/
ProxyPassReverse / ajp://tc1.magedu.com:8009/
<Location />
Require all granted
</Location>
</VirtualHost>

课外实践:client --> nginx --> httpd --> tomcat