From 915c231124d72aeba0d5302785d1f513610053c8 Mon Sep 17 00:00:00 2001 From: colben Date: Sun, 14 Nov 2021 15:50:55 +0800 Subject: [PATCH] update --- content/post/awk.md | 56 +- content/post/bond.md | 24 +- content/post/centos6-oracle11g.md | 73 +-- content/post/ftp.md | 126 ++--- content/post/git-http.md | 114 ---- content/post/gnome.md | 178 +++---- content/post/kubeadm.md | 10 +- content/post/letsencrypt.md | 8 +- content/post/linux-io-random.md | 4 +- content/post/makefile.md | 170 +++--- content/post/mariadb-10.1.md | 123 ++--- content/post/mariadb-galera.md | 11 +- content/post/mariadb-replication.md | 196 +++---- content/post/mongodb.md | 36 +- content/post/mysql-galera.md | 126 ++--- content/post/mysql-group-replication.md | 130 ++--- content/post/mysql-replication.md | 329 ++++++------ content/post/mysql.md | 273 +++++----- content/post/mysql5.7-install.md | 61 +-- content/post/openvpn.md | 586 ++++++++++---------- content/post/oracle.md | 674 ++++++++++++------------ content/post/python-op.md | 61 ++- content/post/shell.md | 269 +++++----- content/post/systemd.md | 6 +- content/post/yum.md | 12 +- content/post/zabbix.md | 3 + content/post/zabbix3.10-install.md | 93 ++-- 27 files changed, 1862 insertions(+), 1890 deletions(-) delete mode 100644 content/post/git-http.md diff --git a/content/post/awk.md b/content/post/awk.md index 2ae113e..6ef4a91 100644 --- a/content/post/awk.md +++ b/content/post/awk.md @@ -34,7 +34,7 @@ RSTART | 被 match 匹配函数匹配的字符串位置 RLENGTH | 被 match 匹配函数匹配的字符串长度 # 函数 -### 常用内置函数 +## 常用内置函数 函数 | 说明 ---- | ---- int(x) | 返回 x 的整数部分 @@ -58,7 +58,7 @@ nextfile | 停止处理当前文件,开始处理下一个文件 system(shell-command) | 返回命令退出状态 exit n | 终止 awk,返回 n -### 自定义函数 +## 自定义函数 - 格式 ```awk function fun_name(arg1, arg2, ...){ @@ -68,15 +68,15 @@ exit n | 终止 awk,返回 n ``` # 判断语句 -```awk -if(条件){ - # 语句 -}else if(条件){ - # 语句 -}else{ - # 语句 -} -``` + ```awk + if(条件){ + # 语句 + }else if(条件){ + # 语句 + }else{ + # 语句 + } + ``` # 循环语句 - for @@ -104,23 +104,23 @@ if(条件){ - continue 退出本次循环,继续下一次循环 # 脚本 -```awk -#!/usr/bin/awk -f - -# 自定义的变量和函数 -# ... - -# 从这里开始执行 -BEGIN{ - # 语句 -} -条件{ - # 语句 -} -END{ - # 语句 -} -``` + ```awk + #!/usr/bin/awk -f + + # 自定义的变量和函数 + # ... + + # 从这里开始执行 + BEGIN{ + # 语句 + } + 条件{ + # 语句 + } + END{ + # 语句 + } + ``` # 其他说明 - 变量在使用时直接赋值即可,无需提前声明或定义 diff --git a/content/post/bond.md b/content/post/bond.md index eeac0ad..b63e1fb 100644 --- a/content/post/bond.md +++ b/content/post/bond.md @@ -8,9 +8,9 @@ categories: ["network"] --- # bond 概要 -### 什么是 bond +## 什么是 bond - 网卡bond是通过把多张网卡绑定为一个逻辑网卡,实现本地网卡的冗余,带宽扩容和负载均衡。在应用部署中是一种常用的技术。 -### bond的模式种类 +## bond的模式种类 - Mode=0(balance-rr) 表示负载分担round-robin,和交换机的聚合强制不协商的方式配合 - Mode=1(active-backup) 表示主备模式,只有一块网卡是active,另外一块是备的standby - **如果交换机配的是捆绑,将不能正常工作,因为交换机往两块网卡发包,有一半包是丢弃的** @@ -21,12 +21,12 @@ categories: ["network"] - Mode=6(balance-alb) 在5的tlb基础上增加了rlb # CentOS7 配置 bond -### 环境 +## 环境 - 操作系统 CentOS7.6,禁用 NetworkManager 服务 - 物理网卡 eth0, eth1 绑定到 bond0 - 物理网卡 eth2, eth3 绑定到 bond1 -### 网卡 eth0 配置 +## 网卡 eth0 配置 - 修改 /etc/sysconfig/network-scripts/ifcfg-eth0 ``` TYPE=Ethernet @@ -38,7 +38,7 @@ categories: ["network"] MASTER=bond0 ``` -### 网卡 eth1 配置 +## 网卡 eth1 配置 - 修改 /etc/sysconfig/network-scripts/ifcfg-eth1 ``` TYPE=Ethernet @@ -50,7 +50,7 @@ categories: ["network"] MASTER=bond0 ``` -### 网卡 eth2 配置 +## 网卡 eth2 配置 - 修改 /etc/sysconfig/network-scripts/ifcfg-eth2 ``` TYPE=Ethernet @@ -62,7 +62,7 @@ categories: ["network"] MASTER=bond1 ``` -### 网卡 eth3 配置 +## 网卡 eth3 配置 - 修改 /etc/sysconfig/network-scripts/ifcfg-eth3 ``` TYPE=Ethernet @@ -74,7 +74,7 @@ categories: ["network"] MASTER=bond1 ``` -### 增加网卡 bond0 配置 +## 增加网卡 bond0 配置 - 创建 /etc/sysconfig/network-scripts/ifcfg-bond0 ``` TYPE=Ethernet @@ -88,7 +88,7 @@ categories: ["network"] DNS1=114.114.114.114 ``` -### 增加网卡 bond1 配置 +## 增加网卡 bond1 配置 - 创建 /etc/sysconfig/network-scripts/ifcfg-bond1 ``` TYPE=Ethernet @@ -102,7 +102,7 @@ categories: ["network"] #DNS1=114.114.114.114 ``` -### 配置绑定模式 +## 配置绑定模式 - 创建 /etc/modprobe.d/bonding.conf,加入以下内容 ``` alias bond0 bonding @@ -110,13 +110,13 @@ categories: ["network"] options bonding miimon=100 mode=1 ``` -### 载入 bonding 模块,重启 network 服务 +## 载入 bonding 模块,重启 network 服务 ```bash modprob bonding systemctl restart network ``` -### 查看网卡绑定状态 +## 查看网卡绑定状态 ```bash cat /proc/net/bonding/bond0 cat /proc/net/bonding/bond1 diff --git a/content/post/centos6-oracle11g.md b/content/post/centos6-oracle11g.md index f7f5c29..2a4b3d4 100644 --- a/content/post/centos6-oracle11g.md +++ b/content/post/centos6-oracle11g.md @@ -7,19 +7,19 @@ categories: ["database"] --- # 安装依赖 -```bash -yum install binutils compat-libstdc++-33 compat-libstdc++-33.i686 \ -elfutils-libelf elfutils-libelf-devel gcc gcc-c++ glibc glibc.i686 \ -glibc-common glibc-devel glibc-devel.i686 glibc-headers ksh libaio \ -libaio.i686 libaio-devel libaio-devel.i686 libgcc libgcc.i686 libstdc++ \ -libstdc++.i686 libstdc++-devel make sysstat unixODBC unixODBC-devel -``` + ```bash + yum install binutils compat-libstdc++-33 compat-libstdc++-33.i686 \ + elfutils-libelf elfutils-libelf-devel gcc gcc-c++ glibc glibc.i686 \ + glibc-common glibc-devel glibc-devel.i686 glibc-headers ksh libaio \ + libaio.i686 libaio-devel libaio-devel.i686 libgcc libgcc.i686 libstdc++ \ + libstdc++.i686 libstdc++-devel make sysstat unixODBC unixODBC-devel + ``` # 创建用户和用户组 -```bash -groupadd dba oinstall -useradd -g oinstall -m oracle -``` + ```bash + groupadd dba oinstall + useradd -g oinstall -m oracle + ``` # 配置oracle用户环境变量 - 打开 oracle 用户的的默认shell配置文件 ~/.bashrc,在最后添加以下代码 @@ -32,16 +32,17 @@ useradd -g oinstall -m oracle #export NLS_LANG="SIMPLIFIED CHINESE_CHINA.AL32UTF8" #设置Oracle客户端中文utf8 export NLS_LANG=AMERICAN_AMERICA.ZHS16GBK #设置Oracle客户端中文gbk ``` + - 使设置立刻生效 ```bash source ~/.bashrc ``` # 创建oracle 11g软件安装路径 -```bash -mkdir /opt/oracle/app/product/11.2.0/db_home1 -p -chown oracle.oinstall /opt/oracle -R -``` + ```bash + mkdir /opt/oracle/app/product/11.2.0/db_home1 -p + chown oracle.oinstall /opt/oracle -R + ``` # 配置内核参数 - 编辑 /etc/sysctl.conf,在文件尾追加下面的参数设置 @@ -55,6 +56,7 @@ chown oracle.oinstall /opt/oracle -R net.core.wmem_max = 1048576 kernel.sem = 250 32000 100 128 ``` + - 使设置生效 ```bash sysctl -p @@ -84,39 +86,44 @@ chown oracle.oinstall /opt/oracle -R unzip linux.x64_11gR2_database_2of2.zip -d /home/oracle/ chown oracle.oinstall /home/oracle/database/ -R ``` + - **切换到 oracle 用户下**,运行安装程序 ```bash su - oracle cd database ./runInstaller ``` + - 若提示swap空间不足,自行百度解决! # 配置监听器数据库 - Oracle软件安装完后,执行 netca 命令配置监听器 -``` -netca -``` + ``` + netca + ``` + - 在图形界面中按提示配置监听器 - 执行 dbca 命令安装数据库 -```bash -dbca -``` + ```bash + dbca + ``` + - 在图形界面中按提示安装数据库就可以了。 # 测试运行 - 数据库安装完后监听器与数据库实例就已启动, - 停止和启动监听器 -```bash -lsnrctl stop -lsnrctl start -``` -- 停止和启动实例 -``` -sqlplus /nolog -SQL> connect / as sysdba; -SQL> shutdown -SQL> startup -#执行其它SQL语句测试数据库 -``` + ```bash + lsnrctl stop + lsnrctl start + ``` + +- 停止和启动实例 + ``` + sqlplus /nolog + SQL> connect / as sysdba; + SQL> shutdown + SQL> startup + # 执行其它SQL语句测试数据库 + ``` diff --git a/content/post/ftp.md b/content/post/ftp.md index 2b94c1b..2171558 100644 --- a/content/post/ftp.md +++ b/content/post/ftp.md @@ -12,9 +12,9 @@ categories: ["storage"] - 关闭 selinux # 安装 vsftpd 服务 -```bash -yum install vsftpd -``` + ```bash + yum install vsftpd + ``` # 常用客户端 - ftp @@ -54,69 +54,69 @@ yum install vsftpd ``` # 匿名用户配置 -```ini -# 控制是否允许匿名用户登入 -# 匿名用户使用的登陆名为 ftp 或 anonymous,口令为空 -# 匿名用户不能离开匿名用户家目录/var/ftp,且只能下载不能上传 -anonymous_enable=YES/NO(YES) - -# 匿名登入时,不会询问密码 -no_anon_password=YES/NO(NO) - -# 定义匿名登入的使用者名称,默认值为ftp -ftp_username=ftp - -# 是否允许登陆用户有写权限,属于全局设置 -write_enable=YES/NO(YES) - -# 使用匿名登入时,所登入的目录,默认值为/var/ftp -# 注意ftp目录不能是777的权限属性,即匿名用户的家目录不能有777的权限 -anon_root=/var/ftp - -# 是否允许匿名者有上传文件(非目录)的权限 -# 只有在write_enable=YES时,此项才有效 -# 匿名用户必须要有对上层目录的写入权 -anon_upload_enable=YES/NO(NO) - -# 是否允许匿名者下载可阅读的档案 -anon_world_readable_only=YES/NO(YES) - -# 是否允许匿名者有新增目录的权限 -# 只有在write_enable=YES时,此项才有效 -# 匿名用户必须要有对上层目录的写入权 -anon_mkdir_write_enable=YES/NO(NO) - -# 是否允许匿名入者拥有其他权限,譬如删除或者重命名 -# 如果anon_upload_enable=NO,则匿名用户不能上传文件,但可以删除或者重命名已经存在的文件 -# 如果anon_mkdir_write_enable=NO,则匿名用户不能上传或者新建文件夹,但可以删除或者重命名已经存在的目录 -anon_other_write_enable=YES/NO(NO) - -# 是否改变匿名用户上传文件(非目录)的属主 -chown_uploads=YES/NO(NO) - -# 设置匿名用户上传文件(非目录)的属主名 -# 建议不要设置为root -chown_username=username - -# 设置匿名登入者新增或上传档案时的 umask 值,默认值为 077 -anon_umask=077 -``` + ```ini + # 控制是否允许匿名用户登入 + # 匿名用户使用的登陆名为 ftp 或 anonymous,口令为空 + # 匿名用户不能离开匿名用户家目录/var/ftp,且只能下载不能上传 + anonymous_enable=YES/NO(YES) + + # 匿名登入时,不会询问密码 + no_anon_password=YES/NO(NO) + + # 定义匿名登入的使用者名称,默认值为ftp + ftp_username=ftp + + # 是否允许登陆用户有写权限,属于全局设置 + write_enable=YES/NO(YES) + + # 使用匿名登入时,所登入的目录,默认值为/var/ftp + # 注意ftp目录不能是777的权限属性,即匿名用户的家目录不能有777的权限 + anon_root=/var/ftp + + # 是否允许匿名者有上传文件(非目录)的权限 + # 只有在write_enable=YES时,此项才有效 + # 匿名用户必须要有对上层目录的写入权 + anon_upload_enable=YES/NO(NO) + + # 是否允许匿名者下载可阅读的档案 + anon_world_readable_only=YES/NO(YES) + + # 是否允许匿名者有新增目录的权限 + # 只有在write_enable=YES时,此项才有效 + # 匿名用户必须要有对上层目录的写入权 + anon_mkdir_write_enable=YES/NO(NO) + + # 是否允许匿名入者拥有其他权限,譬如删除或者重命名 + # 如果anon_upload_enable=NO,则匿名用户不能上传文件,但可以删除或者重命名已经存在的文件 + # 如果anon_mkdir_write_enable=NO,则匿名用户不能上传或者新建文件夹,但可以删除或者重命名已经存在的目录 + anon_other_write_enable=YES/NO(NO) + + # 是否改变匿名用户上传文件(非目录)的属主 + chown_uploads=YES/NO(NO) + + # 设置匿名用户上传文件(非目录)的属主名 + # 建议不要设置为root + chown_username=username + + # 设置匿名登入者新增或上传档案时的 umask 值,默认值为 077 + anon_umask=077 + ``` # 配置 ## 常用配置 -```ini -#允许匿名用户登陆 -anonymous_enable=YES -#允许本地用户登陆 -local_enable=YES -#允许登陆用户写可访问的目录或文件 -write_enable=YES -#指定用户登陆后直接进入系统的/mnt目录 -local_root=/mnt -chroot_list_enable=YES -#限定登陆用户可访问的目录只有自己的家目录或指定的local_root目录 -chroot_list_file=/etc/vsftpd/chroot_list -``` + ```ini + #允许匿名用户登陆 + anonymous_enable=YES + #允许本地用户登陆 + local_enable=YES + #允许登陆用户写可访问的目录或文件 + write_enable=YES + #指定用户登陆后直接进入系统的/mnt目录 + local_root=/mnt + chroot_list_enable=YES + #限定登陆用户可访问的目录只有自己的家目录或指定的local_root目录 + chroot_list_file=/etc/vsftpd/chroot_list + ``` ## 允许 vsftpd 匿名用户上传和下载 - 创建匿名用户登陆目录 diff --git a/content/post/git-http.md b/content/post/git-http.md deleted file mode 100644 index 7022d9d..0000000 --- a/content/post/git-http.md +++ /dev/null @@ -1,114 +0,0 @@ ---- -title: "搭建 Git http 服务" -date: 2019-10-30T17:35:56+08:00 -lastmod: 2019-10-30T17:35:56+08:00 -tags: ["git", "nginx", "http", "fcgiwrap", "spawn-fcgi"] -categories: ["dev/ops"] ---- - -# 环境 -- Centos/Redhat 6 -- 安装好 git - -# 安装 fcgiwrap -- 参考 https://github.com/gnosek/fcgiwrap -![](/img/150546_2jE9_2298475.png) - -# 安装 spawn-fcgi -- 参考 https://github.com/lighttpd/spawn-fcgi -![](/img/150655_jGEp_2298475.png) - -# 编辑 spawn-fcgi/sbin/fcgiwrap 开机启动脚本: -```bash -#! /bin/sh -DESC="fcgiwrap daemon" -DEAMON=/opt/spawn-fcgi/bin/spawn-fcgi -PIDFILE=/tmp/spawn-fcgi.pid -# fcgiwrap socket -FCGI_SOCKET=/tmp/fcgiwrap.socket -# fcgiwrap 可执行文件 -FCGI_PROGRAM=/opt/fcgiwrap/sbin/fcgiwrap -# fcgiwrap 执行的用户和用户组 -FCGI_USER=nobody -FCGI_GROUP=nobody -FCGI_EXTRA_OPTIONS="-M 0770" -OPTIONS="-u $FCGI_USER -g $FCGI_GROUP -s $FCGI_SOCKET -S $FCGI_EXTRA_OPTIONS -F 1 -P $PIDFILE -- $FCGI_PROGRAM" -do_start() { - $DEAMON $OPTIONS || echo -n "$DESC already running" -} -do_stop() { - kill -INT `cat $PIDFILE` || echo -n "$DESC not running" -} -case "$1" in - start) - echo -n "Starting $DESC: $NAME" - do_start - echo "." - ;; - stop) - echo -n "Stopping $DESC: $NAME" - do_stop - echo "." - ;; - restart) - echo -n "Restarting $DESC: $NAME" - do_stop - do_start - echo "." - ;; - *) - echo "Usage: $SCRIPTNAME {start|stop|restart}" >&2 - exit 3 - ;; -esac -exit 0 -``` - -# 启动 fcgiwrap -```bash -chmod 0755 /opt/spawn-fcgi/sbin/fcgiwrap -/opt/spawn-fcgi/sbin/fcgiwrap start -``` - -# 安装 nginx -- 参考 http://nginx.org/en/download.html,启动 nginx - -# 在 nginx 前端目录 html 下创建 git 仓库目录 nginx/html/git/ -```bash -mkdir /opt/nginx/html/git/ -chown nobody.nobody /opt/nginx/html/git/ -R -``` - -# 配置 nginx 的 git 服务 -```nginx -# 在 server section 中添加 git -location ~ /git(/.*) { - gzip off; - fastcgi_pass unix:/tmp/fcgiwrap.socket; - include fastcgi_params; - fastcgi_param SCRIPT_FILENAME /usr/libexec/git-core/git-http-backend; - fastcgi_param GIT_HTTP_EXPORT_ALL ""; - fastcgi_param GIT_PROJECT_ROOT /opt/nginx/html/git; - fastcgi_param PATH_INFO $1; - fastcgi_param REMOTE_USER $remote_user; - client_max_body_size 500m; -} -``` - -# 重新加载配置文件 -```bash -/opt/nginx/sbin/nginx -s reload -``` - -# 测试,在仓库目录下新建一个空repo -```bash -cd /opt/nginx/html/git/ -git init --bare test-repo -chown nobody.nobody test-repo -R -cd test-repo -git config http.reveivepack true -``` - -# 完成 -- 在另一台服务器中可以顺利的进行 clone、push 及 pull 等操作。 - diff --git a/content/post/gnome.md b/content/post/gnome.md index ed49bf1..a7c7ee3 100644 --- a/content/post/gnome.md +++ b/content/post/gnome.md @@ -7,103 +7,103 @@ categories: ["os"] --- # 常用设置 -```bash -# 关闭左上角热响应 -gsettings set org.gnome.desktop.interface enable-hot-corners false - -# 缩放系统字体 -gsettings set org.gnome.desktop.interface text-scaling-factor 1.5 - -# monospace 字体 -gsettings set org.gnome.desktop.interface monospace-font-name 'YaHei Consolas Hybrid 15' - -# gtk 主题 -gsettings set org.gnome.desktop.interface gtk-theme 'Vertex-Dark' - -# gnome-shell 主题 -gsettings set org.gnome.shell.extensions.user-theme name 'Vertex' - -# 图标主题 -gsettings set org.gnome.desktop.interface icon-theme 'Faenza' - -# 调整 gnome3 桌面(包括 gdm )放大级别 -# 0 系统自动缩放 -# n > 0 放大 n 倍 -gsettings set org.gnome.desktop.interface scaling-factor 1 - -# 启用用户扩展 -gsettings set org.gnome.shell disable-user-extensions false -gsettings set org.gnome.shell enabled-extensions "['user-theme@gnome-shell-extensions.gcampax.github.com', 'workspace-indicator@gnome-shell-extensions.gcampax.github.com', 'dash-to-panel@jderose9.github.com']" - -# 工作区 -gsettings set org.gnome.mutter dynamic-workspaces false -gsettings set org.gnome.desktop.wm.preferences num-workspaces 4 -gsettings set org.gnome.desktop.wm.preferences workspace-names "['乾坤', '巽震', '坎离', '艮兑']" - -# 窗口按钮 -gsettings set org.gnome.desktop.wm.preferences button-layout 'appmenu:minimize,maximize,close' -``` + ```bash + # 关闭左上角热响应 + gsettings set org.gnome.desktop.interface enable-hot-corners false + + # 缩放系统字体 + gsettings set org.gnome.desktop.interface text-scaling-factor 1.5 + + # monospace 字体 + gsettings set org.gnome.desktop.interface monospace-font-name 'YaHei Consolas Hybrid 15' + + # gtk 主题 + gsettings set org.gnome.desktop.interface gtk-theme 'Vertex-Dark' + + # gnome-shell 主题 + gsettings set org.gnome.shell.extensions.user-theme name 'Vertex' + + # 图标主题 + gsettings set org.gnome.desktop.interface icon-theme 'Faenza' + + # 调整 gnome3 桌面(包括 gdm )放大级别 + # 0 系统自动缩放 + # n > 0 放大 n 倍 + gsettings set org.gnome.desktop.interface scaling-factor 1 + + # 启用用户扩展 + gsettings set org.gnome.shell disable-user-extensions false + gsettings set org.gnome.shell enabled-extensions "['user-theme@gnome-shell-extensions.gcampax.github.com', 'workspace-indicator@gnome-shell-extensions.gcampax.github.com', 'dash-to-panel@jderose9.github.com']" + + # 工作区 + gsettings set org.gnome.mutter dynamic-workspaces false + gsettings set org.gnome.desktop.wm.preferences num-workspaces 4 + gsettings set org.gnome.desktop.wm.preferences workspace-names "['乾坤', '巽震', '坎离', '艮兑']" + + # 窗口按钮 + gsettings set org.gnome.desktop.wm.preferences button-layout 'appmenu:minimize,maximize,close' + ``` # 在 "活动" 中创建 "文件夹" -```bash -# 创建文件夹 -gsettings set org.gnome.desktop.app-folders folder-children "['Office','VirtualBox']" - -# 指定文件夹名字 -gsettings set org.gnome.desktop.app-folders.folder:/org/gnome/desktop/app-folders/folders/Office/ name "Office" -gsettings set org.gnome.desktop.app-folders.folder:/org/gnome/desktop/app-folders/folders/VirtualBox/ name "VirtualBox" - -# 指定文件夹包含的应用类别 -gsettings set org.gnome.desktop.app-folders.folder:/org/gnome/desktop/app-folders/folders/Office/ categories "['Office']" -gsettings set org.gnome.desktop.app-folders.folder:/org/gnome/desktop/app-folders/folders/VirtualBox/ categories "['Emulator']" -``` + ```bash + # 创建文件夹 + gsettings set org.gnome.desktop.app-folders folder-children "['Office','VirtualBox']" + + # 指定文件夹名字 + gsettings set org.gnome.desktop.app-folders.folder:/org/gnome/desktop/app-folders/folders/Office/ name "Office" + gsettings set org.gnome.desktop.app-folders.folder:/org/gnome/desktop/app-folders/folders/VirtualBox/ name "VirtualBox" + + # 指定文件夹包含的应用类别 + gsettings set org.gnome.desktop.app-folders.folder:/org/gnome/desktop/app-folders/folders/Office/ categories "['Office']" + gsettings set org.gnome.desktop.app-folders.folder:/org/gnome/desktop/app-folders/folders/VirtualBox/ categories "['Emulator']" + ``` # 快捷键 -```bash -gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-1 "[]" -gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-last "[]" -gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-up "['Up']" -gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-down "['Down']" -gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-left "['Left']" -gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-right "['Right']" - -gsettings set org.gnome.desktop.wm.keybindings switch-applications "[]" -gsettings set org.gnome.desktop.wm.keybindings switch-applications-backward "[]" -gsettings set org.gnome.desktop.wm.keybindings switch-windows "['Tab']" -gsettings set org.gnome.desktop.wm.keybindings switch-windows-backward "['Tab']" -gsettings set org.gnome.shell.window-switcher current-workspace-only true -gsettings set org.gnome.shell.window-switcher app-icon-mode both - -gsettings set org.gnome.desktop.wm.keybindings move-to-workspace-down "['Down']" -gsettings set org.gnome.desktop.wm.keybindings move-to-workspace-up "['Up']" -gsettings set org.gnome.desktop.wm.keybindings move-to-workspace-last "[]" - -gsettings set org.gnome.desktop.wm.keybindings move-to-monitor-up "[]" -gsettings set org.gnome.desktop.wm.keybindings move-to-monitor-right "[]" -gsettings set org.gnome.desktop.wm.keybindings move-to-monitor-left "[]" -gsettings set org.gnome.desktop.wm.keybindings move-to-monitor-down "[]" - -gsettings set org.gnome.desktop.wm.keybindings show-desktop "['d']" -gsettings set org.gnome.desktop.wm.keybindings toggle-maximized "['Up']" -gsettings set org.gnome.desktop.wm.keybindings minimize "['Down']" -gsettings set org.gnome.desktop.wm.keybindings maximize "[]" -``` + ```bash + gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-1 "[]" + gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-last "[]" + gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-up "['Up']" + gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-down "['Down']" + gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-left "['Left']" + gsettings set org.gnome.desktop.wm.keybindings switch-to-workspace-right "['Right']" + + gsettings set org.gnome.desktop.wm.keybindings switch-applications "[]" + gsettings set org.gnome.desktop.wm.keybindings switch-applications-backward "[]" + gsettings set org.gnome.desktop.wm.keybindings switch-windows "['Tab']" + gsettings set org.gnome.desktop.wm.keybindings switch-windows-backward "['Tab']" + gsettings set org.gnome.shell.window-switcher current-workspace-only true + gsettings set org.gnome.shell.window-switcher app-icon-mode both + + gsettings set org.gnome.desktop.wm.keybindings move-to-workspace-down "['Down']" + gsettings set org.gnome.desktop.wm.keybindings move-to-workspace-up "['Up']" + gsettings set org.gnome.desktop.wm.keybindings move-to-workspace-last "[]" + + gsettings set org.gnome.desktop.wm.keybindings move-to-monitor-up "[]" + gsettings set org.gnome.desktop.wm.keybindings move-to-monitor-right "[]" + gsettings set org.gnome.desktop.wm.keybindings move-to-monitor-left "[]" + gsettings set org.gnome.desktop.wm.keybindings move-to-monitor-down "[]" + + gsettings set org.gnome.desktop.wm.keybindings show-desktop "['d']" + gsettings set org.gnome.desktop.wm.keybindings toggle-maximized "['Up']" + gsettings set org.gnome.desktop.wm.keybindings minimize "['Down']" + gsettings set org.gnome.desktop.wm.keybindings maximize "[]" + ``` # 在 CentOS6 下安装 gnome 桌面 -```bash -yum groupinstall 'X Window System' -yum groupinstall Desktop -sed -i '/^id/id:5:initdefault:' /etc/inittab -``` + ```bash + yum groupinstall 'X Window System' + yum groupinstall Desktop + sed -i '/^id/id:5:initdefault:' /etc/inittab + ``` # 在 CentOS7 下安装 gnome3 桌面 -```bash -yum groupinstall 'X Window System' -yum groupinstall 'Gnome Desktop' -systemctl set-default graphical.target -systemctl enable gdm -# 创建一个可登陆的普通用户 -``` + ```bash + yum groupinstall 'X Window System' + yum groupinstall 'Gnome Desktop' + systemctl set-default graphical.target + systemctl enable gdm + # 创建一个可登陆的普通用户 + ``` # 在 gdm 中隐藏用户名 - 修改文件/etc/gdm/gdm.schemas,找到这一段: diff --git a/content/post/kubeadm.md b/content/post/kubeadm.md index 91c90c4..738d802 100644 --- a/content/post/kubeadm.md +++ b/content/post/kubeadm.md @@ -9,7 +9,7 @@ categories: ["container"] # kubeadm 安装 kubernetes -### 全部服务器配置 +## 全部服务器配置 IP 地址 | 主机名 | 操作系统 | 内存 | swap | 硬盘 | Internet | firewalld | selinux | /etc/hosts 增加行 --------- | -------- | -------- | ---- | ---- | ---- | -------- | --------- | ------- | ------------------ 10.0.2.80 | master80 | CentOS7 | 4GB | 关闭 | 20GB | 可达 | 关闭 | 关闭 | 127.0.0.1 master80 @@ -76,7 +76,7 @@ categories: ["container"] ``` -### 安装 docker +## 安装 docker - 各服务器安装 docker ```bash yum install docker @@ -106,7 +106,7 @@ categories: ["container"] ``` -### 安装 kubernetes +## 安装 kubernetes - 各服务器配置 kubernetes yum 源 ```bash cat < /etc/yum.repos.d/kubernetes.repo @@ -132,7 +132,7 @@ categories: ["container"] ``` -### 在 master80 服务器上安装 kubernetes master 服务组件 +## 在 master80 服务器上安装 kubernetes master 服务组件 - 初始化 kubeadm ```bash kubeadm init --pod-network-cidr=192.168.0.0/16 --token-ttl 0 @@ -148,7 +148,7 @@ categories: ["container"] ``` -### 加入其他节点 +## 加入其他节点 - 在 node81 和 node82 服务器上执行以下命令,即 master80 服务器 'kuberadm init' 命令的最后一行输出 ```bash kubeadm join --token : --discovery-token-ca-cert-hash sha256: diff --git a/content/post/letsencrypt.md b/content/post/letsencrypt.md index 26e990c..de56a47 100644 --- a/content/post/letsencrypt.md +++ b/content/post/letsencrypt.md @@ -7,7 +7,7 @@ tags: ["letsencrypt", "certbot", "ssl"] categories: ["web"] --- -## 安装 certbot +# 安装 certbot - 在 alpine linux 中安装 certbot ```bash apk add --no-cache certbot openssl @@ -18,7 +18,7 @@ categories: ["web"] certbot register --register-unsafely-without-email --agree-tos ``` -## 普通域名证书 +# 普通域名证书 - 申请 ssl 证书,有效期 90 天 ```bash certbot certonly -n -d x.x.com --standalone @@ -38,7 +38,7 @@ categories: ["web"] openssl dhparam -out /etc/letsencrypt/dhparam.pem 2048 ``` -## 通配域名证书 +# 通配域名证书 - 申请 ssl 证书,有效期 90 天 ```bash certbot certonly --manual -d '*.x.com' \ @@ -61,7 +61,7 @@ categories: ["web"] openssl dhparam -out /etc/letsencrypt/dhparam.pem 2048 ``` -## 使用证书 +# 使用证书 - nginx 配置 ssl ``` server { diff --git a/content/post/linux-io-random.md b/content/post/linux-io-random.md index 4ddb76b..88b50e2 100644 --- a/content/post/linux-io-random.md +++ b/content/post/linux-io-random.md @@ -20,7 +20,7 @@ categories: ["storage"] - iops: 每秒 I/O 的次数 # 同步写测试 -### 同步随机写 +## 同步随机写 - 使用strace工具查看系统调用 ```bash strace -f -tt -o /tmp/randwrite.log -D fio -name=randwrite -rw=randwrite \ @@ -82,7 +82,7 @@ categories: ["storage"] ... ``` -### 同步顺序写 +## 同步顺序写 - 测试顺序写 ```bash strace -f -tt -o /tmp/write.log -D fio -name=write -rw=write \ diff --git a/content/post/makefile.md b/content/post/makefile.md index fc8ca41..e545151 100644 --- a/content/post/makefile.md +++ b/content/post/makefile.md @@ -7,7 +7,7 @@ categories: ["dev/ops"] --- # Makefile 介绍 -### 介绍 +## 介绍 - make命令执行时,需要一个 Makefile 文件,以告诉make命令需要怎么样的去编译和链接程序。 - 首先,我们用一个示例来说明Makefile的书写规则。以便给大家一个感兴认识。这个示例来源于GNU的make使用手册,在这个示例中,我们的工程有8个C文件,和3个头文件,我们要写一个Makefile来告诉make命令如何编译和链接这几个文件。我们的规则是: - 如果这个工程没有编译过,那么我们的所有C文件都要编译并被链接。 @@ -15,7 +15,7 @@ categories: ["dev/ops"] - 如果这个工程的头文件被改变了,那么我们需要编译引用了这几个头文件的C文件,并链接目标程序。 - 只要我们的Makefile写得够好,所有的这一切,我们只用一个make命令就可以完成,make命令会自动智能地根据当前的文件修改的情况来确定哪些文件需要重编译,从而自己编译所需要的文件和链接目标程序。 -### Makefile的规则 +## Makefile的规则 - 在讲述这个Makefile之前,还是让我们先来粗略地看一看Makefile的规则。 ```makefile target... : prerequisites ... @@ -28,7 +28,7 @@ categories: ["dev/ops"] - command 也就是make需要执行的命令(任意的Shell命令)。 - 这是一个文件的依赖关系,也就是说,target这一个或多个的目标文件依赖于prerequisites中的文件,其生成规则定义在command中。说白一点就是说,prerequisites中如果有一个以上的文件比target文件要新的话,command所定义的命令就会被执行。这就是Makefile的规则。也就是Makefile中最核心的内容。 -### 一个示例 +## 一个示例 - 正如前面所说的,如果一个工程有3个头文件,和8个C文件,我们为了完成前面所述的那三个规则,我们的Makefile应该是下面的这个样子的。 ```makefile edit : main.o kbd.o command.o display.o \ @@ -61,7 +61,7 @@ categories: ["dev/ops"] - 在定义好依赖关系后,后续的那一行定义了如何生成目标文件的操作系统命令,一定要以一个Tab键作为开头。记住,make并不管命令是怎么工作的,他只管执行所定义的命令。make会比较targets文件和prerequisites文件的修改日期,如果prerequisites文件的日期要比targets文件的日期要新,或者target不存在的话,那么,make就会执行后续定义的命令。 - 这里要说明一点的是,clean不是一个文件,它只不过是一个动作名字,有点像C语言中的lable一样,其冒号后什么也没有,那么,make就不会自动去找文件的依赖性,也就不会自动执行其后所定义的命令。要执行其后的命令,就要在make命令后明显得指出这个lable的名字。这样的方法非常有用,我们可以在一个makefile中定义不用的编译或是和编译无关的命令,比如程序的打包,程序的备份,等等。 -### make 是如何工作的 +## make 是如何工作的 - 在默认的方式下,也就是我们只输入make命令。那么, - make会在当前目录下找名字叫"Makefile"或"makefile"的文件。 - 如果找到,它会找文件中的第一个目标文件(target),在上面的例子中,他会找到"edit"这个文件,并把这个文件作为最终的目标文件。 @@ -73,7 +73,7 @@ categories: ["dev/ops"] - 于是在我们编程中,如果这个工程已被编译过了,当我们修改了其中一个源文件,比如file.c,那么根据我们的依赖性,我们的目标file.o会被重编译(也就是在这个依性关系后面所定义的命令),于是file.o的文件也是最新的啦,于是file.o的文件修改时间要比edit要新,所以edit也会被重新链接了(详见edit目标文件后定义的命令)。 而如果我们改变了"command.h",那么,kdb.o、command.o和files.o都会被重编译,并且,edit会被重链接。 -### makefile中使用变量 +## makefile中使用变量 - 在上面的例子中,先让我们看看edit的规则: ```makefile edit : main.o kbd.o command.o display.o \ @@ -114,7 +114,7 @@ categories: ["dev/ops"] ``` - 如果有新的 .o 文件加入,我们只需简单地修改一下 objects 变量就可以了。 -### 让make自动推导 +## 让make自动推导 - GNU的make很强大,它可以自动推导文件以及文件依赖关系后面的命令,于是我们就没必要去在每一个[.o]文件后都写上类似的命令,因为,我们的make会自动识别,并自己推导命令。 - 只要make看到一个[.o]文件,它就会自动的把[.c]文件加在依赖关系中,如果make找到一个whatever.o,那么whatever.c,就会是whatever.o的依赖文件。并且 cc -c whatever.c 也会被推导出来,于是,我们的makefile再也不用写得这么复杂。我们的是新的makefile又出炉了。 ```makefile @@ -139,7 +139,7 @@ categories: ["dev/ops"] ``` - 这种方法,也就是make的"隐晦规则"。上面文件内容中,".PHONY"表示,clean是个伪目标文件。 -### 另类风格的makefile +## 另类风格的makefile - 既然我们的make可以自动推导命令,那么我看到那堆[.o]和[.h]的依赖就有点不爽,那么多的重复的[.h],能不能把其收拢起来,好吧,没有问题,这个对于make来说很容易,谁叫它提供了自动推导命令和文件的功能呢?来看看最新风格的makefile吧。 ```makefile objects = main.o kbd.o command.o display.o \ @@ -158,7 +158,7 @@ categories: ["dev/ops"] ``` - 这种风格,让我们的makefile变得很简单,但我们的文件依赖关系就显得有点凌乱了。鱼和熊掌不可兼得。还看你的喜好了 -### 清空目标文件的规则 +## 清空目标文件的规则 - 每个Makefile中都应该写一个清空目标文件(.o和执行文件)的规则,这不仅便于重编译,也很利于保持文件的清洁。这是一个"修养"(呵呵,还记得我的《编程修养》吗)。一般的风格都是: ```makefile clean: @@ -174,7 +174,7 @@ categories: ["dev/ops"] # Makefile 总述 -### Makefile里有什么? +## Makefile里有什么? - Makefile里主要包含了五个东西:显式规则、隐晦规则、变量定义、文件指示和注释。 - 显式规则。显式规则说明了,如何生成一个或多的的目标文件。这是由Makefile的书写者明显指出,要生成的文件,文件的依赖文件,生成的命令。 - 隐晦规则。由于我们的make有自动推导的功能,所以隐晦的规则可以让我们比较粗糙地简略地书写Makefile,这是由make所支持的。 @@ -183,11 +183,11 @@ categories: ["dev/ops"] - 注释。Makefile中只有行注释,和UNIX的Shell脚本一样,其注释是用"#"字符,这个就像C/C++中的"//"一样。如果你要在你的Makefile中使用"#"字符,可以用反斜框进行转义,如:"\#"。 - 最后,还值得一提的是,在Makefile中的命令,必须要以[Tab]键开始。 -### Makefile的文件名 +## Makefile的文件名 - 默认的情况下,make命令会在当前目录下按顺序找寻文件名为"GNUmakefile"、"makefile"、"Makefile"的文件,找到了解释这个文件。在这三个文件名中,最好使用"Makefile"这个文件名,因为,这个文件名第一个字符为大写,这样有一种显目的感觉。最好不要用"GNUmakefile",这个文件是GNU的make识别的。有另外一些make只对全小写的"makefile"文件名敏感,但是基本上来说,大多数的make都支持"makefile"和"Makefile"这两种默认文件名。 - 当然,你可以使用别的文件名来书写Makefile,比如:"Make.Linux","Make.Solaris","Make.AIX"等,如果要指定特定的Makefile,你可以使用make的"-f"和"--file"参数,如:make -f Make.Linux或make --file Make.AIX。 -### 引用其它的Makefile +## 引用其它的Makefile - 在Makefile使用include关键字可以把别的Makefile包含进来,这很像C语言的#include,被包含的文件会原模原样的放在当前文件的包含位置。include的语法是: ```makefile includefilename可以是当前操作系统Shell的文件模式(可以保含路径和通配符) @@ -209,11 +209,11 @@ categories: ["dev/ops"] ``` - 其表示,无论include过程中出现什么错误,都不要报错继续执行。和其它版本make兼容的相关命令是sinclude,其作用和这一个是一样的。 -### 环境变量 MAKEFILES +## 环境变量 MAKEFILES - 如果你的当前环境中定义了环境变量MAKEFILES,那么,make会把这个变量中的值做一个类似于include的动作。这个变量中的值是其它的Makefile,用空格分隔。只是,它和include不同的是,从这个环境变中引入的Makefile的"目标"不会起作用,如果环境变量中定义的文件发现错误,make也会不理。 - 但是在这里我还是建议不要使用这个环境变量,因为只要这个变量一被定义,那么当你使用make时,所有的Makefile都会受到它的影响,这绝不是你想看到的。在这里提这个事,只是为了告诉大家,也许有时候你的Makefile出现了怪事,那么你可以看看当前环境中有没有定义这个变量。 -### make的工作方式 +## make的工作方式 - GNU的make工作时的执行步骤入下 - 读入所有的Makefile。 - 读入被include的其它Makefile。 @@ -226,12 +226,12 @@ categories: ["dev/ops"] - 当然,这个工作方式你不一定要清楚,但是知道这个方式你也会对make更为熟悉。有了这个基础,后续部分也就容易看懂了。 # Makefile书写规则 -### 规则 +## 规则 - 规则包含两个部分,一个是依赖关系,一个是生成目标的方法。 - 在Makefile中,规则的顺序是很重要的,因为,Makefile中只应该有一个最终目标,其它的目标都是被这个目标所连带出来的,所以一定要让make知道你的最终目标是什么。一般来说,定义在Makefile中的目标可能会有很多,但是第一条规则中的目标将被确立为最终的目标。如果第一条规则中的目标有很多个,那么,第一个目标会成为最终的目标。make所完成的也就是这个目标。 - 好了,还是让我们来看一看如何书写规则。 -### 规则举例 +## 规则举例 ```makefile foo.o: foo.c defs.h # foo模块 cc -c -g foo.c @@ -240,7 +240,7 @@ categories: ["dev/ops"] - 文件的依赖关系,foo.o依赖于foo.c和defs.h的文件,如果foo.c和defs.h的文件日期要比foo.o文件日期要新,或是foo.o不存在,那么依赖关系发生。 - 如果生成(或更新)foo.o文件。也就是那个cc命令,其说明了,如何生成foo.o这个文件。(当然foo.c文件include了defs.h文件) -### 规则的语法 +## 规则的语法 ```makefile targets : prerequisites command @@ -258,7 +258,7 @@ categories: ["dev/ops"] - 如果命令太长,你可以使用反斜框(‘\’)作为换行符。make对一行上有多少个字符没有限制。规则告诉make两件事,文件的依赖关系和如何成成目标文件。 - 一般来说,make会以UNIX的标准Shell,也就是/bin/sh来执行命令。 -### 在规则中使用通配符 +## 在规则中使用通配符 - 如果我们想定义一系列比较类似的文件,我们很自然地就想起使用通配符。make支持三各通配符:"\*","?"和"[...]"。这是和Unix的B-Shell是相同的。 - "~" 波浪号("~")字符在文件名中也有比较特殊的用途。如果是"~/test",这就表示当前用户的$HOME目录下的test目录。而"~hchen/test"则表示用户hchen的宿主目录下的test目录。(这些都是Unix下的小知识了,make也支持)而在Windows或是MS-DOS下,用户没有宿主目录,那么波浪号所指的目录则根据环境变量"HOME"而定。 - "\*" 通配符代替了你一系列的文件,如"\*.c"表示所以后缀为c的文件。一个需要我们注意的是,如果我们的文件名中有通配符,如:"\*",那么可以用转义字符"\",如"\*"来表示真实的"\*"字符,而不是任意长度的字符串。 @@ -283,7 +283,7 @@ categories: ["dev/ops"] ``` - 这种用法由关键字"wildcard"指出,关于Makefile的关键字,我们将在后面讨论。 -### 文件搜寻 +## 文件搜寻 - 在一些大的工程中,有大量的源文件,我们通常的做法是把这许多的源文件分类,并存放在不同的目录中。所以,当make需要去找寻文件的依赖关系时,你可以在文件前加上路径,但最好的方法是把一个路径告诉make,让make在自动去找。 - Makefile文件中的特殊变量"VPATH"就是完成这个功能的,如果没有指明这个变量,make只会在当前的目录中去找寻依赖文件和目标文件。如果定义了这个变量,那么,make就会在当当前目录找不到的情况下,到所指定的目录中去找寻文件了。 ```makefile @@ -312,7 +312,7 @@ categories: ["dev/ops"] ``` - 而上面的语句则表示".c"结尾的文件,先在"foo"目录,然后是"bar"目录,最后才是"blish"目录。 -### 伪目标 +## 伪目标 - 最早先的一个例子中,我们提到过一个"clean"的目标,这是一个"伪目标", ```makefile clean: @@ -360,7 +360,7 @@ categories: ["dev/ops"] ``` - "makeclean"将清除所有要被清除的文件。"cleanobj"和"cleandiff"这两个伪目标有点像"子程序"的意思。我们可以输入"makecleanall"和"make cleanobj"和"makecleandiff"命令来达到清除不同种类文件的目的 -### 多目标 +## 多目标 - Makefile的规则中的目标可以不止一个,其支持多目标,有可能我们的多个目标同时依赖于一个文件,并且其生成的命令大体类似。于是我们就能把其合并起来。当然,多个目标的生成规则的执行命令是同一个,这可能会可我们带来麻烦,不过好在我们的可以使用一个自动化变量"$@"(关于自动化变量,将在后面讲述),这个变量表示着目前规则中所有的目标的集合,这样说可能很抽象,还是看一个例子吧。 ```makefile bigoutput littleoutput : text.g @@ -375,7 +375,7 @@ categories: ["dev/ops"] ``` - 其中,-$(subst output,,$@)中的"$"表示执行一个Makefile的函数,函数名为subst,后面的为参数。关于函数,将在后面讲述。这里的这个函数是截取字符串的意思,"$@"表示目标的集合,就像一个数组,"$@"依次取出目标,并执于命令。 -### 静态模式 +## 静态模式 - 静态模式可以更加容易地定义多目标的规则,可以让我们的规则变得更加的有弹性和灵活。我们还是先来看一下语法: ```makefile : : @@ -414,7 +414,7 @@ categories: ["dev/ops"] ``` - $(filter%.o,$(files))表示调用Makefile的filter函数,过滤"$filter"集,只要其中模式为"%.o"的内容。其的它内容,我就不用多说了吧。这个例字展示了Makefile中更大的弹性。 -### 自动生成依赖性 +## 自动生成依赖性 - 在Makefile中,我们的依赖关系可能会需要包含一系列的头文件,比如,如果我们的main.c中有一句"#include "defs.h"",那么我们的依赖关系应该是: ```makefile main.o : main.c defs.h @@ -477,11 +477,11 @@ categories: ["dev/ops"] - 上述语句中的"$(sources:.c=.d)"中的".c=.d"的意思是做一个替换,把变量$(sources)所有[.c]的字串都替换成[.d],关于这个"替换"的内容,在后面我会有更为详细的讲述。当然,你得注意次序,因为include是按次来载入文件,最先载入的[.d]文件中的目标会成为默认目标 # Makefile 书写命令 -### 命令 +## 命令 - 每条规则中的命令和操作系统Shell的命令行是一致的。make会一按顺序一条一条的执行命令,每条命令的开头必须以[Tab]键开头,除非,命令是紧跟在依赖规则后面的分号后的。在命令行之间中的空格或是空行会被忽略,但是如果该空格或空行是以Tab键开头的,那么make会认为其是一个空命令。 - 我们在UNIX下可能会使用不同的Shell,但是make的命令默认是被"/bin/sh" UNIX的标准Shell解释执行的。除非你特别指定一个其它的Shell。Makefile中,"#"是注释符,很像C/C++中的"//",其后的本行字符都被注释。 -### 显示命令 +## 显示命令 - 通常,make会把其要执行的命令行在命令执行前输出到屏幕上。当我们用"@"字符在命令行前,那么,这个命令将不被make显示出来,最具代表性的例子是,我们用这个功能来像屏幕显示一些信息。如: ```makefile @echo 正在编译XXX模块...... @@ -494,7 +494,7 @@ categories: ["dev/ops"] - 如果make执行时,带入make参数"-n"或"--just-print",那么其只是显示命令,但不会执行命令,这个功能很有利于我们调试我们的Makefile,看看我们书写的命令是执行起来是什么样子的或是什么顺序的。 - make参数"-s"或"--slient"则是全面禁止命令的显示。 -### 命令执行 +## 命令执行 - 当依赖目标新于目标时,也就是当规则的目标需要被更新时,make会一条一条的执行其后的命令。需要注意的是,如果你要让上一条命令的结果应用在下一条命令时,你应该使用分号分隔这两条命令。比如你的第一条命令是cd命令,你希望第二条命令得在cd之后的基础上运行,那么你就不能把这两条命令写在两行上,而应该把这两条命令写在一行上,用分号分隔。如: ```makefile # 示例一: @@ -509,7 +509,7 @@ categories: ["dev/ops"] - 当我们执行"make exec"时,第一个例子中的cd没有作用,pwd会打印出当前的Makefile目录,而第二个例子中,cd就起作用了,pwd会打印出"/home/hchen"。 - make 一般是使用环境变量SHELL中所定义的系统Shell来执行命令,默认情况下使用UNIX的标准Shell /bin/sh来执行命令。但在MS-DOS下有点特殊,因为MS-DOS下没有SHELL环境变量,当然你也可以指定。如果你指定了UNIX风格的目录形式,首先,make会在SHELL所指定的路径中找寻命令解释器,如果找不到,其会在当前盘符中的当前目录中寻找,如果再找不到,其会在PATH环境变量中所定义的所有路径中寻找。MS-DOS中,如果你定义的命令解释器没有找到,其会给你的命令解释器加上诸如".exe"、".com"、".bat"、".sh"等后缀。 -### 命令出错 +## 命令出错 - 每当命令运行完后,make会检测每个命令的返回码,如果命令返回成功,那么make会执行下一条命令,当规则中所有的命令成功返回后,这个规则就算是成功完成了。如果一个规则中的某个命令出错了(命令退出码非零),那么make就会终止执行当前规则,这将有可能终止所有规则的执行。 - 有些时候,命令的出错并不表示就是错误的。例如mkdir命令,我们一定需要建立一个目录,如果目录不存在,那么mkdir就成功执行,万事大吉,如果目录存在,那么就出错了。我们之所以使用mkdir的意思就是一定要有这样的一个目录,于是我们就不希望mkdir出错而终止规则的运行。 - 为了做到这一点,忽略命令的出错,我们可以在Makefile的命令行前加一个减号"-"(在Tab键之后),标记为不管命令出不出错都认为是成功的。如: @@ -520,7 +520,7 @@ categories: ["dev/ops"] - 还有一个全局的办法是,给make加上"-i"或是"--ignore-errors"参数,那么,Makefile中所有命令都会忽略错误。而如果一个规则是以".IGNORE"作为目标的,那么这个规则中的所有命令将会忽略错误。这些是不同级别的防止命令出错的方法,你可以根据你的不同喜欢设置。 - 还有一个要提一下的make的参数的是"-k"或是"--keep-going",这个参数的意思是,如果某规则中的命令出错了,那么就终目该规则的执行,但继续执行其它规则。 -### 嵌套执行make +## 嵌套执行make - 在一些大的工程中,我们会把我们不同模块或是不同功能的源文件放在不同的目录中,我们可以在每个目录中都书写一个该目录的Makefile,这有利于让我们的Makefile变得更加地简洁,而不至于把所有的东西全部写在一个Makefile中,这样会很难维护我们的Makefile,这个技术对于我们模块编译和分段编译有着非常大的好处。 - 例如,我们有一个子目录叫subdir,这个目录下有个Makefile文件,来指明了这个目录下文件的编译规则。那么我们总控的Makefile可以这样书写: ```makefile @@ -579,7 +579,7 @@ categories: ["dev/ops"] ``` - 当你使用"-C"参数来指定make下层Makefile时,"-w"会被自动打开的。如果参数中有"-s"("--slient")或是"--no-print-directory",那么,"-w"总是失效的。 -### 定义命令包 +## 定义命令包 - 如果Makefile中出现一些相同命令序列,那么我们可以为这些相同的命令序列定义一个变量。定义这种命令序列的语法以"define"开始,以"endef"结束,如: ```makefile define run-yacc @@ -596,7 +596,7 @@ categories: ["dev/ops"] - 在 Makefile中的定义的变量,就像是C/C++语言中的宏一样,他代表了一个文本字串,在Makefile中执行的时候其会自动原模原样地展开在所使用的地方。其与C/C++所不同的是,你可以在Makefile中改变其值。在Makefile中,变量可以使用在"目标","依赖目标","命令"或是 Makefile的其它部分中。变量的命名字可以包含字符、数字,下划线(可以是数字开头),但不应该含有":"、"#"、"="或是空字符(空格、回车等)。变量是大小写敏感的,"foo"、"Foo"和"FOO"是三个不同的变量名。传统的Makefile的变量名是全大写的命名方式,但我推荐使用大小写搭配的变量名,如:MakeFlags。这样可以避免和系统的变量冲突,而发生意外的事情。有一些变量是很奇怪字串,如"$<"、"$@"等,这些是自动化变量。 # 变量 -### 变量的基础 +## 变量的基础 - 变量在声明时需要给予初值,而在使用时,需要给在变量名前加上"$"符号,但最好用小括号"()"或是大括号"{}"把变量给包括起来。如果你要使用真实的"$"字符,那么你需要用"$$"来表示。变量可以使用在许多地方,如规则中的"目标"、"依赖"、"命令"以及新的变量中。 - 先看一个例子: ```makefile @@ -619,7 +619,7 @@ categories: ["dev/ops"] ``` - 当然,千万不要在你的Makefile中这样干,这里只是举个例子来表明Makefile中的变量在使用处展开的真实样子。可见其就是一个"替代"的原理。另外,给变量加上括号完全是为了更加安全地使用这个变量,在上面的例子中,如果你不想给变量加上括号,那也可以,但我还是强烈建议你给变量加上括号。 -### 变量中的变量 +## 变量中的变量 - 在定义变量的值时,我们可以使用其它变量来构造变量的值,在Makefile中有两种方式来在用变量定义变量的值。 - 先看第一种方式,也就是简单的使用"="号,在"="左侧是变量,右侧是变量的值,右侧变量的值可以定义在文件的任何一处,也就是说,右侧中的变量不一定非要是已定义好 的值,其也可以使用后面定义的值。如: @@ -694,7 +694,7 @@ categories: ["dev/ops"] endif ``` -### 变量高级用法 +## 变量高级用法 - 这里介绍两种变量的高级使用方法,第一种是变量值的替换。 - 我们可以替换变量中的共有的部分,其格式是"$(var:a=b)"或是"${var:a=b}",其意思是,把变量"var"中所有以"a"字串"结尾"的"a"替换成"b"字串。这里的"结尾"意思是"空格"或是"结束符"。 - 还是看一个示例吧: @@ -779,7 +779,7 @@ categories: ["dev/ops"] ``` - 这个例子中定义了三个变量:"dir","foo_sources"和"foo_print"。 -### 追加变量值 +## 追加变量值 - 我们可以使用"+="操作符给变量追加值,如: ```makefile objects = main.o foo.o bar.o utils.o @@ -809,7 +809,7 @@ categories: ["dev/ops"] ``` - 由于前次的赋值符是"=",所以"+="也会以"="来做为赋值,那么岂不会发生变量的递补归定义,这是很不好的,所以make会自动为我们解决这个问题,我们不必担心这个问题。 -### override 指示符 +## override 指示符 - 如果有变量是通常make的命令行参数设置的,那么Makefile中对这个变量的赋值会被忽略。如果你想在Makefile中设置这类参数的值,那么,你可以使用"override"指示符。其语法是: ```makefile override = @@ -826,7 +826,7 @@ categories: ["dev/ops"] endef ``` -### 多行变量 +## 多行变量 - 还有一种设置变量值的方法是使用define关键字。使用define关键字设置变量的值可以有换行,这有利于定义一系列的命令(前面我们讲过"命令包"的技术就是利用这个关键字)。 - define 指示符后面跟的是变量的名字,而重起一行定义变量的值,定义是以endef关键字结束。其工作方式和"="操作符一样。变量的值可以包含函数、命令、文字,或是其它变量。因为命令需要以[Tab]键开头,所以如果你用define定义的命令变量中没有以[Tab]键开头,那么make就不会把其认为是命令。 - 下面的这个示例展示了define的用法: @@ -837,12 +837,12 @@ categories: ["dev/ops"] endef ``` -### 环境变量 +## 环境变量 - make 运行时的系统环境变量可以在make开始运行时被载入到Makefile文件中,但是如果Makefile中已定义了这个变量,或是这个变量由make命令行带入,那么系统的环境变量的值将被覆盖。(如果make指定了"-e"参数,那么,系统环境变量将覆盖Makefile中定义的变量) - 因此,如果我们在环境变量中设置了"CFLAGS"环境变量,那么我们就可以在所有的Makefile中使用这个变量了。这对于我们使用统一的编译参数有比较大的好处。如果Makefile中定义了CFLAGS,那么则会使用Makefile中的这个变量,如果没有定义则使用系统环境变量的值,一个共性和个性的统一,很像"全局变量"和"局部变量"的特性。 当make嵌套调用时(参见前面的"嵌套调用"章节),上层Makefile中定义的变量会以系统环境变量的方式传递到下层的Makefile中。当然,默认情况下,只有通过命令行设置的变量会被传递。而定义在文件中的变量,如果要向下层 Makefile传递,则需要使用exprot关键字来声明。(参见前面章节) - 当然,我并不推荐把许多的变量都定义在系统环境中,这样,在我们执行不用的Makefile时,拥有的是同一套系统变量,这可能会带来更多的麻烦。 -### 目标变量 +## 目标变量 - 前面我们所讲的在Makefile中定义的变量都是"全局变量",在整个文件,我们都可以访问这些变量。当然,"自动化变量"除外,如"$<"等这种类量的自动化变量就属于"规则型变量",这种变量的值依赖于规则的目标和依赖目标的定义。 - 当然,我样同样可以为某个目标设置局部变量,这种变量被称为"Target-specific Variable",它可以和"全局变量"同名,因为它的作用范围只在这条规则以及连带规则中,所以其值也只在作用范围内有效。而不会影响规则链以外的全局变量的值。 - 其语法是: @@ -867,7 +867,7 @@ categories: ["dev/ops"] ``` - 在这个示例中,不管全局的$(CFLAGS)的值是什么,在prog目标,以及其所引发的所有规则中(prog.o foo.o bar.o的规则),$(CFLAGS)的值都是"-g" -### 模式变量 +## 模式变量 - 在GNU的make中,还支持模式变量(Pattern-specific Variable),通过上面的目标变量中,我们知道,变量可以定义在某个目标上。模式变量的好处就是,我们可以给定一种"模式",可以把变量定义在符合这种模式的所有目标上。 - 我们知道,make的"模式"一般是至少含有一个"%"的,所以,我们可以以如下方式给所有以[.o]结尾的目标定义目标变量: ```makefile @@ -881,7 +881,7 @@ categories: ["dev/ops"] - override同样是针对于系统环境传入的变量,或是make命令行指定的变量。 # 条件判断 -### 一个例子 +## 一个例子 - 下面的例子,判断$(CC)变量是否"gcc",如果是的话,则使用GNU函数编译目标。 ```makefile libs_for_gcc = -lgnu @@ -921,7 +921,7 @@ categories: ["dev/ops"] $(CC) -o foo $(objects) $(libs) ``` -### 语法 +## 语法 - 条件表达式的语法为: ```makefile @@ -995,7 +995,7 @@ categories: ["dev/ops"] # 函数 -### 函数的调用语法 +## 函数的调用语法 - 函数调用,很像变量的使用,也是以"$"来标识的,其语法如下: ```makefile $( ) @@ -1015,8 +1015,8 @@ categories: ["dev/ops"] ``` - 在这个示例中,$(comma)的值是一个逗号。$(space)使用了$(empty)定义了一个空格,$(foo)的值是"a b c",$(bar)的定义用,调用了函数"subst",这是一个替换函数,这个函数有三个参数,第一个参数是被替换字串,第二个参数是替换字串,第三个参数是替换操作作用的字串。这个函数也就是把$(foo)中的空格替换成逗号,所以$(bar)的值是"a,b,c"。 -### 字符串处理函数 -##### 字符串替换函数 subst +## 字符串处理函数 +### 字符串替换函数 subst - 功能:把字串\中的字符串替换成。 - 返回:函数返回被替换过后的字符串。 - 语法: @@ -1029,7 +1029,7 @@ categories: ["dev/ops"] ``` - 把"feet on the street"中的"ee"替换成"EE",返回结果是"fEEt on the strEEt"。 -##### 模式字符串替换函数 patsubst +### 模式字符串替换函数 patsubst - 功能:查找\中的单词(单词以"空格"、"Tab"或"回车""换行"分隔)是否符合模式,如果匹配的话,则以替换。这里,可以包括通配符"%",表示任意长度的字串。如果中也包含"%",那么,中的这个"%"将是中的那个"%"所代表的字串。(可以用"\"来转义,以"\%"来表示真实含义的"%"字符)返回:函数返回被替换过后的字符串。 - 语法: ```makefile @@ -1058,7 +1058,7 @@ categories: ["dev/ops"] ``` - 例如有:objects = foo.o bar.o baz.o,那么,"$(objects:.o=.c)"和"$(patsubst %.o,%.c,$(objects))"是一样的。 -##### 去空格函数 strip +### 去空格函数 strip - 功能:去掉字串中开头和结尾的空字符。 - 返回:返回被去掉空格的字符串值。 - 语法 @@ -1071,7 +1071,7 @@ categories: ["dev/ops"] ``` - 把字串"a b c "去到开头和结尾的空格,结果是"a b c"。 -##### 查找字符串函数findstring +### 查找字符串函数findstring - 功能:在字串中查找字串。 - 返回:如果找到,那么返回,否则返回空字符串。 - 语法: @@ -1085,7 +1085,7 @@ categories: ["dev/ops"] ``` - 第一个函数返回"a"字符串,第二个返回""字符串(空字符串) -##### 过滤函数 filter +### 过滤函数 filter - 功能:以模式过滤\字符串中的单词,保留符合模式的单词。可以有多个模式。 - 返回:返回符合模式的字串。 - 语法: @@ -1101,7 +1101,7 @@ categories: ["dev/ops"] - $(filter %.c %.s,$(sources))返回的值是"foo.c bar.c baz.s"。 -##### 反过滤函数 filter-out +### 反过滤函数 filter-out - 功能:以模式过滤\字符串中的单词,去除符合模式的单词。可以有多个模式。 - 返回:返回不符合模式的字串。 - 语法: @@ -1115,7 +1115,7 @@ categories: ["dev/ops"] ``` - $(filter-out $(mains),$(objects)) 返回值是"foo.o bar.o"。 -##### 排序函数 sort。 +### 排序函数 sort。 - 功能:给字符串中的单词排序(升序)。 - 返回:返回排序后的字符串。 - 语法: @@ -1125,7 +1125,7 @@ categories: ["dev/ops"] - 示例:$(sort foo bar lose)返回"bar foo lose" 。 - 备注:sort函数会去掉中相同的单词。 -##### 取单词函数 word +### 取单词函数 word - 功能:取字符串\中第个单词。(从一开始) - 返回:返回字符串\中第个单词。如果比\中的单词数要大,那么返回空字符串。 - 语法: @@ -1134,7 +1134,7 @@ categories: ["dev/ops"] ``` - 示例:$(word 2, foo bar baz)返回值是"bar"。 -##### 取单词串函数 wordlist +### 取单词串函数 wordlist - 功能:从字符串\中取从\开始到的单词串,\是一个数字。 - 返回:返回字符串\中从\的单词字串。如果\比\中的单词数要大,那么返回空字符串。如果大于\的单词数,那么返回从\开始,到\结束的单词串。 - 语法: @@ -1143,7 +1143,7 @@ categories: ["dev/ops"] ``` - 示例: $(wordlist 2, 3, foo bar baz)返回值是"bar baz"。 -##### 单词个数统计函数 words +### 单词个数统计函数 words - 功能:统计\中字符串中的单词个数。 - 返回:返回\中的单词数。 - 语法: @@ -1156,7 +1156,7 @@ categories: ["dev/ops"] $(word $(words \),\ )。 ``` -##### 首单词函数 firstword +### 首单词函数 firstword - 功能:取字符串\中的第一个单词。 - 返回:返回字符串\的第一个单词。 - 语法: @@ -1166,17 +1166,17 @@ categories: ["dev/ops"] - 示例:$(firstword foo bar)返回值是"foo"。 - 备注:这个函数可以用word函数来实现:$(word 1,\ )。 -##### 应用例子 +### 应用例子 - make使用"VPATH"变量来指定"依赖文件"的搜索路径,我们可以利用这个搜索路径来指定编译器对头文件的搜索路径参数CFLAGS,如: ```makefile override CFLAGS += $(patsubst %,-I%,$(subst :, ,$(VPATH))) ``` - 如果我们的"$(VPATH)"值是"src:../headers",那么"$(patsubst %,-I%,$(subst :, ,$(VPATH)))"将返回"-Isrc -I../headers",这正是cc或gcc搜索头文件路径的参数 。 -### 文件名操作函数 +## 文件名操作函数 - 下面我们要介绍的函数主要是处理文件名的。每个函数的参数字符串都会被当做一个或是一系列的文件名来对待。 -##### 取目录函数 dir +### 取目录函数 dir - 功能:从文件名序列中取出目录部分。目录部分是指最后一个反斜杠("/")之 - 前的部分。如果没有反斜杠,那么返回"./"。 - 返回:返回文件名序列的目录部分。 @@ -1186,7 +1186,7 @@ categories: ["dev/ops"] ``` - 示例: $(dir src/foo.c hacks)返回值是"src/ ./"。 -##### 取文件函数 notdir +### 取文件函数 notdir - 功能:从文件名序列中取出非目录部分。非目录部分是指最后一个反斜杠("/")之后的部分。 - 返回:返回文件名序列的非目录部分。 - 语法: @@ -1195,7 +1195,7 @@ categories: ["dev/ops"] ``` - 示例: $(notdir src/foo.c hacks)返回值是"foo.c hacks"。 -##### 取后缀函数 suffix +### 取后缀函数 suffix - 功能:从文件名序列中取出各个文件名的后缀。 - 返回:返回文件名序列的后缀序列,如果文件没有后缀,则返回空字串。 - 语法: @@ -1204,7 +1204,7 @@ categories: ["dev/ops"] ``` - 示例:$(suffix src/foo.c src-1.0/bar.c hacks)返回值是".c .c"。 -##### 取前缀函数 basename +### 取前缀函数 basename - 功能:从文件名序列中取出各个文件名的前缀部分。 - 返回:返回文件名序列的前缀序列,如果文件没有前缀,则返回空字串。 - 语法: @@ -1213,7 +1213,7 @@ categories: ["dev/ops"] ``` - 示例:$(basename src/foo.c src-1.0/bar.c hacks)返回值是"src/foo src-1.0/bar hacks"。 -##### 加后缀函数 addsuffix +### 加后缀函数 addsuffix - 功能:把后缀加到中的每个单词后面。 - 返回:返回加过后缀的文件名序列。 - 语法: @@ -1222,7 +1222,7 @@ categories: ["dev/ops"] ``` - 示例:$(addsuffix .c,foo bar)返回值是"foo.c bar.c"。 -##### 加前缀函数 addprefix +### 加前缀函数 addprefix - 功能:把前缀加到中的每个单词后面。 - 返回:返回加过前缀的文件名序列。 - 语法: @@ -1231,7 +1231,7 @@ categories: ["dev/ops"] ``` - 示例:$(addprefix src/,foo bar)返回值是"src/foo src/bar"。 -##### 连接函数 join。 +### 连接函数 join。 - 功能:把中的单词对应地加到的单词后面。如果的单词个数要比的多,那么,中的多出来的单词将保持原样。如果的单词个数要比多,那么,多出来的单词将被复制到中。 - 返回:返回连接过后的字符串。 - 语法: @@ -1240,7 +1240,7 @@ categories: ["dev/ops"] ``` - 示例:$(join aaa bbb , 111 222 333)返回值是"aaa111 bbb222 333"。 -### foreach 函数 +## foreach 函数 - foreach 函数和别的函数非常的不一样。因为这个函数是用来做循环用的,Makefile中的foreach函数几乎是仿照于Unix标准Shell(/bin /sh)中的for语句,或是C-Shell(/bin/csh)中的foreach语句而构建的。它的语法是: ```makefile $(foreach ,,\ ) @@ -1255,7 +1255,7 @@ categories: ["dev/ops"] - 上面的例子中,$(name)中的单词会被挨个取出,并存到变量"n"中,"$(n).o"每次根据"$(n)"计算出一个值,这些值以空格分隔,最后作为foreach函数的返回,所以,$(files)的值是"a.o b.o c.o d.o"。 - 注意,foreach中的参数是一个临时的局部变量,foreach函数执行完后,参数的变量将不在作用,其作用域只在foreach函数当中。 -### if 函数 +## if 函数 - if函数很像GNU的make所支持的条件语句 ifeq(参见前面所述的章节),if函数的语法是: ```makefile $(if , ) @@ -1268,7 +1268,7 @@ categories: ["dev/ops"] - 而if函数的返回值是,如果为真(非空字符串),那个会是整个函数的返回值,如果为假(空字符串),那么会是整个函数的返回值,此时如果没有被定义,那么,整个函数返回空字串。 - 所以,只会有一个被计算。 -### call函数 +## call函数 - call函数是唯一一个可以用来创建新的参数化的函数。你可以写一个非常复杂的表达式,这个表达式中,你可以定义许多参数,然后你可以用call函数来向这个表达式传递参数。其语法是: ```makefile $(call ,,,...) @@ -1285,7 +1285,7 @@ categories: ["dev/ops"] ``` - 此时的foo的值就是"b a"。 -### origin 函数 +## origin 函数 - origin函数不像其它的函数,他并不操作变量的值,他只是告诉你你的这个变量是哪里来的?其语法是: ```makefile $(origin ) @@ -1308,7 +1308,7 @@ categories: ["dev/ops"] ``` - 当然,你也许会说,使用override关键字不就可以重新定义环境中的变量了吗?为什么需要使用这样的步骤?是的,我们用override是可以达到这样的效果,可是override过于粗暴,它同时会把从命令行定义的变量也覆盖了,而我们只想重新定义环境传来的,而不想重新定义命令行传来的。 -### shell函数 +## shell函数 - shell 函数也不像其它的函数。顾名思义,它的参数应该就是操作系统Shell的命令。它和反引号"`"是相同的功能。这就是说,shell函数把执行操作系统命令后的输出作为函数返回。于是,我们可以用操作系统命令以及字符串处理命令awk,sed等等命令来生成一个变量,如: ```makefile contents := $(shell cat foo) @@ -1317,7 +1317,7 @@ categories: ["dev/ops"] - 注意,这个函数会新生成一个Shell程序来执行命令,所以你要注意其运行性能,如果你的Makefile中有一些比较复杂的规则,并大量使用了这个函数,那么对于你的系统性能是有害的。特别是Makefile的隐晦的规则可能会让你的shell函数执行的次数比你想像的多得多。 -### 控制make的函数 +## 控制make的函数 - make提供了一些函数来控制make的运行。通常,你需要检测一些运行Makefile时的运行时信息,并且根据这些信息来决定,你是让make继续执行,还是停止。 ```makefile $(error ) @@ -1341,14 +1341,14 @@ categories: ["dev/ops"] ``` # make 的运行 -### make 退出码 +## make 退出码 - make命令执行后有三个退出码: - 0 表示成功执行。 - 1 如果make运行时出现任何错误,其返回1。 - 2 如果你使用了make的"-q"选项,并且make使得一些目标不需要更新,那么返回2。 - Make的相关参数我们会在后续章节中讲述。 -### 指定Makefile +## 指定Makefile - 前面我们说过,GNU make找寻默认的Makefile的规则是在当前目录下依次找三个文件 "GNUmakefile"、"makefile"和"Makefile"。其按顺序找这三个文件,一旦找到,就开始读取这个文件并执行。 - 当前,我们也可以给make命令指定一个特殊名字的Makefile。要达到这个功能,我们要使用make的"-f"或是"--file"参数("-- makefile"参数也行)。例如,我们有个makefile的名字是"hchen.mk",那么,我们可以这样来让make来执行这个文件: ```bash @@ -1356,7 +1356,7 @@ categories: ["dev/ops"] ``` - 如果在make的命令行是,你不只一次地使用了"-f"参数,那么,所有指定的makefile将会被连在一起传递给make执行。 -### 指定目标 +## 指定目标 - 一般来说,make的最终目标是makefile中的第一个目标,而其它目标一般是由这个目标连带出来的。这是make的默认行为。当然,一般来说,你的 makefile中的第一个目标是由许多个目标组成,你可以指示make,让其完成你所指定的目标。要达到这一目的很简单,需在make命令后直接跟目标的名字就可以完成(如前面提到的"make clean"形式)任何在makefile中的目标都可以被指定成终极目标,但是除了以"- "打头,或是包含了"="的目标,因为有这些字符的目标,会被解析成命令行参数或是变量。甚至没有被我们明确写出来的目标也可以成为make的终极目标,也就是说,只要make可以找到其隐含规则推导规则,那么这个隐含目标同样可以被指定成终极目标。 - 有一个make的环境变量叫"MAKECMDGOALS",这个变量中会存放你所指定的终极目标的列表,如果在命令行上,你没有指定目标,那么,这个变量是空值。这个变量可以让你使用在一些比较特殊的情形下。比如下面的例子: ```makefile @@ -1383,7 +1383,7 @@ categories: ["dev/ops"] - "check"和"test" 这两个伪目标一般用来测试makefile的流程。 - 当然一个项目的makefile中也不一定要书写这样的目标,这些东西都是GNU的东西,但是我想,GNU搞出这些东西一定有其可取之处(等你的UNIX下的程序文件一多时你就会发现这些功能很有用了),这里只不过是说明了,如果你要书写这种功能,最好使用这种名字命名你的目标,这样规范一些,规范的好处就是 不用解释,大家都明白。而且如果你的makefile中有这些功能,一是很实用,二是可以显得你的makefile很专业(不是那种初学者的作品)。 -### 检查规则 +## 检查规则 - 有时候,我们不想让我们的makefile中的规则执行起来,我们只想检查一下我们的命令,或是执行的序列。于是我们可以使用make命令的下述参数: - "-n" "--just-print" "--dry-run" "--recon" 不执行参数,这些参数只是打印命令,不管目标是否更新,把规则和连带规则下的命令打印出来,但不执行,这些参数对于我们调试makefile很有用处。 - "-t" "--touch" 这个参数的意思就是把目标文件的时间更新,但不更改目标文件。也就是说,make假装编译目标,但不是真正的编译目标,只是把目标变成已编译过的状态。 @@ -1391,7 +1391,7 @@ categories: ["dev/ops"] - "-W " "--what-if=" "--assume-new=" "--new-file=" 这个参数需要指定一个文件。一般是是源文件(或依赖文件),Make会根据规则推导来运行依赖于这个文件的命令,一般来说,可以和"-n"参数一同使用,来查看这个依赖文件所发生的规则命令。 - 另外一个很有意思的用法是结合"-p"和"-v"来输出makefile被执行时的信息(这个将在后面讲述)。 -### make的参数 +## make的参数 - 下面列举了所有GNU make 3.80版的参数定义。其它版本和产商的make大同小异,不过其它产商的make的具体参数还是请参考各自的产品文档。 - "-b" "-m" 这两个参数的作用是忽略和其它版本make的兼容性。 - "-B" "--always-make" 认为所有的目标都需要更新(重编译)。 @@ -1433,7 +1433,7 @@ categories: ["dev/ops"] - "隐含规则"会使用一些我们系统变量,我们可以改变这些系统变量的值来定制隐含规则的运行时的参数。如系统变量"CFLAGS"可以控制编译时的编译器参数。 - 我们还可以通过"模式规则"的方式写下自己的隐含规则。用"后缀规则"来定义隐含规则会有许多的限制。使用"模式规则"会更回得智能和清楚,但"后缀规则"可以用来保证我们Makefile的兼容性。 -### 使用隐含规则 +## 使用隐含规则 - 如果要使用隐含规则生成你需要的目标,你所需要做的就是不要写出这个目标的规则。那么,make会试图去自动推导产生这个目标的规则和命令,如果make可以自动推导生成这个目标的规则和命令,那么这个行为就是隐含规则的自动推导。当然,隐含规则是make事先约定好的一些东西。例如,我们有下面的一个Makefile: ```makefile foo : foo.o bar.o @@ -1456,7 +1456,7 @@ categories: ["dev/ops"] ``` - 依赖文件"foo.p"(Pascal程序的源文件)有可能变得没有意义。如果目录下存在了"foo.c"文件,那么我们的隐含规则一样会生效,并会通过 "foo.c"调用C的编译器生成foo.o文件。因为,在隐含规则中,Pascal的规则出现在C的规则之后,所以,make找到可以生成foo.o的 C的规则就不再寻找下一条规则了。如果你确实不希望任何隐含规则推导,那么,你就不要只写出"依赖规则",而不写命令。 -### 隐含规则一览 +## 隐含规则一览 - 这里我们将讲述所有预先设置(也就是make内建)的隐含规则,如果我们不明确地写下规则,那么,make就会在这些规则中寻找所需要规则和命令。当然,我们也可以使用make的参数"-r"或"--no-builtin-rules"选项来取消所有的预设置的隐含规则。 - 当然,即使是我们指定了"-r"参数,某些隐含规则还是会生效,因为有许多的隐含规则都是使用了"后缀规则"来定义的,所以,只要隐含规则中有"后缀列表 "(也就一系统定义在目标.SUFFIXES的依赖目标),那么隐含规则就会生效。默认的后缀列表是:.out,.a, .ln, .o, .c, .cc, .C, .p, .f, .F, .r, .y, .l, .s, .S, .mod, .sym, .def, .h, .info, .dvi, .tex, .texinfo, .texi, .txinfo, .w, .ch .web, .sh, .elc, .el。具体的细节,我们会在后面讲述。 - 常用的隐含规则 @@ -1530,7 +1530,7 @@ categories: ["dev/ops"] - 从C程序、Yacc文件或Lex文件创建Lint库的隐含规则。 ".ln" (lint生成的文件)的依赖文件被自动推导为"n.c",其生成命令是:"$(LINT) $(LINTFALGS) $(CPPFLAGS) -i"。对于".y"和".l"也是同样的规则。 -### 隐含规则使用的变量 +## 隐含规则使用的变量 - 在隐含规则中的命令中,基本上都是使用了一些预先设置的变量。你可以在你的makefile中改变这些变量的值,或是在make的命令行中传入这些值,或是在你的环境变量中设置这些值,无论怎么样,只要设置了这些特定的变量,那么其就会对隐含规则起作用。当然,你也可以利用make的"-R"或"--no– builtin-variables"参数来取消你所定义的变量对隐含规则的作用。 - 例如,第一条隐含规则 编译C程序的隐含规则的命令是"$(CC) –c $(CFLAGS) $(CPPFLAGS)"。Make默认的编译命令是"cc",如果你把变量"$(CC)"重定义成"gcc",把变量"$(CFLAGS)"重定义成 "-g",那么,隐含规则中的命令全部会以"gcc –c -g $(CPPFLAGS)"的样子来执行了。 - 我们可以把隐含规则中使用的变量分成两种:一种是命令相关的,如"CC";一种是参数 @@ -1571,7 +1571,7 @@ categories: ["dev/ops"] - RFLAGS Ratfor 程序的Fortran 编译器参数。 - YFLAGS Yacc文法分析器参数。 -### 隐含规则链 +## 隐含规则链 - 有些时候,一个目标可能被一系列的隐含规则所作用。例如,一个[.o]的文件生成,可能会是先被Yacc的[.y]文件先成[.c],然后再被C的编译器生成。我们把这一系列的隐含规则叫做"隐含规则链"。 - 在上面的例子中,如果文件[.c]存在,那么就直接调用C的编译器的隐含规则,如果没有[.c]文件,但有一个[.y]文件,那么Yacc的隐含规则会被调用,生成[.c]文件,然后,再调用C编译的隐含规则最终由[.c]生成[.o]文件,达到目标。 - 在默认情况下,对于中间目标,它和一般的目标有两个地方所不同:第一个不同是除非中间的目标不存在,才会引发中间规则。第二个不同的是,只要目标成功产生,那么,产生最终目标过程中,所产生的中间目标文件会被以"rm -f"删除。 @@ -1580,11 +1580,11 @@ categories: ["dev/ops"] - 在"隐含规则链"中,禁止同一个目标出现两次或两次以上,这样一来,就可防止在make自动推导时出现无限递归的情况。 - Make 会优化一些特殊的隐含规则,而不生成中间文件。如,从文件"foo.c"生成目标程序"foo",按道理,make会编译生成中间文件"foo.o",然后链接成"foo",但在实际情况下,这一动作可以被一条"cc"的命令完成(cc –o foo foo.c),于是优化过的规则就不会生成中间文件。 -### 定义模式规则 +## 定义模式规则 - 你可以使用模式规则来定义一个隐含规则。一个模式规则就好像一个一般的规则,只是在规则中,目标的定义需要有"%"字符。"%"的意思是表示一个或多个任意字符。在依赖目标中同样可以使用"%",只是依赖目标中的"%"的取值,取决于其目标。 - 有一点需要注意的是,"%"的展开发生在变量和函数的展开之后,变量和函数的展开发生在make载入Makefile时,而模式规则中的"%"则发生在运行时。 -##### 模式规则介绍 +### 模式规则介绍 - 模式规则中,至少在规则的目标定义中要包含"%",否则,就是一般的规则。目标中的"%"定义表示对文件名的匹配,"%"表示长度任意的非空字符串。例如:"%.c"表示以".c"结尾的文件名(文件名的长度至少为3),而"s.%.c"则表示以"s."开头,".c"结尾的文件名(文件名的长度至少为 5)。 - 如果"%"定义在目标中,那么,目标中的"%"的值决定了依赖目标中的"%"的值,也就是说,目标中的模式的"%"决定了依赖目标中"%"的样子。例如有一个模式规则如下: ```makefile @@ -1593,7 +1593,7 @@ categories: ["dev/ops"] - 其含义是,指出了怎么从所有的[.c]文件生成相应的[.o]文件的规则。如果要生成的目标是"a.o b.o",那么"%c"就是"a.c b.c"。 - 一旦依赖目标中的"%"模式被确定,那么,make会被要求去匹配当前目录下所有的文件名,一旦找到,make就会规则下的命令,所以,在模式规则中,目标可能会是多个的,如果有模式匹配出多个目标,make就会产生所有的模式目标,此时,make关心的是依赖的文件名和生成目标的命令这两件事。 -##### 模式规则示例 +### 模式规则示例 - 下面这个例子表示了,把所有的[.c]文件都编译成[.o]文件. ```makefile %.o : %.c @@ -1607,7 +1607,7 @@ categories: ["dev/ops"] ``` - 这条规则告诉make把所有的[.y]文件都以"bison -d .y"执行,然后生成".tab.c"和".tab.h"文件。(其中,"" 表示一个任意字符串)。如果我们的执行程序"foo"依赖于文件"parse.tab.o"和"scan.o",并且文件"scan.o"依赖于文件"parse.tab.h",如果"parse.y"文件被更新了,那么根据上述的规则,"bison -d parse.y"就会被执行一次,于是,"parse.tab.o"和"scan.o"的依赖文件就齐了。(假设,"parse.tab.o" 由"parse.tab.c"生成,和"scan.o"由"scan.c"生成,而"foo"由"parse.tab.o"和"scan.o"链接生成,而且foo和其[.o]文件的依赖关系也写好,那么,所有的目标都会得到满足) -##### 自动化变量 +### 自动化变量 - 在上述的模式规则中,目标和依赖文件都是一系例的文件,那么我们如何书写一个命令来完成从不同的依赖文件生成相应的目标?因为在每一次的对模式规则的解析时,都会是不同的目标和依赖文件。 - 自动化变量就是完成这个功能的。在前面,我们已经对自动化变量有所提涉,相信你看到这里已对它有一个感性认识了。所谓自动化变量,就是这种变量会把模式中所定义的一系列的文件自动地挨个取出,直至所有的符合模式的文件都取完了。这种自动化变量只应出现在规则的命令中。 - 下面是所有的自动化变量及其说明: @@ -1636,11 +1636,11 @@ categories: ["dev/ops"] - 最后想提醒一下的是,对于"$<",为了避免产生不必要的麻烦,我们最好给$后面的那个特定字符都加上圆括号,比如,"$(< )"就要比"$<"要好一些。 - 还得要注意的是,这些变量只使用在规则的命令中,而且一般都是"显式规则"和"静态模式规则"(参见前面"书写规则"一章)。其在隐含规则中并没有意义。 -### 模式的匹配 +## 模式的匹配 - 一般来说,一个目标的模式有一个有前缀或是后缀的"%",或是没有前后缀,直接就是一个"%"。因为"%"代表一个或多个字符,所以在定义好了的模式中,我们把"%"所匹配的内容叫做"茎",例如"%.c"所匹配的文件"test.c"中"test"就是"茎"。因为在目标和依赖目标中同时有"%"时,依赖目标的"茎"会传给目标,当做目标中的"茎"。 - 当一个模式匹配包含有斜杠(实际也不经常包含)的文件时,那么在进行模式匹配时,目录部分会首先被移开,然后进行匹配,成功后,再把目录加回去。在进行"茎"的传递时,我们需要知道这个步骤。例如有一个模式"e%t",文件"src/eat" 匹配于该模式,于是"src/a"就是其"茎",如果这个模式定义在依赖目标中,而被依赖于这个模式的目标中又有个模式"c%r",那么,目标就是"src/car"。("茎"被传递) -### 重载内建隐含规则 +## 重载内建隐含规则 - 你可以重载内建的隐含规则(或是定义一个全新的),例如你可以重新构造和内建隐含规则不同的命令,如: ```makefile %.o : %.c @@ -1699,7 +1699,7 @@ categories: ["dev/ops"] # 使用make更新函数库文件 - 函数库文件也就是对Object文件(程序编译的中间文件)的打包文件。在Unix下,一般是由命令"ar"来完成打包工作。 -### 函数库文件的成员 +## 函数库文件的成员 - 一个函数库文件由多个文件组成。你可以以如下格式指定函数库文件及其组成: - archive(member) 这个不是一个命令,而一个目标和依赖的定义。一般来说,这种用法基本上就是为了"ar"命令来服务的。如: ```makefile @@ -1719,7 +1719,7 @@ categories: ["dev/ops"] foolib(*.o) ``` -### 函数库成员的隐含规则 +## 函数库成员的隐含规则 - 当 make搜索一个目标的隐含规则时,一个特殊的特性是,如果这个目标是"a(m)"形式的,其会把目标变成"(m)"。于是,如果我们的成员是"%.o" 的模式定义,并且如果我们使用"make foo.a(bar.o)"的形式调用Makefile时,隐含规则会去找"bar.o"的规则,如果没有定义bar.o的规则,那么内建隐含规则生效,make会去找bar.c文件来生成bar.o,如果找得到的话,make执行的命令大致如下: ```makefile cc -c bar.c -o bar.o @@ -1728,7 +1728,7 @@ categories: ["dev/ops"] ``` - 还有一个变量要注意的是"$%",这是专属函数库文件的自动化变量,有关其说明请参见"自动化变量"一节。 -### 函数库文件的后缀规则 +## 函数库文件的后缀规则 - 你可以使用"后缀规则"和"隐含规则"来生成函数库打包文件,如: ```makefile .c.a: diff --git a/content/post/mariadb-10.1.md b/content/post/mariadb-10.1.md index a683bac..64a1a75 100644 --- a/content/post/mariadb-10.1.md +++ b/content/post/mariadb-10.1.md @@ -9,85 +9,74 @@ categories: ["database"] 环境:centos 5.4/6.2/6.5/7.2 x64 1、下载官方编译好的 linux 通用安装包,解压之自定义目录(如/opt)下 - -```bash -# rhel 7 地址: -wget https://mirrors.tuna.tsinghua.edu.cn/mariadb//mariadb-10.1.19/bintar-linux-glibc_214-x86_64/mariadb-10.1.19-linux-glibc_214-x86_64.tar.gz -# rhel 5/6 地址: -wget https://mirrors.tuna.tsinghua.edu.cn/mariadb//mariadb-10.1.19/bintar-linux-x86_64/mariadb-10.1.19-linux-x86_64.tar.gz -tar zxf mariadb-10.1.19-linux*-x86_64.tar.gz -C /opt/ -cd /opt;mv mariadb-10.1.19-linux* mariadb -``` + ```bash + # rhel 7 地址: + wget https://mirrors.tuna.tsinghua.edu.cn/mariadb//mariadb-10.1.19/bintar-linux-glibc_214-x86_64/mariadb-10.1.19-linux-glibc_214-x86_64.tar.gz + # rhel 5/6 地址: + wget https://mirrors.tuna.tsinghua.edu.cn/mariadb//mariadb-10.1.19/bintar-linux-x86_64/mariadb-10.1.19-linux-x86_64.tar.gz + tar zxf mariadb-10.1.19-linux*-x86_64.tar.gz -C /opt/ + cd /opt;mv mariadb-10.1.19-linux* mariadb + ``` 2、创建服务文件和配置文件,创建日志目录 - -``` -cd /opt/mariadb -mv support_files/my-large.cnf ./my.cnf -mv support_files/mysql.server ./mysqld -mkdir -p log -``` + ```bash + cd /opt/mariadb + mv support_files/my-large.cnf ./my.cnf + mv support_files/mysql.server ./mysqld + mkdir -p log + ``` 3、修改服务文件 mysqld - -``` -vim /opt/mariadb/mysqld -# 在打开的文件中,修改开头的basedir和datadir,datadir是数据库文件目录,建议指定一个大分区中的目录 -basedir=/opt/mariadb -datadir=/mnt/sdb1/mariadb_db -# 修改开头的lockdir和lock-file-path -lockdir='/opt/mariadb/log' -lock-file-path="$lockdir/mysql.lock" - -``` + ``` + vim /opt/mariadb/mysqld + # 在打开的文件中,修改开头的basedir和datadir,datadir是数据库文件目录,建议指定一个大分区中的目录 + basedir=/opt/mariadb + datadir=/mnt/sdb1/mariadb_db + # 修改开头的lockdir和lock-file-path + lockdir='/opt/mariadb/log' + lock-file-path="$lockdir/mysql.lock" + ``` 4、修改配置文件 /opt/mariadb/my.cnf - -``` -[mysqld] -datadir=/mnt/sdb1/mariadb_db -log-error=/opt/mariadb/log/error.log -pid-file=/opt/mariadb/log/mysql.pid -user = mysql -#port = 3306 -socket = /tmp/mysql.sock -skip-networking # 取消监听端口,适合本地数据库使用 -skip-name-resolve # 取消域名解析 -max-connections = 3000 -max-connect-errors = 1000 - -#如果系统中存在 /etc/my.cnf 且不可写, 可以在 /opt/mariadb/my.cnf 中重新设置冲突项。 - -``` + ```ini + [mysqld] + datadir=/mnt/sdb1/mariadb_db + log-error=/opt/mariadb/log/error.log + pid-file=/opt/mariadb/log/mysql.pid + user = mysql + #port = 3306 + socket = /tmp/mysql.sock + skip-networking # 取消监听端口,适合本地数据库使用 + skip-name-resolve # 取消域名解析 + max-connections = 3000 + max-connect-errors = 1000 + #如果系统中存在 /etc/my.cnf 且不可写, 可以在 /opt/mariadb/my.cnf 中重新设置冲突项。 + ``` 5、修改数据库程序数据目录的权限: - -```bash -chown mysql.mysql /opt/mariadb/ -R -chown mysql.mysql /mnt/sdb1/mariadb_db/ -R -``` + ```bash + chown mysql.mysql /opt/mariadb/ -R + chown mysql.mysql /mnt/sdb1/mariadb_db/ -R + ``` 6、安装数据库 - -```bash -/opt/mariadb/scripts/mysql_install_db --basedir=/opt/mariadb --datadir=/mnt/sdb1/mariadb_db --user=mysql -``` + ```bash + /opt/mariadb/scripts/mysql_install_db --basedir=/opt/mariadb --datadir=/mnt/sdb1/mariadb_db --user=mysql + ``` 7、根据提示,修改mariadb的root帐号密码,禁用root登陆,删除匿名用户及test库 - -```bash -# 启动 mariadb -/opt/mariadb/mysqld start -# 修改 root 密码 -/opt/mariadb/bin/mysqladmin -u root password '12345678' -# 安全设置 -/opt/mariadb/bin/mysql_secure_install --basedir=/opt/mariadb -``` + ```bash + # 启动 mariadb + /opt/mariadb/mysqld start + # 修改 root 密码 + /opt/mariadb/bin/mysqladmin -u root password '12345678' + # 安全设置 + /opt/mariadb/bin/mysql_secure_install --basedir=/opt/mariadb + ``` 8、增加系统动态库配置 - -```bash -echo '/opt/mariadb/lib' >> /etc/ld.so.conf -ldconfig -``` + ```bash + echo '/opt/mariadb/lib' >> /etc/ld.so.conf + ldconfig + ``` diff --git a/content/post/mariadb-galera.md b/content/post/mariadb-galera.md index 5970127..2a68c91 100644 --- a/content/post/mariadb-galera.md +++ b/content/post/mariadb-galera.md @@ -15,7 +15,7 @@ cpu | mem | hostname | public ip | cluster ip | CentOS | MariaDB # 安装数据库 -### 离线安装 +## 离线安装 - [下载 rpm](http://yum.mariadb.org/10.1/centos7-amd64/rpms/) - MariaDB-10.1.33-centos7-x86_64-client.rpm - MariaDB-10.1.33-centos7-x86_64-common.rpm @@ -33,7 +33,7 @@ cpu | mem | hostname | public ip | cluster ip | CentOS | MariaDB mysql_install_db --user=mysql ``` -### yum 安装 +## yum 安装 - 创建 MariaDB-10.1 的 yum 源文件(就近选择一个) ```bash #官方 @@ -61,6 +61,7 @@ cpu | mem | hostname | public ip | cluster ip | CentOS | MariaDB gpgcheck=1 END ``` + - 安装 MariaDB ```bash yum install MariaDB-client MariaDB-server @@ -68,9 +69,9 @@ cpu | mem | hostname | public ip | cluster ip | CentOS | MariaDB ``` # 启动server -```bash -systemctl start mariadb -``` + ```bash + systemctl start mariadb + ``` # 安全设置 - 设置root账户密码(推荐) diff --git a/content/post/mariadb-replication.md b/content/post/mariadb-replication.md index 2644f05..64d7100 100644 --- a/content/post/mariadb-replication.md +++ b/content/post/mariadb-replication.md @@ -13,116 +13,116 @@ categories: ["database"] - 忽略系统数据库: information_schema, mysql, performance_schema # 在两个主服务器上创建用于备份的用户 replicator -```sql -grant replication slave on *.* to 'replicator'@'%' identified by 'password'; -flush privileges; -``` + ```sql + grant replication slave on *.* to 'replicator'@'%' identified by 'password'; + flush privileges; + ``` # 在两个主服务器上修改 my.cnf -``` -# 唯一 ID -# 192.168.1.141 配置 -server-id = 141 -# 192.168.1.142 配置 -server-id = 142 -read-only = 0 - -# binlog -# MariaDB 默认已开启 GTID -log-bin = /var/lib/mysql-bin/master -binlog-format = row -sync_binlog = 1 -expire-logs-days = 3 -gtid-strict-mode = ON - -# relay log -replicate-wild-ignore-table = information_schema.% -replicate-wild-ignore-table = init_sql.% -replicate-wild-ignore-table = mysql.% -replicate-wild-ignore-table = performance_schema.% -relay-log = /var/lib/mysql-bin/slave -relay-log-recovery = TRUE -# 复制线程数不超过 cpu 核数 -slave-parallel-threads = 4 - -# 双主或多主互备时,可能会用到以下配置 -# 自增主键初始值,与其他互备服务器一致 -#auto-increment-offset = -# 自增主键等差值,与其他互备服务器均不一致 -#auto-increment-increment = -# 该环境中,双主配合 keepalived 实现高可用,无需配置自增 -``` + ``` + # 唯一 ID + # 192.168.1.141 配置 + server-id = 141 + # 192.168.1.142 配置 + server-id = 142 + read-only = 0 + + # binlog + # MariaDB 默认已开启 GTID + log-bin = /var/lib/mysql-bin/master + binlog-format = row + sync_binlog = 1 + expire-logs-days = 3 + gtid-strict-mode = ON + + # relay log + replicate-wild-ignore-table = information_schema.% + replicate-wild-ignore-table = init_sql.% + replicate-wild-ignore-table = mysql.% + replicate-wild-ignore-table = performance_schema.% + relay-log = /var/lib/mysql-bin/slave + relay-log-recovery = TRUE + # 复制线程数不超过 cpu 核数 + slave-parallel-threads = 4 + + # 双主或多主互备时,可能会用到以下配置 + # 自增主键初始值,与其他互备服务器一致 + #auto-increment-offset = + # 自增主键等差值,与其他互备服务器均不一致 + #auto-increment-increment = + # 该环境中,双主配合 keepalived 实现高可用,无需配置自增 + ``` # 开启互主同步 -```sql --- 在 192.168.1.141 上启动 mariadb,配置同步 192.168.1.142: -change master to master_host = '192.168.1.142', - master_port = 3306, - master_user = 'replicator', - master_password = 'password', - master_use_gtid = slave_pos; - --- 在 192.168.1.142 上启动 mariadb,配置同步 192.168.1.141: -change master to master_host = '192.168.1.141', - master_port = 3306, - master_user = 'replicator', - master_password = 'password', - master_use_gtid = slave_pos; -``` + ```sql + -- 在 192.168.1.141 上启动 mariadb,配置同步 192.168.1.142: + change master to master_host = '192.168.1.142', + master_port = 3306, + master_user = 'replicator', + master_password = 'password', + master_use_gtid = slave_pos; + + -- 在 192.168.1.142 上启动 mariadb,配置同步 192.168.1.141: + change master to master_host = '192.168.1.141', + master_port = 3306, + master_user = 'replicator', + master_password = 'password', + master_use_gtid = slave_pos; + ``` # 在两个主服务器上启动 slave ,查看 slave 状态 -```sql -start slave; --- 查看 slave 状态 -show slave status\G --- 如果看到 --- Slave_IO_Running: Yes --- Slave_SQL_Running: Yes --- 则表示 slave 开启成功! -``` + ```sql + start slave; + -- 查看 slave 状态 + show slave status\G + -- 如果看到 + -- Slave_IO_Running: Yes + -- Slave_SQL_Running: Yes + -- 则表示 slave 开启成功! + ``` # 在从服务器上编辑 my.cnf -``` -# 唯一 ID -server-id = 143 -# 从服务器只做查询,无增删改 -read-only = 1 - -# 忽略的数据表 -#replicate-ignore-table = db1.t1 -replicate-wild-ignore-table = information_schema.% -replicate-wild-ignore-table = init_sql.% -replicate-wild-ignore-table = mysql.% -replicate-wild-ignore-table = performance_schema.% -relay-log = /var/log/mysql-bin/slave -slave-parallel-threads = 4 -``` + ``` + # 唯一 ID + server-id = 143 + # 从服务器只做查询,无增删改 + read-only = 1 + + # 忽略的数据表 + #replicate-ignore-table = db1.t1 + replicate-wild-ignore-table = information_schema.% + replicate-wild-ignore-table = init_sql.% + replicate-wild-ignore-table = mysql.% + replicate-wild-ignore-table = performance_schema.% + relay-log = /var/log/mysql-bin/slave + slave-parallel-threads = 4 + ``` # 开启同步 -```sql -change master 'db141' to master_host = '192.168.1.141', - master_port = 3306, - master_user = 'replicator', - master_password = 'password', - master_use_gtid = slave_pos; - -change master 'db142' to master_host = '192.168.1.142', - master_port = 3306, - master_user = 'replicator', - master_password = 'password', - master_use_gtid = slave_pos; -``` + ```sql + change master 'db141' to master_host = '192.168.1.141', + master_port = 3306, + master_user = 'replicator', + master_password = 'password', + master_use_gtid = slave_pos; + + change master 'db142' to master_host = '192.168.1.142', + master_port = 3306, + master_user = 'replicator', + master_password = 'password', + master_use_gtid = slave_pos; + ``` # 在从服务器上启动 slave ,查看 slave 状态 -```sql -start all slaves; --- 在从服务器上查看 slave 状态 -show all slaves status\G --- 如果看到 --- Slave_IO_Running: Yes --- Slave_SQL_Running: Yes --- 则表示 slave 开启成功! -``` + ```sql + start all slaves; + -- 在从服务器上查看 slave 状态 + show all slaves status\G + -- 如果看到 + -- Slave_IO_Running: Yes + -- Slave_SQL_Running: Yes + -- 则表示 slave 开启成功! + ``` # 参考 - [MariaDB 复制](https://mariadb.com/kb/en/standard-replication/) diff --git a/content/post/mongodb.md b/content/post/mongodb.md index 9d4683d..5e0f777 100644 --- a/content/post/mongodb.md +++ b/content/post/mongodb.md @@ -8,7 +8,7 @@ categories: ["database"] --- # 数据迁移 -### 导出集合数据到 json 或 csv 文件 +## 导出集合数据到 json 或 csv 文件 - 命令 ``` mongoexport -d dbname -c collectionname -o file --type json/csv -f "field1,field2,...,fieldN" @@ -20,7 +20,7 @@ categories: ["database"] - --type 输出格式,默认 json - -f 输出字段,如果导出 csv,需指定字段名 -### 导入数据到集合 +## 导入数据到集合 - 命令 ``` mongoimport -d dbname -c collectionname --file filename --headerline --type json/csv -f "field1,field2,...,fieldN" @@ -33,7 +33,7 @@ categories: ["database"] - --headerline 导入csv时,使用第一行的标题作为导入字段 - --file 导入的文件 -### 备份数据库 +## 备份数据库 - 命令 ``` mongodump -h dbhost -d dbname -o backup_dir @@ -43,7 +43,7 @@ categories: ["database"] - -d 数据库名 - -o 备份数据存放目录,需提前建立 -### 恢复数据库 +## 恢复数据库 - 命令 ``` mongorestore -h dbhost -d dbname --dir backup_dir @@ -63,20 +63,20 @@ categories: ["database"] - 删除数据库 use dbname; db.dropDatabase() # 操作集合 -### 创建 +## 创建 ``` db.createCollection("集合名", {capped:false, autoIndexId:false, size:最大字节, max:文档最多数量}) # 或者在插入文档时自动创建 db.集合名.inert({}) ``` -### 删除 +## 删除 ``` db.集合名.drop() ``` # 操作文档 -### insert +## insert - 插入一个文档 ``` db.集合名.insert({}) @@ -90,7 +90,7 @@ db.集合名.drop() db.集合名.insertMany([{},{},{},...,{}]) ``` -### find +## find - 查询匹配的文档 ``` db.集合名.find({}).pretty() @@ -124,7 +124,7 @@ db.集合名.drop() db.集合名.find({}).sort({"key":1}) ``` -### update +## update - 更新一个文档 ``` db.集合名.update({},{$set:{}}) @@ -134,12 +134,12 @@ db.集合名.drop() db.集合名.update({},{$set:{},{multi:true}}) ``` -### save +## save ``` db.集合名.save({,...}) ``` -### remove +## remove - 删除多条记录 ``` db.集合名.remove({}) @@ -153,19 +153,19 @@ db.集合名.save({,...}) db.集合名.remove() ``` -### 索引 +## 索引 - 创建索引,1升序,-1降序 ``` db.集合名.createIndex({"key1":1,"key2":-1}) ``` -### 聚合 +## 聚合 ``` db.集合名.aggregate([{}]) ``` # 用户 -### 创建用户 +## 创建用户 - 管理员权限 ``` use admin @@ -189,23 +189,23 @@ db.集合名.aggregate([{}]) ) ``` -### 验证身份 +## 验证身份 ``` db.auth("username", "password") ``` -### 列出所有用户 +## 列出所有用户 ``` db.getUsers() ``` -### 删除数据库用户 +## 删除数据库用户 ``` use testdb db.dropUser("username") ``` -### 更改用户密码 +## 更改用户密码 ``` db.updateUser( "username", diff --git a/content/post/mysql-galera.md b/content/post/mysql-galera.md index 2073c12..7bc5fea 100644 --- a/content/post/mysql-galera.md +++ b/content/post/mysql-galera.md @@ -15,79 +15,79 @@ cpu | mem | hostname | public ip | cluster ip | CentOS | MySQL 双核 | 2GB | mysql_3 | 10.0.0.233 | 10.10.10.3 | 7.5 | 5.7 # 创建 galera yum 源文件 -```bash -cat > /etc/yum.repos.d/galera.repo <<-END -[galera] -name = Galera -baseurl = http://releases.galeracluster.com/galera-3/centos/7/x86_64/ -gpgkey = http://releases.galeracluster.com/GPG-KEY-galeracluster.com -gpgcheck = 1 -# -[mysql-wsrep] -name = MySQL-wsrep -baseurl = http://releases.galeracluster.com/mysql-wsrep-5.7/centos/7/x86_64/ -gpgkey = http://releases.galeracluster.com/GPG-KEY-galeracluster.com -gpgcheck = 1 -END -``` + ```bash + cat > /etc/yum.repos.d/galera.repo <<-END + [galera] + name = Galera + baseurl = http://releases.galeracluster.com/galera-3/centos/7/x86_64/ + gpgkey = http://releases.galeracluster.com/GPG-KEY-galeracluster.com + gpgcheck = 1 + + [mysql-wsrep] + name = MySQL-wsrep + baseurl = http://releases.galeracluster.com/mysql-wsrep-5.7/centos/7/x86_64/ + gpgkey = http://releases.galeracluster.com/GPG-KEY-galeracluster.com + gpgcheck = 1 + END + ``` # 安装 -```bash -yum install galera-3 mysql-wsrep-5.7 rsync -``` + ```bash + yum install galera-3 mysql-wsrep-5.7 rsync + ``` # 修改 /etc/my.cnf -``` -[mysqld] -datadir=/var/lib/mysql -socket=/var/lib/mysql/mysql.sock -user=mysql -binlog-format=ROW -bind-address=0.0.0.0 -default-storage-engine=innodb -innodb-autoinc-lock-mode=2 -innodb-flush-log-at-trx-commit=0 -innodb-buffer-pool-size=1024M #物理内存一半 -wsrep-provider=/usr/lib64/galera-3/libgalera_smm.so -wsrep-provider-options="gcache.dir=/var/lib/gcache;gcache.size=1G;gcache.recover=yes;pc.recovery=TRUE" -wsrep-cluster-name="mysql_galera_cluster" #集群名字 -wsrep-cluster-address="gcomm://10.10.10.1,10.10.10.2,10.10.10.3" -wsrep-sst-method=rsync -wsrep-node-name=mysql_1 #当前节点名字 -wsrep-node-address="10.10.10.1" #当前节点 cluster ip -#wsrep-auto-increment-control=OFF #只通过一个节点做增删改时使用 -# -[mysql_safe] -log-error=/var/log/mysqld.log -pid-file=/var/run/mysqld/mysqld.pid -# -!includedir /etc/my.cnf.d/ -``` + ``` + [mysqld] + datadir=/var/lib/mysql + socket=/var/lib/mysql/mysql.sock + user=mysql + binlog-format=ROW + bind-address=0.0.0.0 + default-storage-engine=innodb + innodb-autoinc-lock-mode=2 + innodb-flush-log-at-trx-commit=0 + innodb-buffer-pool-size=1024M #物理内存一半 + wsrep-provider=/usr/lib64/galera-3/libgalera_smm.so + wsrep-provider-options="gcache.dir=/var/lib/gcache;gcache.size=1G;gcache.recover=yes;pc.recovery=TRUE" + wsrep-cluster-name="mysql_galera_cluster" #集群名字 + wsrep-cluster-address="gcomm://10.10.10.1,10.10.10.2,10.10.10.3" + wsrep-sst-method=rsync + wsrep-node-name=mysql_1 #当前节点名字 + wsrep-node-address="10.10.10.1" #当前节点 cluster ip + #wsrep-auto-increment-control=OFF #只通过一个节点做增删改时使用 + + [mysql_safe] + log-error=/var/log/mysqld.log + pid-file=/var/run/mysqld/mysqld.pid + + !includedir /etc/my.cnf.d/ + ``` # 随机选择一个节点,使用专用脚本 mysqld_bootstrap 初始化集群 -```bash -/usr/bin/mysqld_bootstrap -#该命令会启动本机的 mysqld 服务 -systemctl status mysqld -``` + ```bash + /usr/bin/mysqld_bootstrap + # 该命令会启动本机的 mysqld 服务 + systemctl status mysqld + ``` # 查找密码,修改初始密码 -```bash -grep -i password /var/log/messages -#记录输出的密码 -mysqladmin -uroot -p password 'P@sswo2d' -#根据提示输入上一步输出的密码 -``` + ```bash + grep -i password /var/log/messages + # 记录输出的密码 + mysqladmin -uroot -p password 'P@sswo2d' + # 根据提示输入上一步输出的密码 + ``` # 在其他节点上启动 mysqld 服务 -```bash -systemctl start mysqld -``` + ```bash + systemctl start mysqld + ``` # 查看集群节点数量 -```sql -show status like 'wsrep_cluster_size'; -``` + ```sql + show status like 'wsrep_cluster_size'; + ``` # ssl 加密同步数据(不推荐,存在性能损失) - 生成证书 @@ -103,11 +103,13 @@ show status like 'wsrep_cluster_size'; -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 \ -out server-cert.pem ``` + - 修改配置文件 my.cnf ``` - #在 wsrep_provider_options 中添加如下选项,选项间用分号";"间隔 + # 在 wsrep_provider_options 中添加如下选项,选项间用分号";"间隔 socket.ssl_key=/etc/my.cnf.d/ssl/server-key.pem; socket.ssl_cert=/etc/my.cnf.d/ssl/server-cert.pem; socket.ssl_ca=/etc/my.cnf.d/ssl/ca-cert.pem; socket.checksum=2; socket.ssl_cipher=AES128-SHA ``` + - 重新启动集群 # ssl 加密客户端(不推荐,存在性能损失) diff --git a/content/post/mysql-group-replication.md b/content/post/mysql-group-replication.md index 36a5729..c07a630 100644 --- a/content/post/mysql-group-replication.md +++ b/content/post/mysql-group-replication.md @@ -17,72 +17,73 @@ mysql_33 | 192.168.1.33 | centos7.7 | 8.0.19 - 懒得写了 ... # 修改 my.cnf -``` -# mysql_11(选择一个) -server-id = 11 -# mysql_22(选择一个) -server-id = 22 -# mysql_33(选择一个) -server-id = 33 - -# 开启 binlog -log-bin = /var/log/mysql-bin/master -binlog-format = ROW -# 关闭 binlog 校验 -binlog-checksum = NONE -# 保留 2 天的 binlog -binlog-expire-logs-seconds = 172800 -# 开启 gtid -gtid-mode = ON -enforce-gtid-consistency = TRUE -# 指定 relay-log 存储位置 -relay-log = /var/lib/mysql-bin/slave -# relay-log 更新计入 binlog -log-slave-updates = TRUE - -# 多线程执行从库日志(可选) -slave-parallel-workers = 2 -slave-parallel-type = LOGICAL_CLOCK -slave-preserve-commit-order = ON - -# 存储引擎只能用 InnoDB -disabled-storage-engines = "MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY" -# 加载插件,克隆插件用于快速 state transfer -plugin-load-add = "group_replication.so;mysql_clone.so" -# 集群 uuid -group-replication-group-name = "aaaa1111-bbbb-2222-cccc-3333dddd4444" - -# mysql_11(选择一个) -group-replication-local-address = "192.168.1.11:33061" -# mysql_22(选择一个) -group-replication-local-address = "192.168.1.22:33061" -# mysql_33(选择一个) -group-replication-local-address = "192.168.1.33:33061" - -# 种子节点 -group-replication-group-seeds = "192.168.1.11:33061,192.168.1.22:33061,192.168.1.33:33061" -# 新主库在执行完自己的从库日志后,再处理用户的写请求 -group-replication-consistency = BEFORE_ON_PRIMARY_FAILOVER -# 启动时,不自动创建/初始化新集群 -group-replication-bootstrap-group = OFF -# 新节点启动时,先不启动组复制,待手动配置完成并确认正常后,再把 OFF 改成 ON -group-replication-start-on-boot = OFF - -# 怀疑某节点不可用,2秒内,如果该嫌疑节点依旧无响应,则开除它(可选) -group-replication-member-expel-timeout = 2 -# 2秒内,依旧连接不上主网(majority),则退出组复制,进入 ERROR 状态(可选) -group-replication-unreachable-majority-timeout = 2 -# 退出组复制后,不再尝试重新加入组复制,直接执行指定的退出动作(默认) -group-replication-autorejoin-tries = 0 -# 指定退出动作: 数据库设置超级只读并关闭客户端连接(推荐) -group-replication-exit-state-action = OFFLINE_MODE -``` + ``` + # mysql_11(选择一个) + server-id = 11 + # mysql_22(选择一个) + server-id = 22 + # mysql_33(选择一个) + server-id = 33 + + # 开启 binlog + log-bin = /var/log/mysql-bin/master + binlog-format = ROW + # 关闭 binlog 校验 + binlog-checksum = NONE + # 保留 2 天的 binlog + binlog-expire-logs-seconds = 172800 + # 开启 gtid + gtid-mode = ON + enforce-gtid-consistency = TRUE + # 指定 relay-log 存储位置 + relay-log = /var/lib/mysql-bin/slave + # relay-log 更新计入 binlog + log-slave-updates = TRUE + + # 多线程执行从库日志(可选) + slave-parallel-workers = 2 + slave-parallel-type = LOGICAL_CLOCK + slave-preserve-commit-order = ON + + # 存储引擎只能用 InnoDB + disabled-storage-engines = "MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY" + # 加载插件,克隆插件用于快速 state transfer + plugin-load-add = "group_replication.so;mysql_clone.so" + # 集群 uuid + group-replication-group-name = "aaaa1111-bbbb-2222-cccc-3333dddd4444" + + # mysql_11(选择一个) + group-replication-local-address = "192.168.1.11:33061" + # mysql_22(选择一个) + group-replication-local-address = "192.168.1.22:33061" + # mysql_33(选择一个) + group-replication-local-address = "192.168.1.33:33061" + + # 种子节点 + group-replication-group-seeds = "192.168.1.11:33061,192.168.1.22:33061,192.168.1.33:33061" + # 新主库在执行完自己的从库日志后,再处理用户的写请求 + group-replication-consistency = BEFORE_ON_PRIMARY_FAILOVER + # 启动时,不自动创建/初始化新集群 + group-replication-bootstrap-group = OFF + # 新节点启动时,先不启动组复制,待手动配置完成并确认正常后,再把 OFF 改成 ON + group-replication-start-on-boot = OFF + + # 怀疑某节点不可用,2秒内,如果该嫌疑节点依旧无响应,则开除它(可选) + group-replication-member-expel-timeout = 2 + # 2秒内,依旧连接不上主网(majority),则退出组复制,进入 ERROR 状态(可选) + group-replication-unreachable-majority-timeout = 2 + # 退出组复制后,不再尝试重新加入组复制,直接执行指定的退出动作(默认) + group-replication-autorejoin-tries = 0 + # 指定退出动作: 数据库设置超级只读并关闭客户端连接(推荐) + group-replication-exit-state-action = OFFLINE_MODE + ``` # 初始化集群 - 重新启动节点 mysql_11 ```bash systemctl restart mysqld ``` + - 创建同步用户 ```sql SET SQL_LOG_BIN = 0; @@ -92,6 +93,7 @@ group-replication-exit-state-action = OFFLINE_MODE FLUSH PRIVILEGES; SET SQL_LOG_BIN = 1; ``` + - 配置同步信息 ```sql CHANGE MASTER TO @@ -99,16 +101,19 @@ group-replication-exit-state-action = OFFLINE_MODE MASTER_PASSWORD='password' FOR CHANNEL 'group_replication_recovery'; ``` + - 启动集群 ```sql SET GLOBAL group_replication_bootstrap_group=ON; START GROUP_REPLICATION; SET GLOBAL group_replication_bootstrap_group=OFF; ``` + - 查看集群成员(只有一个) ```sql SELECT * FROM performance_schema.replication_group_members; ``` + - 修改 my.cnf,配置 group-replication-start-on-boot = ON # 增加节点 @@ -116,6 +121,7 @@ group-replication-exit-state-action = OFFLINE_MODE ```bash systemctl restart mysql_22 ``` + - 创建同步用户,与 mysql_11 相同 ```sql SET SQL_LOG_BIN = 0; @@ -125,6 +131,7 @@ group-replication-exit-state-action = OFFLINE_MODE FLUSH PRIVILEGES; SET SQL_LOG_BIN = 1; ``` + - 配置同步信息 ```sql CHANGE MASTER TO @@ -132,15 +139,18 @@ group-replication-exit-state-action = OFFLINE_MODE MASTER_PASSWORD='password' FOR CHANNEL 'group_replication_recovery'; ``` + - 启动组复制 ```sql START GROUP_REPLICATION; ``` + - 在 mysql_33 上重复 mysql_22 的步骤 - 查看集群成员(有三个) ```sql SELECT * FROM performance_schema.replication_group_members; ``` + - 修改 mysql_22 和 mysql_33 的 my.cnf,配置 group-replication-start-on-boot = ON # 注意 diff --git a/content/post/mysql-replication.md b/content/post/mysql-replication.md index a0cdd97..7912ef1 100644 --- a/content/post/mysql-replication.md +++ b/content/post/mysql-replication.md @@ -12,186 +12,186 @@ categories: ["database"] - 要复制的数据库有 data_db、conf_db # 在主服务器上创建用于备份的用户 replicator -```sql -grant replication slave on *.* to 'replicator'@'192.168.1.6' identified by 'password'; -flush privileges; -``` + ```sql + grant replication slave on *.* to 'replicator'@'192.168.1.6' identified by 'password'; + flush privileges; + ``` # 在主服务器上修改 my.cnf -``` -# 建议与本机ip地址最后一位一致,与其他互备服务器均不一致 -server-id = 10 -read-only = 0 - -# 开启 binlog -log-bin = /var/log/mysql-bin/master -binlog-format = row -#关注要复制的数据库,存在跨库问题 -binlog-do-db = data-db -binlog-do-db = conf-db -#忽略的数据库,存在跨库问题 -#binlog-ignore-db = -#binlog 有效时间 -expire-logs-days = -#GTID 复制模式 -#gtid-mode = ON -#enforce-gtid-consistency=true -#双主或多主互备时,会用到以下配置 -#自增主键初始值,与其他互备服务器一致 -#auto-increment-offset = -#自增主键等差值,与其他互备服务器均不一致 -#auto-increment-increment = -``` + ``` + # 建议与本机ip地址最后一位一致,与其他互备服务器均不一致 + server-id = 10 + read-only = 0 + + # 开启 binlog + log-bin = /var/log/mysql-bin/master + binlog-format = row + # 关注要复制的数据库,存在跨库问题 + binlog-do-db = data-db + binlog-do-db = conf-db + # 忽略的数据库,存在跨库问题 + #binlog-ignore-db = + #binlog 有效时间 + expire-logs-days = + # GTID 复制模式 + #gtid-mode = ON + #enforce-gtid-consistency=true + # 双主或多主互备时,会用到以下配置 + # 自增主键初始值,与其他互备服务器一致 + #auto-increment-offset = + # 自增主键等差值,与其他互备服务器均不一致 + #auto-increment-increment = + ``` # 在主服务器上重启 mysql,获取 master 状态 -```sql --- 如果 mysql 是全新安装,则无须导出数据库初态,直接查看 binlog pos 即可 --- 锁定要导出的数据库表 -flush tables with read lock; -``` + ```sql + -- 如果 mysql 是全新安装,则无须导出数据库初态,直接查看 binlog pos 即可 + -- 锁定要导出的数据库表 + flush tables with read lock; + ``` # 导出数据库初态 -```bash -#在主服务器的另一个终端中运行 -mysqldump -uroot -p data_db > /tmp/data_db.sql -mysqldump -uroot -p conf_db > /tmp/conf_db.sql -#复制到从服务器上 -scp /tmp/data_db.sql /tmp/conf_db.sql 192.168.1.6:/tmp/ -``` + ```bash + # 在主服务器的另一个终端中运行 + mysqldump -uroot -p data_db > /tmp/data_db.sql + mysqldump -uroot -p conf_db > /tmp/conf_db.sql + # 复制到从服务器上 + scp /tmp/data_db.sql /tmp/conf_db.sql 192.168.1.6:/tmp/ + ``` # 查看 binary 日志位置 -```sql -show master status\G --- 记住输出里的如下类似两行(不记录也可以,这两个信息已经写入了导出的sql文件中) --- File: mysql-bin.000001 --- Position: 137103822 --- 解锁数据库表 -unlock tables; -``` + ```sql + show master status\G + -- 记住输出里的如下类似两行(不记录也可以,这两个信息已经写入了导出的sql文件中) + -- File: mysql-bin.000001 + -- Position: 137103822 + -- 解锁数据库表 + unlock tables; + ``` # 在从服务器上编辑 my.cnf -``` -# 建议与本机ip地址最后一位一致,与其他互备服务器均不一致 -server-id = 6 -read-only = 1 - -# 如果该 slave 中也运行了 master,或者使用了 gtid 模式复制,则开启 binlog -#log-bin = mysql-bin -#binlog-format = row -# 把 slave 操作也计入 binlog,用于链式同步 -#log-slave-updates = ON -# 指定要复制的数据库,存在跨库问题 -#replicate-do-db = data_db -#replicate-do-db = conf_db -# 指定要复制的数据表,无跨库问题 -replicate-do-table = db1.t1 -replicate-wild-do-table = db1.% -# 忽略的数据库,存在跨库问题 -#replicate-ignore-db = -# 忽略的数据表,无跨库问题 -#replicate-ignore-table = db1.t1 -#replicate-wild-ignore-table = db1.% -# 中继日志 -relay-log = /var/lib/mysql-bin/slave -# 多线程复制 -slave-parallel-type = logical-clock -slave-parallel-workers = 4 -# GTID 模式 -#gtid-mode = ON -#enforce-gtid-consistency=true -# 双主或多主互备时,会用到以下配置 -# 自增主键初始值,与其他互备服务器一致 -#auto-increment-offset = -# 自增主键等差值,与其他互备服务器均不一致 -#auto-increment-increment = -``` + ``` + # 建议与本机ip地址最后一位一致,与其他互备服务器均不一致 + server-id = 6 + read-only = 1 + + # 如果该 slave 中也运行了 master,或者使用了 gtid 模式复制,则开启 binlog + #log-bin = mysql-bin + #binlog-format = row + # 把 slave 操作也计入 binlog,用于链式同步 + #log-slave-updates = ON + # 指定要复制的数据库,存在跨库问题 + #replicate-do-db = data_db + #replicate-do-db = conf_db + # 指定要复制的数据表,无跨库问题 + replicate-do-table = db1.t1 + replicate-wild-do-table = db1.% + # 忽略的数据库,存在跨库问题 + #replicate-ignore-db = + # 忽略的数据表,无跨库问题 + #replicate-ignore-table = db1.t1 + #replicate-wild-ignore-table = db1.% + # 中继日志 + relay-log = /var/lib/mysql-bin/slave + # 多线程复制 + slave-parallel-type = logical-clock + slave-parallel-workers = 4 + # GTID 模式 + #gtid-mode = ON + #enforce-gtid-consistency=true + # 双主或多主互备时,会用到以下配置 + # 自增主键初始值,与其他互备服务器一致 + #auto-increment-offset = + # 自增主键等差值,与其他互备服务器均不一致 + #auto-increment-increment = + ``` # 在从服务器上重启 mysql,导入初态 -```sql --- 创建要导入的数据库 -create database data_db default charset utf8mb4; -create database conf_db default charset utf8mb4; -``` + ```sql + -- 创建要导入的数据库 + create database data_db default charset utf8mb4; + create database conf_db default charset utf8mb4; + ``` # 导入数据库 -```bash -msyql -uroot -p data_db < /tmp/data_db.sql -mysql -uroot -p conf_db < /tmp/conf_db.sql -``` + ```bash + msyql -uroot -p data_db < /tmp/data_db.sql + mysql -uroot -p conf_db < /tmp/conf_db.sql + ``` # 开启同步 -```sql --- 基于 binlog 文件位置复制 -change master to master_host = '192.168.1.10', - master_port = 3306, - master_user = 'replicator', - master_password = 'password', - master_log_file = 'mysql-bin.000001', - master_log_pos = 137103822; -flush privileges; --- 基于 gtid 复制 -change master to master_host = '192.168.1.10', - master_port = 3306, - master_user = 'replicator', - master_password = 'password', - master_auto_position = 1; -``` + ```sql + -- 基于 binlog 文件位置复制 + change master to master_host = '192.168.1.10', + master_port = 3306, + master_user = 'replicator', + master_password = 'password', + master_log_file = 'mysql-bin.000001', + master_log_pos = 137103822; + flush privileges; + -- 基于 gtid 复制 + change master to master_host = '192.168.1.10', + master_port = 3306, + master_user = 'replicator', + master_password = 'password', + master_auto_position = 1; + ``` # 启动 slave,查看 slave 状态 -```sql -start slave; --- 在从服务器上查看 slave 状态 -show slave status\G --- 如果看到 --- Slave_IO_Running: Yes --- Slave_SQL_Running: Yes --- 则表示 slave 开启成功! -``` + ```sql + start slave; + -- 在从服务器上查看 slave 状态 + show slave status\G + -- 如果看到 + -- Slave_IO_Running: Yes + -- Slave_SQL_Running: Yes + -- 则表示 slave 开启成功! + ``` # MySQL8 gtid 互为主从配置 -``` -[mysqld] -# ---- 固定配置 ---- -datadir = /var/lib/mysql -socket = /var/lib/mysql/mysql.sock -pid-file = /var/lib/mysql/mysql.pid -log-timestamps = SYSTEM -log-error = /var/log/mysql/error.log -slow-query-log = TRUE -slow-query-log-file = /var/log/mysql/slow.log -default-authentication-plugin = mysql_native_password - -# ---- 动态配置 ---- -mysqlx = OFF -character-set-server = utf8mb4 -default-storage-engine = innodb -lower-case-table-names = 1 -#skip-name-resolve = 1 -#max-user-connections = 600 -#innodb-buffer-pool-size = 8G -#innodb-buffer-pool-instances = 8 - -# master -# 确认不同节点该 id 唯一 -server-id = 1 -log-bin = /var/lib/mysql-bin/master -binlog-format = ROW -#binlog-do-db = db1 -binlog-expire-logs-seconds = 172800 -gtid-mode = ON -enforce-gtid-consistency = TRUE - -# slave -replicate-wild-ignore-table = information_schema.% -replicate-wild-ignore-table = mysql.% -replicate-wild-ignore-table = performance_schema.% -replicate-wild-ignore-table = sys.% -slave-parallel-workers = 2 -log-slave-updates = FALSE -relay-log = /var/lib/mysql-bin/slave -relay-log-recovery = TRUE -#read-only = ON -``` + ``` + [mysqld] + # ---- 固定配置 ---- + datadir = /var/lib/mysql + socket = /var/lib/mysql/mysql.sock + pid-file = /var/lib/mysql/mysql.pid + log-timestamps = SYSTEM + log-error = /var/log/mysql/error.log + slow-query-log = TRUE + slow-query-log-file = /var/log/mysql/slow.log + default-authentication-plugin = mysql_native_password + + # ---- 动态配置 ---- + mysqlx = OFF + character-set-server = utf8mb4 + default-storage-engine = innodb + lower-case-table-names = 1 + #skip-name-resolve = 1 + #max-user-connections = 600 + #innodb-buffer-pool-size = 8G + #innodb-buffer-pool-instances = 8 + + # master + # 确认不同节点该 id 唯一 + server-id = 1 + log-bin = /var/lib/mysql-bin/master + binlog-format = ROW + #binlog-do-db = db1 + binlog-expire-logs-seconds = 172800 + gtid-mode = ON + enforce-gtid-consistency = TRUE + + # slave + replicate-wild-ignore-table = information_schema.% + replicate-wild-ignore-table = mysql.% + replicate-wild-ignore-table = performance_schema.% + replicate-wild-ignore-table = sys.% + slave-parallel-workers = 2 + log-slave-updates = FALSE + relay-log = /var/lib/mysql-bin/slave + relay-log-recovery = TRUE + #read-only = ON + ``` # MySQL8 gtid 多源复制从库配置 - 修改 my.cnf @@ -240,21 +240,25 @@ relay-log-recovery = TRUE master_info_repository = table relay_log_info_repository = table ``` + - 导出主库数据 ```bash mysqldump -uroot -h<主库1> -p --single-transaction --set-gtid-purged=on --databases db1 > 1_db1.sql mysqldump -uroot -h<主库2> -p --single-transaction --set-gtid-purged=on --databases db2 > 2_db2.sql ``` + - 在导出的文件(1_db1.sql,2_db2.sql)中找到 "SET @@GLOBAL.gtid_purged ..." 语句,记录下来,并在该文件中删除 - 导入 1_db1.sql 和 2_db2.sql ```bash mysql -uroot -p < 1_db1.sql mysql -uroot -p < 2_db2.sql ``` + - 合并这两个 "SET @@GLOBAL.gtid_purged ..." 语句(gtid set 做并集),导入 gtid set 并集 ```sql set @@global.gtid_purged = '' ``` + - 加入两个主库的同步配置 ```sql change master to master_host='<主库1>', @@ -268,16 +272,19 @@ relay-log-recovery = TRUE master_password='<主库上的 replication 账户的密码>', master_auto_position=1 for channel ''; ``` + - 启动从库 ```sql start slave for channel ''; start slave for channel ''; ``` + - 查看从库 ```sql show slave status for channel ''\G show slave status for channel ''\G ``` + - 停止从库 ```sql -- 停止全部 slave @@ -285,6 +292,7 @@ relay-log-recovery = TRUE -- 停止指定 slave stop slave for channel '...'; ``` + - 重置从库 ```sql -- 重置全部 slave @@ -292,5 +300,6 @@ relay-log-recovery = TRUE -- 重置指定 slave reset slave for channel '...'; ``` + - 监控表: performance_schema.replication_connection_status diff --git a/content/post/mysql.md b/content/post/mysql.md index 1e047f6..ff06b43 100644 --- a/content/post/mysql.md +++ b/content/post/mysql.md @@ -7,78 +7,80 @@ categories: ["database"] --- # MySQL 5.7 配置文件 my.cnf -``` -[mysqld] -datadir = /db/mysql -socket = /var/lib/mysql/mysql.sock -symbolic-links = 0 -log-timestamps = SYSTEM -slow-query-log = 1 -slow-query-log-file = /var/log/mysqld/slow.log -long-query-time = 8 -#log-queries-not-using-indexes = 1 -log-error = /var/log/mysqld/error.log -pid-file = /var/run/mysqld/mysqld.pid -max-connections = 1000 -max-connect-errors = 1000 -max-user-connections = 600 -interactive-timeout = 3600 -wait-timeout = 3600 -skip-name-resolve = 1 -lower-case-table-names = 1 -default-time-zone = '+08:00' -character-set-server = utf8mb4 -sql-mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES -bind-address = 0.0.0.0 -table-open-cache = 2048 -default-storage-engine = innodb -innodb-autoinc-lock-mode = 2 -innodb-flush-log-at-trx-commit = 0 -# 建议物理内存一半 -innodb-buffer-pool-size = 8G -innodb-buffer-pool-instances = 8 -max-allowed-packet = 512M -query-cache-size = 0 -query-cache-type = 0 -# 建议点分 ip 的最后一个数字 -server-id = 123 -# bin log -#binlog-format = ROW -#log-bin = /var/lib/mysql/mysql-bin -#expire-logs-days = 3 -# relay log -#read-only = 1 -#replicate-wild-do-table = db1.% -#relay-log = /var/lib/mysql/mysql-relay-bin -#slave-parallel-type = logical-clock -``` + ``` + [mysqld] + datadir = /db/mysql + socket = /var/lib/mysql/mysql.sock + symbolic-links = 0 + log-timestamps = SYSTEM + slow-query-log = 1 + slow-query-log-file = /var/log/mysqld/slow.log + long-query-time = 8 + #log-queries-not-using-indexes = 1 + log-error = /var/log/mysqld/error.log + pid-file = /var/run/mysqld/mysqld.pid + max-connections = 1000 + max-connect-errors = 1000 + max-user-connections = 600 + interactive-timeout = 3600 + wait-timeout = 3600 + skip-name-resolve = 1 + lower-case-table-names = 1 + default-time-zone = '+08:00' + character-set-server = utf8mb4 + sql-mode = NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES + bind-address = 0.0.0.0 + table-open-cache = 2048 + default-storage-engine = innodb + innodb-autoinc-lock-mode = 2 + innodb-flush-log-at-trx-commit = 0 + # 建议物理内存一半 + innodb-buffer-pool-size = 8G + innodb-buffer-pool-instances = 8 + max-allowed-packet = 512M + query-cache-size = 0 + query-cache-type = 0 + # 建议点分 ip 的最后一个数字 + server-id = 123 + # bin log + #binlog-format = ROW + #log-bin = /var/lib/mysql/mysql-bin + #expire-logs-days = 3 + # relay log + #read-only = 1 + #replicate-wild-do-table = db1.% + #relay-log = /var/lib/mysql/mysql-relay-bin + #slave-parallel-type = logical-clock + ``` # 复制表结构 -```sql -create table db1.t1 like db2.t2; -create table db1.t1 select db2.t2 where 1=2; -``` + ```sql + create table db1.t1 like db2.t2; + create table db1.t1 select db2.t2 where 1=2; + ``` # 复制表结构及其数据 -```sql -create table db1.t1 select db2.t2 [where ...] -``` + ```sql + create table db1.t1 select db2.t2 [where ...] + ``` # 复制表数据 -``` -insert into db2.t2(column1, column2 ...) - select column1, column2 ... from db1.t1 [where ...] -``` + ``` + insert into db2.t2(column1, column2 ...) + select column1, column2 ... from db1.t1 [where ...] + ``` # 通过复制表文件来复制表数据 - 在db2中创建同结构表 ```sql create table db2.t1 like db1.t1; ``` + - 丢弃表空间 ```sql alter table db2.t1 discard tablespace; ``` + - 复制 t1 的表数据文件 ```bash #关闭数据库 @@ -89,51 +91,52 @@ insert into db2.t2(column1, column2 ...) #启动数据库 systemctl start mysqld ``` + - 导入表空间 ```sql alter table db2.t1 import tablespace; ``` # 设置一个表的空列自增 -```sql --- 删除可能存在的主键 -alter table 表名 drop primary key; -alter table 表名 modify 列名 auto_increment primary key; -``` + ```sql + -- 删除可能存在的主键 + alter table 表名 drop primary key; + alter table 表名 modify 列名 auto_increment primary key; + ``` # 查看数据库中每个表的全部列名 -```sql -select table_name, column_name from - information_schema.columns - where table_schema = '数据库名'; -``` + ```sql + select table_name, column_name from + information_schema.columns + where table_schema = '数据库名'; + ``` # 查看数据库中每个表的行数 -```sql -select table_name, table_rows - from information_schema.tables - where table_schema = '数据库名'; -``` + ```sql + select table_name, table_rows + from information_schema.tables + where table_schema = '数据库名'; + ``` # 查看数据库中每个表的索引 -```sql -select table_name, column_name, index_name - from INFORMATION_SCHEMA.STATISTICS - where table_schema = '数据库名'; -``` + ```sql + select table_name, column_name, index_name + from INFORMATION_SCHEMA.STATISTICS + where table_schema = '数据库名'; + ``` # 表的部分列数据到另一个表 -```sql -update db2.t2(column1, column2 ...) = ( - select column1, column2 from db1.t1 - where db1.t1.id = db2.t2.id); -``` + ```sql + update db2.t2(column1, column2 ...) = ( + select column1, column2 from db1.t1 + where db1.t1.id = db2.t2.id); + ``` # 把语句执行结果写到文件 -```bash -mysql -uroot -p -hsever_ip -Ddb_name - -Ne "select ... from table_name;" > file_name -``` + ```bash + mysql -uroot -p -hsever_ip -Ddb_name + -Ne "select ... from table_name;" > file_name + ``` # 表分区 - 查看表的分区情况 @@ -142,27 +145,32 @@ mysql -uroot -p -hsever_ip -Ddb_name from information_schema.partitions where table_name = 'table_name'; ``` + - 建表时指定 ```sql create table table_name(...) partition by range columns(column_name) (partition part_name values less than(some_value)); ``` + - 修改成分区表 ```sql alter table table_name partition by range(column_name) (partition part_name values less than(som_value)); ``` + - 增加分区 ```sql alter table table_name add partition (partition part_name values less than(som_value)); ``` + - 删除分区 ```sql alter table table_name drop partition part_name; ``` + - 合并/拆分分区 ```sql alter table table_name @@ -170,26 +178,31 @@ mysql -uroot -p -hsever_ip -Ddb_name (partition part_new_1 values less than(value_1), partition part_new_2 values less than(value_2)); ``` + - 重建分区,整理分区碎片 ```sql alter table table_name rebuild partition part_name_1, part_name_2; ``` + - 优化分区,回收空间,整理碎片 ```sql alter table table_name optimize partition part_name_1, part_name_2; ``` + - 分析分区,读取并保存分区的健分布 ```sql alter table table_name analyze partition part_name_1, part_name_2; ``` + - 修复分区 ```sql alter table table_name repair partition part_name_1, part_name_2; ``` + - 检查分区 ```sql alter table table_name @@ -197,59 +210,61 @@ mysql -uroot -p -hsever_ip -Ddb_name ``` # MySQL 5.7 从库多线程同步 -```sql -stop slave; -set global slave_parallel_type='logical_clock'; -set global slave_parallel_workers=4; -start slave; -show processlist; -``` + ```sql + stop slave; + set global slave_parallel_type='logical_clock'; + set global slave_parallel_workers=4; + start slave; + show processlist; + ``` # MySQL 5.7 提示密码复杂度不够 -```sql -set global validate_password_policy=0; -``` + ```sql + set global validate_password_policy=0; + ``` # MySQL 5.7 从库复制失败跳过指定数量的事务 -```sql -stop slave; --- 跳过一个事务 -SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; -start slave; --- 修改 my.cnf -slave-skip-errors=1062,1053,1146,1032 #跳过指定error no类型的错误 -slave-skip-errors=all #跳过所有错误 -``` + ```sql + stop slave; + -- 跳过一个事务 + SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; + start slave; + -- 修改 my.cnf + slave-skip-errors=1062,1053,1146,1032 #跳过指定error no类型的错误 + slave-skip-errors=all #跳过所有错误 + ``` # MySQL 5.7 查看全部任务 -```sql --- 分号换成 \G 显示完整 sql -show processlist; -show full processlist; -SELECT command FROM information_schema.processlist; -``` + ```sql + -- 分号换成 \G 显示完整 sql + show processlist; + show full processlist; + SELECT command FROM information_schema.processlist; + ``` # MySQL 5.7 ssl 连接 -``` ---ssl-mode=REQUIRED -``` + ``` + --ssl-mode=REQUIRED + ``` # MariaDB 10.1 修改密码 -```sql -UPDATE user SET password=password('newpassword') WHERE user='root'; -``` + ```sql + UPDATE user SET password=password('newpassword') WHERE user='root'; + ``` # MySQL 5.7 编码 - 查看 ```sql SHOW VARIABLES LIKE 'character_set%'; ``` + - 数据库连接参数中,characterEncoding=utf8 会被自动识别为 utf8mb4,但是 autoReconnect=true 必须指定 - 更改数据库编码 ```sql ALTER DATABASE db_name CHARSET UTF8MB4 COLLATE UTF8MB4_GENERAL_CI; ``` + - 更改表编码 ```sql ALTER TABLE table_name @@ -257,24 +272,27 @@ UPDATE user SET password=password('newpassword') WHERE user='root'; ``` # MySQL 5.7 升级数据库管理表结构 -```bash -mysql_upgrade -u root -p -``` + ```bash + mysql_upgrade -u root -p + ``` # MySQL 5.7 误删 root 后恢复 root 账户 - 停止 mysql 服务 ```bash systemctl stop mysqld ``` + - 修改 my.cnf ``` # 添加如下一行 skip-grant-tables ``` + - 启动 mysql 服务 ```bash systemctl start mysqld ``` + - 重建 root 账户,并授权 ```sql insert into user @@ -317,15 +335,18 @@ mysql_upgrade -u root -p where user='root'; flush privileges; ``` + - 停止 mysql 服务 ```bash systemctl stop mysqld ``` + - 修改 my.cnf ``` - # 删除刚添加的如下一行 - #skip-grant-tables + # 删除或注释刚添加的如下一行 + skip-grant-tables ``` + - 启动 mysql 服务,root 账户正常可用 ```bash systemctl start mysqld @@ -336,6 +357,7 @@ mysql_upgrade -u root -p ```sql explain sql ``` + - select_type 查询类型 - SIMPLE 简单表,没有表连接或子查询 - PRIMARY 最外层的查询 @@ -363,10 +385,10 @@ mysql_upgrade -u root -p - Using Flesort 依靠索引顺序达不到排序效果,需额外排序 # 统计 insert、delete、update 和 select 次数 -```sql -show global status where Variable_name in - ('com_insert', 'com_delete', 'com_update', 'com_select'); -``` + ```sql + show global status where Variable_name in + ('com_insert', 'com_delete', 'com_update', 'com_select'); + ``` # csv 文件 - 导出 @@ -386,6 +408,7 @@ show global status where Variable_name in escaped by '\\' lines terminated by '\n'; ``` + - 导入 ``` # Shell 终端 diff --git a/content/post/mysql5.7-install.md b/content/post/mysql5.7-install.md index f04577d..b1367e2 100644 --- a/content/post/mysql5.7-install.md +++ b/content/post/mysql5.7-install.md @@ -11,47 +11,48 @@ categories: ["database"] - MySQL 5.7.20 # 下载 mysql 源安装包 -```bash -#repo 地址: https://repo.mysql.com/ -cd /root/ -curl -O https://repo.mysql.com/mysql57-community-release-el7.rpm -``` + ```bash + # repo 地址: https://repo.mysql.com/ + cd /root/ + curl -O https://repo.mysql.com/mysql57-community-release-el7.rpm + ``` # 安装 mysql 源 -```bash -rpm -ivh /root/mysql57-community-release-el7.rpm -``` + ```bash + rpm -ivh /root/mysql57-community-release-el7.rpm + ``` # 更新 yum 缓存 -```bash -yum clean all -yum makecache fast -``` + ```bash + yum clean all + yum makecache fast + ``` # 安装 mysql -```bash -yum install mysql-community-server -``` + ```bash + yum install mysql-community-server + ``` # 启动 mysql -```bash -systemctl start mysqld -``` + ```bash + systemctl start mysqld + ``` # 查找 mysql 默认密码 -```bash -grep 'temporary password' /var/log/mysqld.log -mysql -uroot -p -# 输入查找到的密码 -``` + ```bash + grep 'temporary password' /var/log/mysqld.log + mysql -uroot -p + # 输入查找到的密码 + ``` # 修改 mysql 本地密码 - 在 mysql 下修改 -```sql -mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'Pass-1234'; -``` -- 或者直接在终端修改 -```bash -mysqladmin -uroot -p password 'Pass-1234' -``` + ```sql + mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'Pass-1234'; + ``` + +- 或者直接在终端修改 + ```bash + mysqladmin -uroot -p password 'Pass-1234' + ``` diff --git a/content/post/openvpn.md b/content/post/openvpn.md index 75d0076..934e6c7 100644 --- a/content/post/openvpn.md +++ b/content/post/openvpn.md @@ -8,299 +8,299 @@ categories: ["network"] --- # 服务端配置文件 server.conf -``` -################################################# -# 针对多客户端的OpenVPN 2.0 的服务器端配置文件示例 -# -# 本文件用于多客户端<->单服务器端的OpenVPN服务器端配置 -# -# OpenVPN也支持单机<->单机的配置(更多信息请查看网站上的示例页面) -# -# 该配置支持Windows或者Linux/BSD系统。此外,在Windows上,记得将路径加上双引号, -# 并且使用两个反斜杠,例如:"C:\\Program Files\\OpenVPN\\config\\foo.key" -# -# '#' or ';'开头的均为注释内容 -################################################# - -#OpenVPN应该监听本机的哪些IP地址? -#该命令是可选的,如果不设置,则默认监听本机的所有IP地址。 -;local a.b.c.d - -# OpenVPN应该监听哪个TCP/UDP端口? -# 如果你想在同一台计算机上运行多个OpenVPN实例,你可以使用不同的端口号来区分它们。 -# 此外,你需要在防火墙上开放这些端口。 -port 1194 - -#OpenVPN使用TCP还是UDP协议? -;proto tcp -proto udp - -# 指定OpenVPN创建的通信隧道类型。 -# "dev tun"将会创建一个路由IP隧道, -# "dev tap"将会创建一个以太网隧道。 -# -# 如果你是以太网桥接模式,并且提前创建了一个名为"tap0"的与以太网接口进行桥接的虚拟接口,则你可以使用"dev tap0" -# -# 如果你想控制VPN的访问策略,你必须为TUN/TAP接口创建防火墙规则。 -# -# 在非Windows系统中,你可以给出明确的单位编号(unit number),例如"tun0"。 -# 在Windows中,你也可以使用"dev-node"。 -# 在多数系统中,除非你部分禁用或者完全禁用了TUN/TAP接口的防火墙,否则VPN将不起作用。 -;dev tap -dev tun - -# 如果你想配置多个隧道,你需要用到网络连接面板中TAP-Win32适配器的名称(例如"MyTap")。 -# 在XP SP2或更高版本的系统中,你可能需要有选择地禁用掉针对TAP适配器的防火墙 -# 通常情况下,非Windows系统则不需要该指令。 -;dev-node MyTap - -# 设置SSL/TLS根证书(ca)、证书(cert)和私钥(key)。 -# 每个客户端和服务器端都需要它们各自的证书和私钥文件。 -# 服务器端和所有的客户端都将使用相同的CA证书文件。 -# -# 通过easy-rsa目录下的一系列脚本可以生成所需的证书和私钥。 -# 记住,服务器端和每个客户端的证书必须使用唯一的Common Name。 -# -# 你也可以使用遵循X509标准的任何密钥管理系统来生成证书和私钥。 -# OpenVPN 也支持使用一个PKCS #12格式的密钥文件(详情查看站点手册页面的"pkcs12"指令) -ca ca.crt -cert server.crt -key server.key # 该文件应该保密 - -# 指定迪菲·赫尔曼参数。 -# 你可以使用如下名称命令生成你的参数: -# openssl dhparam -out dh1024.pem 1024 -# 如果你使用的是2048位密钥,使用2048替换其中的1024。 -dh dh1024.pem - -# 设置服务器端模式,并提供一个VPN子网,以便于从中为客户端分配IP地址。 -# 在此处的示例中,服务器端自身将占用10.8.0.1,其他的将提供客户端使用。 -# 如果你使用的是以太网桥接模式,请注释掉该行。更多信息请查看官方手册页面。 -server 10.8.0.0 255.255.255.0 - -# 指定用于记录客户端和虚拟IP地址的关联关系的文件。 -# 当重启OpenVPN时,再次连接的客户端将分配到与上一次分配相同的虚拟IP地址 -ifconfig-pool-persist ipp.txt - -# 该指令仅针对以太网桥接模式。 -# 首先,你必须使用操作系统的桥接能力将以太网网卡接口和TAP接口进行桥接。 -# 然后,你需要手动设置桥接接口的IP地址、子网掩码; -# 在这里,我们假设为10.8.0.4和255.255.255.0。 -# 最后,我们必须指定子网的一个IP范围(例如从10.8.0.50开始,到10.8.0.100结束),以便于分配给连接的客户端。 -# 如果你不是以太网桥接模式,直接注释掉这行指令即可。 -;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100 - -# 该指令仅针对使用DHCP代理的以太网桥接模式, -# 此时客户端将请求服务器端的DHCP服务器,从而获得分配给它的IP地址和DNS服务器地址。 -# -# 在此之前,你也需要先将以太网网卡接口和TAP接口进行桥接。 -# 注意:该指令仅用于OpenVPN客户端,并且该客户端的TAP适配器需要绑定到一个DHCP客户端上。 -;server-bridge - -# 推送路由信息到客户端,以允许客户端能够连接到服务器背后的其他私有子网。 -# (简而言之,就是允许客户端访问VPN服务器自身所在的其他局域网) -# 记住,这些私有子网也要将OpenVPN客户端的地址池(10.8.0.0/255.255.255.0)反馈回OpenVPN服务器。 -;push "route 192.168.10.0 255.255.255.0" -;push "route 192.168.20.0 255.255.255.0" - -# 为指定的客户端分配指定的IP地址,或者客户端背后也有一个私有子网想要访问VPN, -# 那么你可以针对该客户端的配置文件使用ccd子目录。 -# (简而言之,就是允许客户端所在的局域网成员也能够访问VPN) - -# 举个例子:假设有个Common Name为"Thelonious"的客户端背后也有一个小型子网想要连接到VPN,该子网为192.168.40.128/255.255.255.248。 -# 首先,你需要去掉下面两行指令的注释: -;client-config-dir ccd -;route 192.168.40.128 255.255.255.248 -# 然后创建一个文件ccd/Thelonious,该文件的内容为: -# iroute 192.168.40.128 255.255.255.248 -#这样客户端所在的局域网就可以访问VPN了。 -# 注意,这个指令只能在你是基于路由、而不是基于桥接的模式下才能生效。 -# 比如,你使用了"dev tun"和"server"指令。 - -# 再举个例子:假设你想给Thelonious分配一个固定的IP地址10.9.0.1。 -# 首先,你需要去掉下面两行指令的注释: -;client-config-dir ccd -;route 10.9.0.0 255.255.255.252 -# 然后在文件ccd/Thelonious中添加如下指令: -# ifconfig-push 10.9.0.1 10.9.0.2 - -# 如果你想要为不同群组的客户端启用不同的防火墙访问策略,你可以使用如下两种方法: -# (1)运行多个OpenVPN守护进程,每个进程对应一个群组,并为每个进程(群组)启用适当的防火墙规则。 -# (2) (进阶)创建一个脚本来动态地修改响应于来自不同客户的防火墙规则。 -# 关于learn-address脚本的更多信息请参考官方手册页面。 -;learn-address ./script - -# 如果启用该指令,所有客户端的默认网关都将重定向到VPN,这将导致诸如web浏览器、DNS查询等所有客户端流量都经过VPN。 -# (为确保能正常工作,OpenVPN服务器所在计算机可能需要在TUN/TAP接口与以太网之间使用NAT或桥接技术进行连接) -;push "redirect-gateway def1 bypass-dhcp" - -# 某些具体的Windows网络设置可以被推送到客户端,例如DNS或WINS服务器地址。 -# 下列地址来自opendns.com提供的Public DNS 服务器。 -;push "dhcp-option DNS 208.67.222.222" -;push "dhcp-option DNS 208.67.220.220" - -# 去掉该指令的注释将允许不同的客户端之间相互"可见"(允许客户端之间互相访问)。 -# 默认情况下,客户端只能"看见"服务器。为了确保客户端只能看见服务器,你还可以在服务器端的TUN/TAP接口上设置适当的防火墙规则。 -;client-to-client - -# 如果多个客户端可能使用相同的证书/私钥文件或Common Name进行连接,那么你可以取消该指令的注释。 -# 建议该指令仅用于测试目的。对于生产使用环境而言,每个客户端都应该拥有自己的证书和私钥。 -# 如果你没有为每个客户端分别生成Common Name唯一的证书/私钥,你可以取消该行的注释(但不推荐这样做)。 -;duplicate-cn - -# keepalive指令将导致类似于ping命令的消息被来回发送,以便于服务器端和客户端知道对方何时被关闭。 -# 每10秒钟ping一次,如果120秒内都没有收到对方的回复,则表示远程连接已经关闭。 -keepalive 10 120 - -# 出于SSL/TLS之外更多的安全考虑,创建一个"HMAC 防火墙"可以帮助抵御DoS攻击和UDP端口淹没攻击。 -# 你可以使用以下命令来生成: -# openvpn --genkey --secret ta.key -# -# 服务器和每个客户端都需要拥有该密钥的一个拷贝。 -# 第二个参数在服务器端应该为'0',在客户端应该为'1'。 -;tls-auth ta.key 0 # 该文件应该保密 - -# 选择一个密码加密算法。 -# 该配置项也必须复制到每个客户端配置文件中。 -;cipher BF-CBC # Blowfish (默认) -;cipher AES-128-CBC # AES -;cipher DES-EDE3-CBC # Triple-DES - -# 在VPN连接上启用压缩。 -# 如果你在此处启用了该指令,那么也应该在每个客户端配置文件中启用它。 -comp-lzo - -# 允许并发连接的客户端的最大数量 -;max-clients 100 - -# 在完成初始化工作之后,降低OpenVPN守护进程的权限是个不错的主意。 -# 该指令仅限于非Windows系统中使用。 -;user nobody -;group nobody - -# 持久化选项可以尽量避免访问那些在重启之后由于用户权限降低而无法访问的某些资源。 -persist-key -persist-tun - -# 输出一个简短的状态文件,用于显示当前的连接状态,该文件每分钟都会清空并重写一次。 -status openvpn-status.log - -# 默认情况下,日志消息将写入syslog(在Windows系统中,如果以服务方式运行,日志消息将写入OpenVPN安装目录的log文件夹中)。 -# 你可以使用log或者log-append来改变这种默认情况。 -# "log"方式在每次启动时都会清空之前的日志文件。 -# "log-append"这是在之前的日志内容后进行追加。 -# 你可以使用两种方式之一(但不要同时使用)。 -;log openvpn.log -;log-append openvpn.log - -# 为日志文件设置适当的冗余级别(0~9)。冗余级别越高,输出的信息越详细。 -# -# 0 表示静默运行,只记录致命错误。 -# 4 表示合理的常规用法。 -# 5 和 6 可以帮助调试连接错误。 -# 9 表示极度冗余,输出非常详细的日志信息。 -verb 3 - -# 重复信息的沉默度。 -# 相同类别的信息只有前20条会输出到日志文件中。 -;mute 20 -``` + ``` + ################################################# + # 针对多客户端的OpenVPN 2.0 的服务器端配置文件示例 + # + # 本文件用于多客户端<->单服务器端的OpenVPN服务器端配置 + # + # OpenVPN也支持单机<->单机的配置(更多信息请查看网站上的示例页面) + # + # 该配置支持Windows或者Linux/BSD系统。此外,在Windows上,记得将路径加上双引号, + # 并且使用两个反斜杠,例如:"C:\\Program Files\\OpenVPN\\config\\foo.key" + # + # '#' or ';'开头的均为注释内容 + ################################################# + + #OpenVPN应该监听本机的哪些IP地址? + #该命令是可选的,如果不设置,则默认监听本机的所有IP地址。 + ;local a.b.c.d + + # OpenVPN应该监听哪个TCP/UDP端口? + # 如果你想在同一台计算机上运行多个OpenVPN实例,你可以使用不同的端口号来区分它们。 + # 此外,你需要在防火墙上开放这些端口。 + port 1194 + + #OpenVPN使用TCP还是UDP协议? + ;proto tcp + proto udp + + # 指定OpenVPN创建的通信隧道类型。 + # "dev tun"将会创建一个路由IP隧道, + # "dev tap"将会创建一个以太网隧道。 + # + # 如果你是以太网桥接模式,并且提前创建了一个名为"tap0"的与以太网接口进行桥接的虚拟接口,则你可以使用"dev tap0" + # + # 如果你想控制VPN的访问策略,你必须为TUN/TAP接口创建防火墙规则。 + # + # 在非Windows系统中,你可以给出明确的单位编号(unit number),例如"tun0"。 + # 在Windows中,你也可以使用"dev-node"。 + # 在多数系统中,除非你部分禁用或者完全禁用了TUN/TAP接口的防火墙,否则VPN将不起作用。 + ;dev tap + dev tun + + # 如果你想配置多个隧道,你需要用到网络连接面板中TAP-Win32适配器的名称(例如"MyTap")。 + # 在XP SP2或更高版本的系统中,你可能需要有选择地禁用掉针对TAP适配器的防火墙 + # 通常情况下,非Windows系统则不需要该指令。 + ;dev-node MyTap + + # 设置SSL/TLS根证书(ca)、证书(cert)和私钥(key)。 + # 每个客户端和服务器端都需要它们各自的证书和私钥文件。 + # 服务器端和所有的客户端都将使用相同的CA证书文件。 + # + # 通过easy-rsa目录下的一系列脚本可以生成所需的证书和私钥。 + # 记住,服务器端和每个客户端的证书必须使用唯一的Common Name。 + # + # 你也可以使用遵循X509标准的任何密钥管理系统来生成证书和私钥。 + # OpenVPN 也支持使用一个PKCS #12格式的密钥文件(详情查看站点手册页面的"pkcs12"指令) + ca ca.crt + cert server.crt + key server.key # 该文件应该保密 + + # 指定迪菲·赫尔曼参数。 + # 你可以使用如下名称命令生成你的参数: + # openssl dhparam -out dh1024.pem 1024 + # 如果你使用的是2048位密钥,使用2048替换其中的1024。 + dh dh1024.pem + + # 设置服务器端模式,并提供一个VPN子网,以便于从中为客户端分配IP地址。 + # 在此处的示例中,服务器端自身将占用10.8.0.1,其他的将提供客户端使用。 + # 如果你使用的是以太网桥接模式,请注释掉该行。更多信息请查看官方手册页面。 + server 10.8.0.0 255.255.255.0 + + # 指定用于记录客户端和虚拟IP地址的关联关系的文件。 + # 当重启OpenVPN时,再次连接的客户端将分配到与上一次分配相同的虚拟IP地址 + ifconfig-pool-persist ipp.txt + + # 该指令仅针对以太网桥接模式。 + # 首先,你必须使用操作系统的桥接能力将以太网网卡接口和TAP接口进行桥接。 + # 然后,你需要手动设置桥接接口的IP地址、子网掩码; + # 在这里,我们假设为10.8.0.4和255.255.255.0。 + # 最后,我们必须指定子网的一个IP范围(例如从10.8.0.50开始,到10.8.0.100结束),以便于分配给连接的客户端。 + # 如果你不是以太网桥接模式,直接注释掉这行指令即可。 + ;server-bridge 10.8.0.4 255.255.255.0 10.8.0.50 10.8.0.100 + + # 该指令仅针对使用DHCP代理的以太网桥接模式, + # 此时客户端将请求服务器端的DHCP服务器,从而获得分配给它的IP地址和DNS服务器地址。 + # + # 在此之前,你也需要先将以太网网卡接口和TAP接口进行桥接。 + # 注意:该指令仅用于OpenVPN客户端,并且该客户端的TAP适配器需要绑定到一个DHCP客户端上。 + ;server-bridge + + # 推送路由信息到客户端,以允许客户端能够连接到服务器背后的其他私有子网。 + # (简而言之,就是允许客户端访问VPN服务器自身所在的其他局域网) + # 记住,这些私有子网也要将OpenVPN客户端的地址池(10.8.0.0/255.255.255.0)反馈回OpenVPN服务器。 + ;push "route 192.168.10.0 255.255.255.0" + ;push "route 192.168.20.0 255.255.255.0" + + # 为指定的客户端分配指定的IP地址,或者客户端背后也有一个私有子网想要访问VPN, + # 那么你可以针对该客户端的配置文件使用ccd子目录。 + # (简而言之,就是允许客户端所在的局域网成员也能够访问VPN) + + # 举个例子:假设有个Common Name为"Thelonious"的客户端背后也有一个小型子网想要连接到VPN,该子网为192.168.40.128/255.255.255.248。 + # 首先,你需要去掉下面两行指令的注释: + ;client-config-dir ccd + ;route 192.168.40.128 255.255.255.248 + # 然后创建一个文件ccd/Thelonious,该文件的内容为: + # iroute 192.168.40.128 255.255.255.248 + #这样客户端所在的局域网就可以访问VPN了。 + # 注意,这个指令只能在你是基于路由、而不是基于桥接的模式下才能生效。 + # 比如,你使用了"dev tun"和"server"指令。 + + # 再举个例子:假设你想给Thelonious分配一个固定的IP地址10.9.0.1。 + # 首先,你需要去掉下面两行指令的注释: + ;client-config-dir ccd + ;route 10.9.0.0 255.255.255.252 + # 然后在文件ccd/Thelonious中添加如下指令: + # ifconfig-push 10.9.0.1 10.9.0.2 + + # 如果你想要为不同群组的客户端启用不同的防火墙访问策略,你可以使用如下两种方法: + # (1)运行多个OpenVPN守护进程,每个进程对应一个群组,并为每个进程(群组)启用适当的防火墙规则。 + # (2) (进阶)创建一个脚本来动态地修改响应于来自不同客户的防火墙规则。 + # 关于learn-address脚本的更多信息请参考官方手册页面。 + ;learn-address ./script + + # 如果启用该指令,所有客户端的默认网关都将重定向到VPN,这将导致诸如web浏览器、DNS查询等所有客户端流量都经过VPN。 + # (为确保能正常工作,OpenVPN服务器所在计算机可能需要在TUN/TAP接口与以太网之间使用NAT或桥接技术进行连接) + ;push "redirect-gateway def1 bypass-dhcp" + + # 某些具体的Windows网络设置可以被推送到客户端,例如DNS或WINS服务器地址。 + # 下列地址来自opendns.com提供的Public DNS 服务器。 + ;push "dhcp-option DNS 208.67.222.222" + ;push "dhcp-option DNS 208.67.220.220" + + # 去掉该指令的注释将允许不同的客户端之间相互"可见"(允许客户端之间互相访问)。 + # 默认情况下,客户端只能"看见"服务器。为了确保客户端只能看见服务器,你还可以在服务器端的TUN/TAP接口上设置适当的防火墙规则。 + ;client-to-client + + # 如果多个客户端可能使用相同的证书/私钥文件或Common Name进行连接,那么你可以取消该指令的注释。 + # 建议该指令仅用于测试目的。对于生产使用环境而言,每个客户端都应该拥有自己的证书和私钥。 + # 如果你没有为每个客户端分别生成Common Name唯一的证书/私钥,你可以取消该行的注释(但不推荐这样做)。 + ;duplicate-cn + + # keepalive指令将导致类似于ping命令的消息被来回发送,以便于服务器端和客户端知道对方何时被关闭。 + # 每10秒钟ping一次,如果120秒内都没有收到对方的回复,则表示远程连接已经关闭。 + keepalive 10 120 + + # 出于SSL/TLS之外更多的安全考虑,创建一个"HMAC 防火墙"可以帮助抵御DoS攻击和UDP端口淹没攻击。 + # 你可以使用以下命令来生成: + # openvpn --genkey --secret ta.key + # + # 服务器和每个客户端都需要拥有该密钥的一个拷贝。 + # 第二个参数在服务器端应该为'0',在客户端应该为'1'。 + ;tls-auth ta.key 0 # 该文件应该保密 + + # 选择一个密码加密算法。 + # 该配置项也必须复制到每个客户端配置文件中。 + ;cipher BF-CBC # Blowfish (默认) + ;cipher AES-128-CBC # AES + ;cipher DES-EDE3-CBC # Triple-DES + + # 在VPN连接上启用压缩。 + # 如果你在此处启用了该指令,那么也应该在每个客户端配置文件中启用它。 + comp-lzo + + # 允许并发连接的客户端的最大数量 + ;max-clients 100 + + # 在完成初始化工作之后,降低OpenVPN守护进程的权限是个不错的主意。 + # 该指令仅限于非Windows系统中使用。 + ;user nobody + ;group nobody + + # 持久化选项可以尽量避免访问那些在重启之后由于用户权限降低而无法访问的某些资源。 + persist-key + persist-tun + + # 输出一个简短的状态文件,用于显示当前的连接状态,该文件每分钟都会清空并重写一次。 + status openvpn-status.log + + # 默认情况下,日志消息将写入syslog(在Windows系统中,如果以服务方式运行,日志消息将写入OpenVPN安装目录的log文件夹中)。 + # 你可以使用log或者log-append来改变这种默认情况。 + # "log"方式在每次启动时都会清空之前的日志文件。 + # "log-append"这是在之前的日志内容后进行追加。 + # 你可以使用两种方式之一(但不要同时使用)。 + ;log openvpn.log + ;log-append openvpn.log + + # 为日志文件设置适当的冗余级别(0~9)。冗余级别越高,输出的信息越详细。 + # + # 0 表示静默运行,只记录致命错误。 + # 4 表示合理的常规用法。 + # 5 和 6 可以帮助调试连接错误。 + # 9 表示极度冗余,输出非常详细的日志信息。 + verb 3 + + # 重复信息的沉默度。 + # 相同类别的信息只有前20条会输出到日志文件中。 + ;mute 20 + ``` # 客户端配置文件 -``` -############################################## -# 针对多个客户端的OpenVPN 2.0 的客户端配置文件示例 -# -# 该配置文件可以被多个客户端使用,当然每个客户端都应该有自己的证书和密钥文件 -# -# 在Windows上此配置文件的后缀应该是".ovpn",在Linux/BSD系统中则是".conf" -############################################## - -# 指定这是一个客户端,我们将从服务器获取某些配置文件指令 -client - -# 在大多数系统中,除非你部分禁用或者完全禁用了TUN/TAP接口的防火墙,否则VPN将不起作用。 -;dev tap -dev tun - -# 在Windows系统中,如果你想配置多个隧道,则需要该指令。 -# 你需要用到网络连接面板中TAP-Win32适配器的名称(例如"MyTap")。 -# 在XP SP2或更高版本的系统中,你可能需要禁用掉针对TAP适配器的防火墙。 -;dev-node MyTap - -# 指定连接的服务器是采用TCP还是UDP协议。 -# 这里需要使用与服务器端相同的设置。 -;proto tcp -proto udp - -# 指定服务器的主机名(或IP)以及端口号。 -# 如果有多个VPN服务器,为了实现负载均衡,你可以设置多个remote指令。 -remote my-server-1 1194 -;remote my-server-2 1194 - -# 如果指定了多个remote指令,启用该指令将随机连接其中的一台服务器, -# 否则,客户端将按照指定的先后顺序依次尝试连接服务器。 -;remote-random - -# 启用该指令,与服务器连接中断后将自动重新连接,这在网络不稳定的情况下(例如:笔记本电脑无线网络)非常有用。 -resolv-retry infinite - -# 大多数客户端不需要绑定本机特定的端口号 -nobind - -# 在初始化完毕后,降低OpenVPN的权限(该指令仅限于非Windows系统中使用) -;user nobody -;group nobody - -# 持久化选项可以尽量避免访问在重启时由于用户权限降低而无法访问的某些资源。 -persist-key -persist-tun - -# 如果你是通过HTTP代理方式来连接到实际的VPN服务器,请在此处指定代理服务器的主机名(或IP)和端口号。 -# 如果你的代理服务器需要身份认证,请参考官方手册页面。 -;http-proxy-retry # 连接失败时自动重试 -;http-proxy [proxy server] [proxy port #] - -# 无线网络通常会产生大量的重复数据包。设置此标识将忽略掉重复数据包的警告信息。 -;mute-replay-warnings - -# SSL/TLS 参数配置。 -# 更多描述信息请参考服务器端配置文件。 -# 最好为每个客户端单独分配.crt/.key文件对。 -# 单个CA证书可以供所有客户端使用。 -ca ca.crt -cert client.crt -key client.key - -# 指定通过检查证书的nsCertType字段是否为"server"来验证服务器端证书。 -# 这是预防潜在攻击的一种重要措施。 -# -# 为了使用该功能,你需要在生成服务器端证书时,将其中的nsCertType字段设为"server" -# easy-rsa文件夹中的build-key-server脚本文件可以达到该目的。 -ns-cert-type server - -# 如果服务器端使用了tls-auth密钥,那么每个客户端也都应该有该密钥。 -;tls-auth ta.key 1 - -# 指定密码的加密算法。 -# 如果服务器端启用了cipher指令选项,那么你必须也在这里指定它。 -;cipher x - -# 在VPN连接中启用压缩。 -# 该指令的启用/禁用应该与服务器端保持一致。 -comp-lzo - -# 设置日志文件冗余级别(0~9)。 -# 0 表示静默运行,只记录致命错误。 -# 4 表示合理的常规用法。 -# 5 和 6 可以帮助调试连接错误。 -# 9 表示极度冗余,输出非常详细的日志信息。 -verb 3 - -# 忽略过多的重复信息。 -# 相同类别的信息只有前20条会输出到日志文件中。 -;mute 20 -``` + ``` + ############################################## + # 针对多个客户端的OpenVPN 2.0 的客户端配置文件示例 + # + # 该配置文件可以被多个客户端使用,当然每个客户端都应该有自己的证书和密钥文件 + # + # 在Windows上此配置文件的后缀应该是".ovpn",在Linux/BSD系统中则是".conf" + ############################################## + + # 指定这是一个客户端,我们将从服务器获取某些配置文件指令 + client + + # 在大多数系统中,除非你部分禁用或者完全禁用了TUN/TAP接口的防火墙,否则VPN将不起作用。 + ;dev tap + dev tun + + # 在Windows系统中,如果你想配置多个隧道,则需要该指令。 + # 你需要用到网络连接面板中TAP-Win32适配器的名称(例如"MyTap")。 + # 在XP SP2或更高版本的系统中,你可能需要禁用掉针对TAP适配器的防火墙。 + ;dev-node MyTap + + # 指定连接的服务器是采用TCP还是UDP协议。 + # 这里需要使用与服务器端相同的设置。 + ;proto tcp + proto udp + + # 指定服务器的主机名(或IP)以及端口号。 + # 如果有多个VPN服务器,为了实现负载均衡,你可以设置多个remote指令。 + remote my-server-1 1194 + ;remote my-server-2 1194 + + # 如果指定了多个remote指令,启用该指令将随机连接其中的一台服务器, + # 否则,客户端将按照指定的先后顺序依次尝试连接服务器。 + ;remote-random + + # 启用该指令,与服务器连接中断后将自动重新连接,这在网络不稳定的情况下(例如:笔记本电脑无线网络)非常有用。 + resolv-retry infinite + + # 大多数客户端不需要绑定本机特定的端口号 + nobind + + # 在初始化完毕后,降低OpenVPN的权限(该指令仅限于非Windows系统中使用) + ;user nobody + ;group nobody + + # 持久化选项可以尽量避免访问在重启时由于用户权限降低而无法访问的某些资源。 + persist-key + persist-tun + + # 如果你是通过HTTP代理方式来连接到实际的VPN服务器,请在此处指定代理服务器的主机名(或IP)和端口号。 + # 如果你的代理服务器需要身份认证,请参考官方手册页面。 + ;http-proxy-retry # 连接失败时自动重试 + ;http-proxy [proxy server] [proxy port #] + + # 无线网络通常会产生大量的重复数据包。设置此标识将忽略掉重复数据包的警告信息。 + ;mute-replay-warnings + + # SSL/TLS 参数配置。 + # 更多描述信息请参考服务器端配置文件。 + # 最好为每个客户端单独分配.crt/.key文件对。 + # 单个CA证书可以供所有客户端使用。 + ca ca.crt + cert client.crt + key client.key + + # 指定通过检查证书的nsCertType字段是否为"server"来验证服务器端证书。 + # 这是预防潜在攻击的一种重要措施。 + # + # 为了使用该功能,你需要在生成服务器端证书时,将其中的nsCertType字段设为"server" + # easy-rsa文件夹中的build-key-server脚本文件可以达到该目的。 + ns-cert-type server + + # 如果服务器端使用了tls-auth密钥,那么每个客户端也都应该有该密钥。 + ;tls-auth ta.key 1 + + # 指定密码的加密算法。 + # 如果服务器端启用了cipher指令选项,那么你必须也在这里指定它。 + ;cipher x + + # 在VPN连接中启用压缩。 + # 该指令的启用/禁用应该与服务器端保持一致。 + comp-lzo + + # 设置日志文件冗余级别(0~9)。 + # 0 表示静默运行,只记录致命错误。 + # 4 表示合理的常规用法。 + # 5 和 6 可以帮助调试连接错误。 + # 9 表示极度冗余,输出非常详细的日志信息。 + verb 3 + + # 忽略过多的重复信息。 + # 相同类别的信息只有前20条会输出到日志文件中。 + ;mute 20 + ``` # 撤销客户端证书 - 生成/更新 crl.pem @@ -309,11 +309,13 @@ verb 3 ./easyrsa gen-crl cp pki/crl.pem /etc/openvpn-server/server/my-server0/ ``` + - 修改 openvpn-server 的配置文件,追加/修改下面一行 - ``` + ```bash # 注意: 该 crl.pem 文件本身及其上级目录,均需对 openvpn 运行用户可读 crl-verify my-server0/crl.pem ``` + - 重启 openvpn-server 服务 # 参考链接 diff --git a/content/post/oracle.md b/content/post/oracle.md index 840217f..8431c55 100644 --- a/content/post/oracle.md +++ b/content/post/oracle.md @@ -35,309 +35,309 @@ clob | 4GB | 字符串 bfile | 视操作系统 | 存储非结构化数据到数据库外的文件中 # 创建表 -```sql -CREATE TABLE table_name -( -column_name datatype [NULL|NOT NULL], -..., -PRIMARY KEY(), -CONSTRAINT table_name constraint_name FOREIGN KEY (column_name) REFERENCE table_name(column_name) ON DELETE CASCADE, -CONSTRAINT constraint_name CHECK(condition), -CONSTRAINT constraint_name UNIQUE(column_name) -) -|AS SELECT column_name1,column_name2,...FROM source_table; -DROP TABLE table_name; -``` + ```sql + CREATE TABLE table_name + ( + column_name datatype [NULL|NOT NULL], + ..., + PRIMARY KEY(), + CONSTRAINT table_name constraint_name FOREIGN KEY (column_name) REFERENCE table_name(column_name) ON DELETE CASCADE, + CONSTRAINT constraint_name CHECK(condition), + CONSTRAINT constraint_name UNIQUE(column_name) + ) + |AS SELECT column_name1,column_name2,...FROM source_table; + DROP TABLE table_name; + ``` # 删除表 -```bash -DROP TABLE table_name; -# 执行最快,删除数据、结构、索引、约束、触发器和索引,存储过程和索引invalid状态,直接生效,不可回滚,不释放空间 -TRUNCATE TABLE table_name; -# 执行较快,只删除数据,直接生效,不可回滚,释放空间 -DELETE FROM table_name [WHERE condition]; -# 执行最慢,只删除数据,commit 后生效,可回滚,不释放空间 -``` + ```bash + DROP TABLE table_name; + # 执行最快,删除数据、结构、索引、约束、触发器和索引,存储过程和索引invalid状态,直接生效,不可回滚,不释放空间 + TRUNCATE TABLE table_name; + # 执行较快,只删除数据,直接生效,不可回滚,释放空间 + DELETE FROM table_name [WHERE condition]; + # 执行最慢,只删除数据,commit 后生效,可回滚,不释放空间 + ``` # 操作表列 -```sql -ALTER TABLE table_name -ADD column_name datatype [NULL|NOT NULL] -|MODIFY column_name new_datatype|NULL|NOT NULL -|DROP COLUMN column_name; --- 删除列时通常追加 CASCADE CONSTRAINTS ,以删除于该列有关的约束 -``` + ```sql + ALTER TABLE table_name + ADD column_name datatype [NULL|NOT NULL] + |MODIFY column_name new_datatype|NULL|NOT NULL + |DROP COLUMN column_name; + -- 删除列时通常追加 CASCADE CONSTRAINTS ,以删除于该列有关的约束 + ``` # 操作主键 -```sql -ALTER TABLE table_name -ADD CONSTRAINTS constraint_name PRIMARY KEY(column_name) -|DROP CONSTRAINTS constraint_name; -``` + ```sql + ALTER TABLE table_name + ADD CONSTRAINTS constraint_name PRIMARY KEY(column_name) + |DROP CONSTRAINTS constraint_name; + ``` # 操作外键 -```sql -ALTER TABLE table_name -ADD CONSTRAINT constraint_name FOREIGN KEY(column_name) REFERENCE table_name(column_name) ON DELETE CASCADE -|DROP CONSTRAINT constraint_name; -``` + ```sql + ALTER TABLE table_name + ADD CONSTRAINT constraint_name FOREIGN KEY(column_name) REFERENCE table_name(column_name) ON DELETE CASCADE + |DROP CONSTRAINT constraint_name; + ``` # 操作CHECK约束 -```sql -ALTER TABLE table_name -ADD CONSTRAINT constraint_name CHECK(condition) -|DROP CONSTRAINT constraint_name; -``` + ```sql + ALTER TABLE table_name + ADD CONSTRAINT constraint_name CHECK(condition) + |DROP CONSTRAINT constraint_name; + ``` # 操作UNIQUE约束 -```sql -ALTER TABLE table_name -ADD CONSTRAINT constraint_name UNIQUE(column_name) -|DROP CONSTRAINT constraint_name; -``` + ```sql + ALTER TABLE table_name + ADD CONSTRAINT constraint_name UNIQUE(column_name) + |DROP CONSTRAINT constraint_name; + ``` # 添加数据 -```sql -INSERT INTO table_name(column_name1,column_name2,...) -VALUES(data1,data2,...) -|SELECT column_name1,column_name2...FROM table_name2; -``` + ```sql + INSERT INTO table_name(column_name1,column_name2,...) + VALUES(data1,data2,...) + |SELECT column_name1,column_name2...FROM table_name2; + ``` # 修改数据 -```sql -UPDATE table_name SET column_name1=data1,column_name2=data2,...[WHERE condition]; -``` + ```sql + UPDATE table_name SET column_name1=data1,column_name2=data2,...[WHERE condition]; + ``` # 删除数据 -```sql -DELETE FROM table_name [WHERE condition]; -TRUNCATE TABLE table_name; -``` + ```sql + DELETE FROM table_name [WHERE condition]; + TRUNCATE TABLE table_name; + ``` # 查询数据 -```sql -SELECT column_name1,column_name2,...FROM table_name [WHERE condition]; -``` + ```sql + SELECT column_name1,column_name2,...FROM table_name [WHERE condition]; + ``` # MERGE语句 -```sql -MERGE INTO table_name1 USING table_name2 ON(condition) WHEN MATCHED THEN ... WHEN NOT MATCHED THEN ...; -``` + ```sql + MERGE INTO table_name1 USING table_name2 ON(condition) WHEN MATCHED THEN ... WHEN NOT MATCHED THEN ...; + ``` # SELECT 语句 -```sql -SELECT [DISTINCT|ALL] select_list FROM table_list [WHERE ...] [GROUP BY ...] [HAVING ...] [ORDER BY ...]; -``` + ```sql + SELECT [DISTINCT|ALL] select_list FROM table_list [WHERE ...] [GROUP BY ...] [HAVING ...] [ORDER BY ...]; + ``` # select_list -```sql -*|[schema.] {table|view} .*|expr[ [AS ]c_alias] -``` + ```sql + *|[schema.] {table|view} .*|expr[ [AS ]c_alias] + ``` # expr -```sql -"||" 连接的字符串 | 函数 -``` + ```sql + "||" 连接的字符串 | 函数 + ``` # ORDER BY ... -```sql -{expr|positon|c_alias} {ASC|DESC} {NULLS FIRST|NULLS LAST}[ {expr|positon|c_alias} {ASC|DESC} {NULLS FIRST|NULLS LAST},...] -``` + ```sql + {expr|positon|c_alias} {ASC|DESC} {NULLS FIRST|NULLS LAST}[ {expr|positon|c_alias} {ASC|DESC} {NULLS FIRST|NULLS LAST},...] + ``` # 模糊查询关键字like -```sql -'_'替代一个字符,'%'替代多个字符 -``` + ```sql + '_'替代一个字符,'%'替代多个字符 + ``` # 从给定值中选取查询 -```sql -IN(data1,data2,...) -``` + ```sql + IN(data1,data2,...) + ``` # 连接 -```sql --- 连接,只能查询匹配记录 -SELECT select_list FROM table_name1 INNER JOIN table_name2 ON condition; --- 左外连接 -SELECT select_list FROM table_name1 LEFT JOIN table_name2 ON condition; --- 右外连接 -SELECT select_list FROM table_name1 RIGHT JOIN table_name2 ON condition; --- 全外连接 -SELECT select_list FROM table_name1 FULL JOIN table_name2 ON condition; -``` + ```sql + -- 连接,只能查询匹配记录 + SELECT select_list FROM table_name1 INNER JOIN table_name2 ON condition; + -- 左外连接 + SELECT select_list FROM table_name1 LEFT JOIN table_name2 ON condition; + -- 右外连接 + SELECT select_list FROM table_name1 RIGHT JOIN table_name2 ON condition; + -- 全外连接 + SELECT select_list FROM table_name1 FULL JOIN table_name2 ON condition; + ``` # 内置函数 -```sql -ABS(n) -- n绝对值 -MOD(n2,n1) -- n2对n1取余 -SIGN(n) -- n的符号 -CEIL(n) -- 大于等于n的最小整数 -FLOOR(n) -- 小于等于n的最大整数 -SQRT(n) -- n的平方根 -POWER(n2,n1) -- n2的n1次幂 -EXP(n) -- e的n次幂 -LOG(n1,n2) -- n1为底n2的对数 -LN(n) -- n的自然对数 -ROUND(n2,n1) -- n2小数部分四舍五入至n1位 -TRUNC(n2,n1) -- n2截取至n1位 -CHR(n) -- 把n根据ASCII转换成字符 -ASCII(char) -- 参数首字母的ASCII值 -LENGTH(char) -- 字符串长度 -SUBSTR(char,position[,substring_length]) -- 截取字符串 -CONCAT(char1,char2) -- 连接字符串 -INSTR(string,substring[,position[,occurrence]]) -- 查找字符串 -UPPER(char) -- 转换成大写 -LOWER(char) -- 转换成小些 -INITCAP(char) -- 单词首字母大写 -NLSSORT(char[,nslparam]) -- 按指定方式排序'NLS_SORT=SCHINESE_PINYIN_M' -REPLACE(char,search_string[,replacement_string]) -- 字符串替换,默认删除 -RPAD(expr1,n[,expr2]) -- 用expr2右填充expr1至长度为n,默认空格 -LPAD(expr1,n[,expr2]) -- 用expr2左填充expr1至长度为n,默认空格 -TRIM([LEADING|TRAILING|BOTH] [trim_character FROM] trim_source) -- 删除字符串首尾指定字符 -SYSDATE -- 获取系统当前日期 -SYSTIMESTAMP -- 获取系统当前时间 -DBTIMEZONE -- 获取数据库当前时区 -ADD_MONTHS(date,integer) -- 指定日期增加指定月份数 -SESSIONTIMEZONE -- 获取当前会话的时区 -LAST_DAY(date) -- 获取指定日期对应月份的最后一天 -NEXT_DAY(date,char) -- 获取下周char的日期 -CURRENT_DATE -- 获取会话时区的当前日期 -EXTRACT(datetime) -- 从指定时间中获取指定部分 -MONTHS_BETWEEN(date1,date2) -- 获取两个时间之间的月份数 -NET_TIME(date,timezone1,timezone2) -- 获取时区1中的时间转换到时区2后的时间 -TO_CHAR(n[,fmt]) -- 转换为字符类型 -TO_DATE(n[,fmt]) -- 转换为时间类型 -TO_NUMBER(n[,fmt]) -- 转换为数字类型 -LNNVL(condition) -- 排除指定条件函数 -NVL(expr1,expr2) -- expr1为空时返回expr2 -NVL2(expr1,expr2,expr3) -- expr1为空时返回expr3,不为空返回expr2 -AVG([DISTINCT|ALL ]expr) -- 获取平均值 -COUNT(*|[DISTINCT|ALL ]expr) -- 获取数量 -SUM([DISTINCT|ALL ]expr) -- 获取和 -SELECT USER FROM DUAL; -- 返回当前会话的登录名 -USERENV(param) -- 返回当前会话的信息 -SYS_CONTEXT(namespace,param) -- 返回oracle已创建的context -DECODE(expr,search,result[,search1,result1...]) -- expr结果是search返回result -``` + ```sql + ABS(n) -- n绝对值 + MOD(n2,n1) -- n2对n1取余 + SIGN(n) -- n的符号 + CEIL(n) -- 大于等于n的最小整数 + FLOOR(n) -- 小于等于n的最大整数 + SQRT(n) -- n的平方根 + POWER(n2,n1) -- n2的n1次幂 + EXP(n) -- e的n次幂 + LOG(n1,n2) -- n1为底n2的对数 + LN(n) -- n的自然对数 + ROUND(n2,n1) -- n2小数部分四舍五入至n1位 + TRUNC(n2,n1) -- n2截取至n1位 + CHR(n) -- 把n根据ASCII转换成字符 + ASCII(char) -- 参数首字母的ASCII值 + LENGTH(char) -- 字符串长度 + SUBSTR(char,position[,substring_length]) -- 截取字符串 + CONCAT(char1,char2) -- 连接字符串 + INSTR(string,substring[,position[,occurrence]]) -- 查找字符串 + UPPER(char) -- 转换成大写 + LOWER(char) -- 转换成小些 + INITCAP(char) -- 单词首字母大写 + NLSSORT(char[,nslparam]) -- 按指定方式排序'NLS_SORT=SCHINESE_PINYIN_M' + REPLACE(char,search_string[,replacement_string]) -- 字符串替换,默认删除 + RPAD(expr1,n[,expr2]) -- 用expr2右填充expr1至长度为n,默认空格 + LPAD(expr1,n[,expr2]) -- 用expr2左填充expr1至长度为n,默认空格 + TRIM([LEADING|TRAILING|BOTH] [trim_character FROM] trim_source) -- 删除字符串首尾指定字符 + SYSDATE -- 获取系统当前日期 + SYSTIMESTAMP -- 获取系统当前时间 + DBTIMEZONE -- 获取数据库当前时区 + ADD_MONTHS(date,integer) -- 指定日期增加指定月份数 + SESSIONTIMEZONE -- 获取当前会话的时区 + LAST_DAY(date) -- 获取指定日期对应月份的最后一天 + NEXT_DAY(date,char) -- 获取下周char的日期 + CURRENT_DATE -- 获取会话时区的当前日期 + EXTRACT(datetime) -- 从指定时间中获取指定部分 + MONTHS_BETWEEN(date1,date2) -- 获取两个时间之间的月份数 + NET_TIME(date,timezone1,timezone2) -- 获取时区1中的时间转换到时区2后的时间 + TO_CHAR(n[,fmt]) -- 转换为字符类型 + TO_DATE(n[,fmt]) -- 转换为时间类型 + TO_NUMBER(n[,fmt]) -- 转换为数字类型 + LNNVL(condition) -- 排除指定条件函数 + NVL(expr1,expr2) -- expr1为空时返回expr2 + NVL2(expr1,expr2,expr3) -- expr1为空时返回expr3,不为空返回expr2 + AVG([DISTINCT|ALL ]expr) -- 获取平均值 + COUNT(*|[DISTINCT|ALL ]expr) -- 获取数量 + SUM([DISTINCT|ALL ]expr) -- 获取和 + SELECT USER FROM DUAL; -- 返回当前会话的登录名 + USERENV(param) -- 返回当前会话的信息 + SYS_CONTEXT(namespace,param) -- 返回oracle已创建的context + DECODE(expr,search,result[,search1,result1...]) -- expr结果是search返回result + ``` # 查看所有默认表空间 -```sql -SELECT TABLESPACE_NAME FROM DBA_TABLESPACES; -``` + ```sql + SELECT TABLESPACE_NAME FROM DBA_TABLESPACES; + ``` # 查看指定用户默认表空间 -```sql -SELECT DEFAULT_STAPCE,USERNAME FROM DBA_USERS WHERE USERNAME='username'; -``` + ```sql + SELECT DEFAULT_STAPCE,USERNAME FROM DBA_USERS WHERE USERNAME='username'; + ``` # 创建表空间 -```sql -CREATE TABLESPACE tablespace_name -DATAFILE filename -SIZE size -[AUTOEXTEND [ON NEXT size|OFF]] -[MAXSIZE size] -[PERMANENT|TEMPORARY] 永久/临时表空间,默认永久 -[EXTENT MANAGEMENT [DICTIONARY|LOCAL 字典/本地管理方式,默认本地 -[AUTOALLOCATE|UNIFORM. [SIZE integer[K|M]]]]; -``` + ```sql + CREATE TABLESPACE tablespace_name + DATAFILE filename + SIZE size + [AUTOEXTEND [ON NEXT size|OFF]] + [MAXSIZE size] + [PERMANENT|TEMPORARY] 永久/临时表空间,默认永久 + [EXTENT MANAGEMENT [DICTIONARY|LOCAL 字典/本地管理方式,默认本地 + [AUTOALLOCATE|UNIFORM. [SIZE integer[K|M]]]]; + ``` # 重命名表空间 -```sql -ALTER TABLESPACE oldname RENAME TO newname; -``` + ```sql + ALTER TABLESPACE oldname RENAME TO newname; + ``` # 修改表空间大小 -```sql -ALTER DATABASE DATAFILE filename RESIZE size; -``` + ```sql + ALTER DATABASE DATAFILE filename RESIZE size; + ``` # 增加表空间大小 -```sql -ALTER TABLESPACE tablespace_name ADD DATAFILE filename SIZE size; -``` + ```sql + ALTER TABLESPACE tablespace_name ADD DATAFILE filename SIZE size; + ``` # 设置表空间读写状态 -```sql -ALTER TABLESPACE tablespace_name READ {ONLY|WRITE}; -``` + ```sql + ALTER TABLESPACE tablespace_name READ {ONLY|WRITE}; + ``` # 设置表空间可用状态 -```sql -ALTER TABLESPACE tablespace_name {ONLINE|OFFLINE [NORMAL|TEMPORARY|IMMEDIATE]}; -``` + ```sql + ALTER TABLESPACE tablespace_name {ONLINE|OFFLINE [NORMAL|TEMPORARY|IMMEDIATE]}; + ``` # 创建大文件表空间 -```sql -CREATE BIGFILE TABLESPACE tablespace_name DATAFILE filename SIZE size; -``` + ```sql + CREATE BIGFILE TABLESPACE tablespace_name DATAFILE filename SIZE size; + ``` # 删除表空间 -```sql -DROP TABLESPACE tablespace_name -[INCLUDING CONTENTS AND DATAFILES] 数据文件删除 -[CASCADE CONSTRAINTS]; 完整性删除 -``` + ```sql + DROP TABLESPACE tablespace_name + [INCLUDING CONTENTS AND DATAFILES] 数据文件删除 + [CASCADE CONSTRAINTS]; 完整性删除 + ``` # 查看表空间大小 -```sql -SELECT TABLESPACE_NAME,FILE_NAME,BYTES FROM DBA_DATA_FILES WHERE TABLESPACE_NAME=tablespace_name; -``` + ```sql + SELECT TABLESPACE_NAME,FILE_NAME,BYTES FROM DBA_DATA_FILES WHERE TABLESPACE_NAME=tablespace_name; + ``` # 查看表空间剩余 空间 -```sql -SELECT TABLESPACE_NAME,BYTES FROM DBA_FREE_SPACES; -``` + ```sql + SELECT TABLESPACE_NAME,BYTES FROM DBA_FREE_SPACES; + ``` # 创建/修改用户 -```sql -CREATE|ALTER -USER user_name -IDENTIFIED BY password -[DEFAULT TABLESPACE tablespace_name ] -[QUOTA size|UNLIMITED ON tablespace_name ] 用户使用表空间的最大值 -[PROFILE profile ] 概要文件 -[PASSWORD EXPIRE ] 用户密码过期 -[ACCOUNT LOCK|UNLOCK]; 默认锁定状态 -``` + ```sql + CREATE|ALTER + USER user_name + IDENTIFIED BY password + [DEFAULT TABLESPACE tablespace_name ] + [QUOTA size|UNLIMITED ON tablespace_name ] 用户使用表空间的最大值 + [PROFILE profile ] 概要文件 + [PASSWORD EXPIRE ] 用户密码过期 + [ACCOUNT LOCK|UNLOCK]; 默认锁定状态 + ``` # 删除用户 -```sql -DROP USER user_name CASCADE; -``` + ```sql + DROP USER user_name CASCADE; + ``` # 授予系统权限 -```sql -GRANT -system_privileges|ALL PRIVILEGES 权限 -TO {user IDENTIFIED BY password|role } 用户/角色 -[WITH ADMIN OPTION]; 授予其他用户或角色系统权限 -``` + ```sql + GRANT + system_privileges|ALL PRIVILEGES 权限 + TO {user IDENTIFIED BY password|role } 用户/角色 + [WITH ADMIN OPTION]; 授予其他用户或角色系统权限 + ``` # 授予对象权限 -```sql -GRANT -object_privilege|ALL 权限 -ON schema.object 对象 -TO user_name|role_name 用户/角色 -[WITH ADMIN OPTION ] 授予其他用户或角色系统权限 -[WITH THE GRANT ANY OBJECT]; 授予其他用户或角色对象权限 -``` + ```sql + GRANT + object_privilege|ALL 权限 + ON schema.object 对象 + TO user_name|role_name 用户/角色 + [WITH ADMIN OPTION ] 授予其他用户或角色系统权限 + [WITH THE GRANT ANY OBJECT]; 授予其他用户或角色对象权限 + ``` # 撤销系统权限 -```sql -REVOKE system_privilege FROM -user|role; -``` + ```sql + REVOKE system_privilege FROM + user|role; + ``` # 撤销对象权限 -```sql -REVOKE -object_privilege |ALL -ON schema.object FROM -user_name|role_name -[CASCADE CONSTRAINTS]; -``` + ```sql + REVOKE + object_privilege |ALL + ON schema.object FROM + user_name|role_name + [CASCADE CONSTRAINTS]; + ``` # 数据字典 数据 | 字典 @@ -347,150 +347,150 @@ user_name|role_name 用户角色 | DBA_ROLE_PRIVS # 创建角色 -```sql -CREATE|ALTER //创建/修改 -ROLE role_name -[NOT IDENTIFIED|IDENDIFIED BY [password]]; -GRANT //填充权限 -system_privilege|ALL PRIVILEGES -TO role_name -[WITH ADMIN OPTION]; --- 角色创建完成后不能直接使用,需将角色赋予用户才能使用 -GRANT role_name TO user_name; -SET ROLE role_name -- 设置角色生效 -SET ROLE ALL -- 设置所有角色生效 -SET ROLE ALL EXCEPT role_name -- 设置只有role_name失效 -SET ROLE NONE -- 设置所有角色失效 -``` + ```sql + CREATE|ALTER //创建/修改 + ROLE role_name + [NOT IDENTIFIED|IDENDIFIED BY [password]]; + GRANT //填充权限 + system_privilege|ALL PRIVILEGES + TO role_name + [WITH ADMIN OPTION]; + -- 角色创建完成后不能直接使用,需将角色赋予用户才能使用 + GRANT role_name TO user_name; + SET ROLE role_name -- 设置角色生效 + SET ROLE ALL -- 设置所有角色生效 + SET ROLE ALL EXCEPT role_name -- 设置只有role_name失效 + SET ROLE NONE -- 设置所有角色失效 + ``` # 删除角色 -```sql -DROP ROLE role_name; -``` + ```sql + DROP ROLE role_name; + ``` # 脱机备份(冷备份)/恢复 -```sql -关闭数据库服务后直接复制需要的文件,包括数据文件和控制文件 -``` + ```sql + 关闭数据库服务后直接复制需要的文件,包括数据文件和控制文件 + ``` # 联机备份(热备份) -```sql -ARCHIVE LOG LIST 查看本机数据库的日志状态 -ALTER SYSTEM SET LOG_ARCHIVE_START=TRUE SCOPE=SPFILE; 设置日志模式为归档 -SHUTDOWN IMMEDIATE; 关闭数据库 -STARTUP MOUNT; 启动mount实例 -ALTER DATABASE ARCHIVELOG; 更改数据库为归档日志模式 -ALTER DATABASE OPEN; 更改数据库状态为打开模式 -ALTER TABLESPACE tablespace_name BEGIN BACKUP; 开始备份数据库 -复制文件到其他目录 -ALTER TABLESPACE tablespace_name END BACKUP; 结束备份操作 -``` + ```sql + ARCHIVE LOG LIST 查看本机数据库的日志状态 + ALTER SYSTEM SET LOG_ARCHIVE_START=TRUE SCOPE=SPFILE; 设置日志模式为归档 + SHUTDOWN IMMEDIATE; 关闭数据库 + STARTUP MOUNT; 启动mount实例 + ALTER DATABASE ARCHIVELOG; 更改数据库为归档日志模式 + ALTER DATABASE OPEN; 更改数据库状态为打开模式 + ALTER TABLESPACE tablespace_name BEGIN BACKUP; 开始备份数据库 + 复制文件到其他目录 + ALTER TABLESPACE tablespace_name END BACKUP; 结束备份操作 + ``` # 恢复 -```sql -ALTER SYSTEM ARCHIVE LOG CURRENT; 归档当前日志 -ALTER SYSTEM SWITCH LOGFILE; 切换日志文件 -SELECT * FROM v$RECOVER_FILE 获取文件编号 -ALTER DATABASE DATAFILE file_id OFFLINE DROP; 把要恢复的数据文件脱机 -ALTER DATABASE OPEN; 更改数据库状态为打开模式 -RECOVER DATAFILE file_id; 恢复数据文件 -ALTER DATABASE DATAFILE file_id ONLINE; 设置数据文件联机 -``` + ```sql + ALTER SYSTEM ARCHIVE LOG CURRENT; 归档当前日志 + ALTER SYSTEM SWITCH LOGFILE; 切换日志文件 + SELECT * FROM v$RECOVER_FILE 获取文件编号 + ALTER DATABASE DATAFILE file_id OFFLINE DROP; 把要恢复的数据文件脱机 + ALTER DATABASE OPEN; 更改数据库状态为打开模式 + RECOVER DATAFILE file_id; 恢复数据文件 + ALTER DATABASE DATAFILE file_id ONLINE; 设置数据文件联机 + ``` # EXP工具导出数据 -```bash -exp db_user/password 登陆数据库的用户名和密码,非SYS -``` + ```bash + exp db_user/password 登陆数据库的用户名和密码,非SYS + ``` # EXP工具直接导出表 -```bash -exp db_user/password file="filename.dmp" tables="table_name,..." -``` + ```bash + exp db_user/password file="filename.dmp" tables="table_name,..." + ``` # EXP工具导出表空间 -```bash -exp db_user/password file="filename.dmp" tablespaces="tablespaces_name" -``` + ```bash + exp db_user/password file="filename.dmp" tablespaces="tablespaces_name" + ``` # EXPDP导出数据 -```sql -CREATE DIRECTORY directory_name AS 'file_name'; 目录名称 文件名称 -GRANT READ,WRITE ON DIRECTORY directory_name TO db_user; 授权用户使用该目录 -#expdp db_user/password directory=directory_name dumpfile=file_name tables=table_name; -``` + ```sql + CREATE DIRECTORY directory_name AS 'file_name'; 目录名称 文件名称 + GRANT READ,WRITE ON DIRECTORY directory_name TO db_user; 授权用户使用该目录 + #expdp db_user/password directory=directory_name dumpfile=file_name tables=table_name; + ``` # IMP导入数据 -```sql -imp db_user/password -``` + ```sql + imp db_user/password + ``` # IMP直接导入表 -```sql -imp db_user/password file="filename.dmp" tables="table_name,..." -``` + ```sql + imp db_user/password file="filename.dmp" tables="table_name,..." + ``` # IMPDP导入数据 -```sql -impdp db_user_password -``` + ```sql + impdp db_user_password + ``` # IMPDP直接导入表 -```bash -impdp db_user/password directory=dir dumpfile=filename.dmp tables=table_name; -``` + ```bash + impdp db_user/password directory=dir dumpfile=filename.dmp tables=table_name; + ``` # RMAN工具配置 -```sql -CONN /AS SYSDBA; 连接恢复目录数据库 -CREATE USER rman_user IDENTIFIED BY password DEFAULT TABLESPACE tablespace_name; 创建恢复用户 -GRANT RECOVERY_CATALOG_OWNER TO rman_user; 为新创建的用户授权 -#rman -CONN CATALOG rman_user/password; 连接新创建的用户 -CREATE CATALOG; 创建恢复目录 -``` + ```sql + CONN /AS SYSDBA; 连接恢复目录数据库 + CREATE USER rman_user IDENTIFIED BY password DEFAULT TABLESPACE tablespace_name; 创建恢复用户 + GRANT RECOVERY_CATALOG_OWNER TO rman_user; 为新创建的用户授权 + #rman + CONN CATALOG rman_user/password; 连接新创建的用户 + CREATE CATALOG; 创建恢复目录 + ``` # RMAN工具使用 -```sql -#rman target db_user/password@servicename catalog rman_user/password 连接恢复目录数据库 -CONNECT TARGET db_user/password@servicename; 连接目标数据库 -CONNECT CATALOG rman_user/password@servicename; 连接恢复目录数据库 -REGISTER database; 在恢复目录数据库中注册数据库 -``` + ```sql + #rman target db_user/password@servicename catalog rman_user/password 连接恢复目录数据库 + CONNECT TARGET db_user/password@servicename; 连接目标数据库 + CONNECT CATALOG rman_user/password@servicename; 连接恢复目录数据库 + REGISTER database; 在恢复目录数据库中注册数据库 + ``` # 手动分配通道 -```sql -关闭目标数据库,启动到mount状态,运行: -run -{ - ALLOCATE CHANNEL channel_name1 DEVICE TYPE {sbt|disk}; - ... - BACKUP [level] [backup type] [option] -} -``` + ```sql + 关闭目标数据库,启动到mount状态,运行: + run + { + ALLOCATE CHANNEL channel_name1 DEVICE TYPE {sbt|disk}; + ... + BACKUP [level] [backup type] [option] + } + ``` # 自动分配通道 -```sql -CONFIGURE DEVICE TYPE {sbt|disk} PARALLELISM n; 指定通道类型和名称 -CONFIGURE DEFAULT DEVICE TYPE {sbt|disk}; 指定默认设备类型 -BACKUP [level] [backup type] [option]; -``` + ```sql + CONFIGURE DEVICE TYPE {sbt|disk} PARALLELISM n; 指定通道类型和名称 + CONFIGURE DEFAULT DEVICE TYPE {sbt|disk}; 指定默认设备类型 + BACKUP [level] [backup type] [option]; + ``` # BACKUP 参数 -```sql -level 备份增量,1、2、3、4或者FULL(全备份) -backup type 对象类型,database、datafile、tablespace、controlfilecopy、archivelog all -option channel备份使用的通道 maxsetsize定义备份集的最大值 -``` + ```sql + level 备份增量,1、2、3、4或者FULL(全备份) + backup type 对象类型,database、datafile、tablespace、controlfilecopy、archivelog all + option channel备份使用的通道 maxsetsize定义备份集的最大值 + ``` # RESTORE还原 -```sql -RESTORE database_object; -database_object: DATABASE(mount),TABLESPACE(open),DATAFILE,CONTROLFILE(mount),ARCHIVELOG,SPFILE(mount) -``` + ```sql + RESTORE database_object; + database_object: DATABASE(mount),TABLESPACE(open),DATAFILE,CONTROLFILE(mount),ARCHIVELOG,SPFILE(mount) + ``` # RECOVER同步恢复 -```sql -RECOVER database_object; -database_object: DATABASE(mount),TABLESPACE(open),DATAFILE -``` + ```sql + RECOVER database_object; + database_object: DATABASE(mount),TABLESPACE(open),DATAFILE + ``` diff --git a/content/post/python-op.md b/content/post/python-op.md index 3a7f487..bb860f2 100644 --- a/content/post/python-op.md +++ b/content/post/python-op.md @@ -7,30 +7,30 @@ categories: ["python"] --- # 生成标准的、符合Unix/Posix 规范的命令行说明 -```python -from optparse import OptionParser -parser = OptionParser() -parser.add_option('-p', '--pdbk', action = 'store_true', dest = 'pdcl', default = False, - help = 'write pdbk data to oracle db') -parser.add_option('-z', '--zdbk', action = 'store_true', dest = 'zdcl', default = False, - help = 'write zdbk data to oracle db') -(options, args) = parser.parse_args() -if options.pdcl == True: - print 'pdcl is true.' -if options.zdcl == True: - print 'zdcl is True.' -``` + ```python + from optparse import OptionParser + parser = OptionParser() + parser.add_option('-p', '--pdbk', action = 'store_true', dest = 'pdcl', default = False, + help = 'write pdbk data to oracle db') + parser.add_option('-z', '--zdbk', action = 'store_true', dest = 'zdcl', default = False, + help = 'write zdbk data to oracle db') + (options, args) = parser.parse_args() + if options.pdcl == True: + print 'pdcl is true.' + if options.zdcl == True: + print 'zdcl is True.' + ``` # 简单流程 -```python -#引入OptionParser类,创建OptionParser对象 -from optparse import OptionParser -parser = OptionParser() -# 定义命令行参数 -parser.add_option(opt_str, ..., attr = value, ...) -# 解析命令行参数 -(options, args) = parser.parse_args() -``` + ```python + # 引入OptionParser类,创建OptionParser对象 + from optparse import OptionParser + parser = OptionParser() + # 定义命令行参数 + parser.add_option(opt_str, ..., attr = value, ...) + # 解析命令行参数 + (options, args) = parser.parse_args() + ``` # parse_args 和 add_options 函数 - parse_args() 接收一个命令行列表,默认使用 sys.argv\[:-1\] @@ -45,6 +45,7 @@ parser.add_option(opt_str, ..., attr = value, ...) help = 'Don\'t print status message to stdout.') (options, args) = parser.parse_args() ``` + - action 默认 store 表示将参数值保存到 options 对象里 ```python from optparse import OptionParser @@ -54,6 +55,7 @@ parser.add_option(opt_str, ..., attr = value, ...) (options, args) = parser.parse_args(args) print options.filename ``` + - type 默认 'string',也可以是 'int' 或 'float' 等,长参数名可选,dest 未指定时将用命令行的参数名来存取 options 对象的值 - store 其他两种形式:store_true 和 store_false,还有 store_const、append、count、callback ```python @@ -61,6 +63,7 @@ parser.add_option(opt_str, ..., attr = value, ...) parser.add_option('-q', action = 'store_false', dest = 'verbose') #当解析到 '-v', options.verbose 为 True,解析到 '-q',options.verbose 为 False ``` + - default 设置参数默认值 ``` parser.add_option('-f', action = 'store', dest = 'filename', default = 'foo.txt') @@ -70,6 +73,7 @@ parser.add_option(opt_str, ..., attr = value, ...) parser.add_option(...) (options, args) = parser.parse_args() ``` + - help 生成帮助信息 ```python usage = 'usage: %prog [options] arg1 arg2' @@ -89,12 +93,13 @@ parser.add_option(opt_str, ..., attr = value, ...) - metavar 提醒用户该参数期待的参数,如 metavar = 'mode' 会在帮助中显示成 -m MODE, --mode=MODE # OptionGroup 参数分组 -```python -group = OptionGroup(parser, 'Dangerous Options', - 'Caution: use these options at your own risk. It is believed that some of them bite.') -group.add_option('-g', action = 'store_true', help = 'Group option.') -parser.add_option_group(group) -``` + ```python + group = OptionGroup(parser, 'Dangerous Options', + 'Caution: use these options at your own risk. It is believed that some of them bite.') + group.add_option('-g', action = 'store_true', help = 'Group option.') + parser.add_option_group(group) + ``` + - version 创建OptionParser对象时指定该参数,会解释成 --version 命令行参数 - optparser 可以自动探测并处理一些用户异常,也可以使用 parser.error() 方法来自定义部分异常的处理 ``` diff --git a/content/post/shell.md b/content/post/shell.md index afca202..7f809b9 100644 --- a/content/post/shell.md +++ b/content/post/shell.md @@ -17,126 +17,126 @@ categories: ["shell"] - $1...$n #shell 位置参数 # BASH 字符串处理 -```bash -#字符串 str 长度 -${#str} -expr length "$str" - -#子串 substr 出现位置,找不到返回 0 -expr index "$str" "$substr" - -#子串 substr 开头匹配,找不到返回 0 -expr match "$str" "$substr" - -#字符串 str 抽取左起位置 pos 后 长度 len 的子串 -${str:$pos} -${str:$pos:$len} -expr substr "$str" $pos $len - -#字符串 str 抽取右起位置 pos 前的子串 -${str: -pos} -${str:(pos)} - -#正则 pat 抽取字符串 str 开头子串 -expr match "$str" "\($pat\)" -expr "$str" : "\($pat\)" - -#正则 pat 抽取字符串 str 结尾子串 -expr match "$str" ".*\($pat\)" -expr "$str" : ".*\($pat\)" - -#删除字符串 str 开头的最短子串 sub -${str#$sub} - -#删除字符串 str 开头的最长子串 sub -${str##$sub} - -#删除字符串 str 结尾的最短子串 sub -${str%$sub} - -#删除字符串 str 结尾的最长子串 sub -${str%%$sub} - -#替换字符串 str 第一个子串 sub 为字符串 rep -${str/"$sub"/"$rep"} - -#替换字符串 str 所有子串 sub 为字符串 rep -${str//"$sub"/"$rep"} - -#替换字符串 str 开头的子串 sub 为字符串 rep -${str/#"$sub"/"$rep"} - -#替换字符串 str 结尾的子串 sub 为字符串 rep -${str/%"$sub"/"$rep"} - -#var为空或没有设置,代入word,否则代入var值 -${var:-word} - -#如果var已经被设置且不为空,则代入它的值,否则代入word,并且在后面var始终为word的值。位置参量不能用这种方式赋值。 -${variable:=word} - -#如果变量var已被设置且值为非空,代入word值,否则什么也不代入 -${variable:+word} - -#如果变量var已被设置值且为非空,就代入它的值,否则输出word并从shell中退出,如果有省略了word,就会显示信息:parameter null or not set. -${var:?word} -``` + ```bash + # 字符串 str 长度 + ${#str} + expr length "$str" + + # 子串 substr 出现位置,找不到返回 0 + expr index "$str" "$substr" + + # 子串 substr 开头匹配,找不到返回 0 + expr match "$str" "$substr" + + # 字符串 str 抽取左起位置 pos 后 长度 len 的子串 + ${str:$pos} + ${str:$pos:$len} + expr substr "$str" $pos $len + + # 字符串 str 抽取右起位置 pos 前的子串 + ${str: -pos} + ${str:(pos)} + + # 正则 pat 抽取字符串 str 开头子串 + expr match "$str" "\($pat\)" + expr "$str" : "\($pat\)" + + # 正则 pat 抽取字符串 str 结尾子串 + expr match "$str" ".*\($pat\)" + expr "$str" : ".*\($pat\)" + + # 删除字符串 str 开头的最短子串 sub + ${str#$sub} + + # 删除字符串 str 开头的最长子串 sub + ${str##$sub} + + # 删除字符串 str 结尾的最短子串 sub + ${str%$sub} + + # 删除字符串 str 结尾的最长子串 sub + ${str%%$sub} + + # 替换字符串 str 第一个子串 sub 为字符串 rep + ${str/"$sub"/"$rep"} + + # 替换字符串 str 所有子串 sub 为字符串 rep + ${str//"$sub"/"$rep"} + + # 替换字符串 str 开头的子串 sub 为字符串 rep + ${str/#"$sub"/"$rep"} + + # 替换字符串 str 结尾的子串 sub 为字符串 rep + ${str/%"$sub"/"$rep"} + + # var为空或没有设置,代入word,否则代入var值 + ${var:-word} + + # 如果var已经被设置且不为空,则代入它的值,否则代入word,并且在后面var始终为word的值。位置参量不能用这种方式赋值。 + ${variable:=word} + + # 如果变量var已被设置且值为非空,代入word值,否则什么也不代入 + ${variable:+word} + + # 如果变量var已被设置值且为非空,就代入它的值,否则输出word并从shell中退出,如果有省略了word,就会显示信息:parameter null or not set. + ${var:?word} + ``` # BASH 数组 -```bash -#定义数组,有三种方式 -declare -a array -array=() -array[0]='value0' - -#打印数组第一个元素 -echo ${array[0]} - -#打印数组所有元素,有两种方式 -echo ${array[@]} -echo ${array[*]} - -#打印数组所有索引,有两种方式 -echo ${!array[@]} -echo ${!array[*]} - -#打印数组的元素个数,有两种方式 -echo ${#array[@]} -echo ${#array[*]} - -#移除数组中索引为2的元素 -unset array[2] - -#添加id为3的元素 -array[3]="" -``` + ```bash + # 定义数组,有三种方式 + declare -a array + array=() + array[0]='value0' + + # 打印数组第一个元素 + echo ${array[0]} + + # 打印数组所有元素,有两种方式 + echo ${array[@]} + echo ${array[*]} + + # 打印数组所有索引,有两种方式 + echo ${!array[@]} + echo ${!array[*]} + + # 打印数组的元素个数,有两种方式 + echo ${#array[@]} + echo ${#array[*]} + + # 移除数组中索引为2的元素 + unset array[2] + + # 添加id为3的元素 + array[3]="" + ``` # BASH 字典 -```bash -#定义字典 -declare -A dict - -#新增或修改键 k1 的值 -dict['k1']='v1' - -#打印对应键的值 -echo $['k1'] - -#打印字典所有元素,有两种方式 -echo ${dict[@]} -echo ${dict[*]} - -#打印字典所有键,有两种方式 -echo ${!dict[@]} -echo ${!dict[*]} - -#打印字典的元素个数,有两种方式 -echo ${#dict[@]} -echo ${#dict[*]} - -#移除键 k1 -unset dict['k1'] -``` + ```bash + # 定义字典 + declare -A dict + + # 新增或修改键 k1 的值 + dict['k1']='v1' + + # 打印对应键的值 + echo $['k1'] + + # 打印字典所有元素,有两种方式 + echo ${dict[@]} + echo ${dict[*]} + + # 打印字典所有键,有两种方式 + echo ${!dict[@]} + echo ${!dict[*]} + + # 打印字典的元素个数,有两种方式 + echo ${#dict[@]} + echo ${#dict[*]} + + # 移除键 k1 + unset dict['k1'] + ``` # 终端环境变量 PS1 参数 - \d 日期,格式为weekday month date,例如:"Mon Aug 1" @@ -187,24 +187,24 @@ unset dict['k1'] - 去掉头部 AA 和尾部 ZZ # expect 自动输入密码 -```bash -expect<> /etc/sudoers -或者 -echo "cephdeploy ALL = (root) NOPASSWD:ALL" > /etc/sudoers.d/username -chmod 0400 /etc/sudoers.d/username -``` + ```bash + echo "username ALL = (root) NOPASSWD:ALL" >> /etc/sudoers + # 或 + echo "cephdeploy ALL = (root) NOPASSWD:ALL" > /etc/sudoers.d/username + chmod 0400 /etc/sudoers.d/username + ``` # 用户登陆操作记录 - 创建日志共存目录 @@ -212,13 +212,14 @@ chmod 0400 /etc/sudoers.d/username mkdir /var/log/user_history -p chmod 0777 /var/log/user_history -R ``` + - 配置 history 历史文件 /etc/profile.d/history.sh ```bash #!/bin/bash - # + export HISTSIZE=10000 export HISTTIMEFORMAT="[%F %T] " - # + LOG_DIR=/var/log/user_history mkdir -p $LOG_DIR/$USER if [ 0 -eq $? ]; then diff --git a/content/post/systemd.md b/content/post/systemd.md index 5e6e8e8..5b8e57a 100644 --- a/content/post/systemd.md +++ b/content/post/systemd.md @@ -215,7 +215,7 @@ Runlevel 6 | runlevel6.target | reboot.target - loginctl # Unit 配置文件 -### [Unit] +## [Unit] - Description: 简短描述 - Documentation: 文档地址 - Requires: 当前 Unit 依赖的其他 Unit,如果它们没有运行,当前 Unit 会启动失败 @@ -226,7 +226,7 @@ Runlevel 6 | runlevel6.target | reboot.target - Conflicts: 这里指定的 Unit 不能与当前 Unit 同时运行 - Condition...: 当前 Unit 运行必须满足的条件,否则不会运行 - Assert...: 当前 Unit 运行必须满足的条件,否则会报启动失败 -### [Service] +## [Service] - WorkingDirectory: 设置进程的工作目录 - 特殊值 "~" 表示 User= 用户的家目录 - 设为一个以 RootDirectory= 为基准的绝对路径 @@ -271,7 +271,7 @@ Runlevel 6 | runlevel6.target | reboot.target - on-watchdog: 超时退出,才会重启 - always: 不管是什么退出原因,总是重启 - RestartSec: 系统重启前等待的秒数 -### [Install] +## [Install] - WantedBy: 它的值是一个或多个 Target,当前 Unit 激活时(enable)符号链接会放入/etc/systemd/system目录下面以 Target 名 + .wants 后缀构成的子目录中 - RequiredBy: 它的值是一个或多个 Target,当前 Unit 激活时,符号链接会放入/etc/systemd/system目录下面以 Target 名 + .required 后缀构成的子目录中 - Alias: 当前 Unit 可用于启动的别名 diff --git a/content/post/yum.md b/content/post/yum.md index df3819d..78a45bc 100644 --- a/content/post/yum.md +++ b/content/post/yum.md @@ -7,21 +7,22 @@ categories: ["os"] --- # CentOS 配置本地 ISO 镜像源 -### 上传 iso 文件 +## 上传 iso 文件 - 上传 CentOS7 的 DVD iso 镜像文件到目标服务器,例如 /home/centos7.4.iso -### 挂载 iso 文件 +## 挂载 iso 文件 - 挂载该 iso 文件到操作系统的一个空目录中,例如 /mnt/ 下 ```bash mount -o loop /home/centos7.4.iso /mnt/ ``` -### 修改软件源文件 +## 修改软件源文件 - 备份全部的 .repo 文件 ```bash cd /etc/yum.repos.d/ ls *.repo|xargs -i mv {} {}_bak ``` + - 创建 centos-base.repo 空文件,写入下面几行 ``` [base] @@ -31,16 +32,17 @@ categories: ["os"] gpgcheck=0 ``` -### 重新创建 yum 缓存 +## 重新创建 yum 缓存 - 清空以前的 yum cache ```bash yum clean all ``` + - 生成新的 yum 缓存 ```bash yum makecache fast ``` -### 其他 yum 源汇总 +## 其他 yum 源汇总 - [pkgs.org](https://pkgs.org/) diff --git a/content/post/zabbix.md b/content/post/zabbix.md index 7aad863..d3debfc 100644 --- a/content/post/zabbix.md +++ b/content/post/zabbix.md @@ -14,6 +14,7 @@ categories: ["zabbix"] JavaGatewayPort=10052 StartJavaPollers=5 ``` + - 配置 tomcat catalina 启动参数 ```bash export CATALINA_OPTS=" @@ -24,12 +25,14 @@ categories: ["zabbix"] -Djava.rmi.server.hostname={tomcat_server_ip} " ``` + - 重启 tomcat - 启动 JavaGateway ```bash # 进入 zabbix_server 安装目录,执行 ./sbin/zabbix_java/startup.sh ``` + - 重启 zabbix-server ``` # 进入 zabbix_server 安装目录,执行 diff --git a/content/post/zabbix3.10-install.md b/content/post/zabbix3.10-install.md index 925c713..55d3bc0 100644 --- a/content/post/zabbix3.10-install.md +++ b/content/post/zabbix3.10-install.md @@ -33,15 +33,18 @@ categories: ["zabbix"] - 下载 [php-5.6.31.tar.bz2](http://cn2.php.net/distributions/php-5.6.31.tar.bz2) - 安装 ```bash - #解压 + # 解压 tar jxf php-5.6.31.tar.bz2 -C /root/ cd /root/php-5.6.31/ - #安装依赖包 + + # 安装依赖包 yum install gcc make gd-devel libjpeg-devel libpng-devel libxml2-devel bzip2-devel libcurl-devel - #创建安装目录 + + # 创建安装目录 mkdir /opt/php-5.6.31/etc/ -p ln -s /opt/php-5.6.31 /opt/php - #检查编译环境 + + # 检查编译环境 ./configure --prefix=/opt/php \ --with-config-file-path=/opt/php/etc --with-bz2 --with-curl \ --enable-ftp --enable-sockets --disable-ipv6 --with-gd \ @@ -51,16 +54,19 @@ categories: ["zabbix"] --with-gettext --with-libxml-dir=/usr/local --with-zlib \ --with-pdo-mysql=mysqlnd --with-mysqli=mysqlnd \ --enable-dom --enable-xml --enable-fpm --with-libdir=lib64 --enable-bcmath - #编译安装 + + # 编译安装 make make install ``` + - 配置 ```ini - #复制配置文件 + # 复制配置文件 cp php.ini-production /opt/php/etc/php.ini cp /opt/php/etc/php-fpm.conf.default /opt/php/etc/php-fpm.conf - #修改 /opt/php/etc/php.ini 的下面选项 + + # 修改 /opt/php/etc/php.ini 的下面选项 max_execution_time = 300 memory_limit = 128M post_max_size = 16M @@ -68,12 +74,15 @@ categories: ["zabbix"] max_input_time = 300 date.timezone PRC always_populate_raw_post_data = -1 - #php 与 mysql 同机可指定 mysql 本地套接字 + + # php 与 mysql 同机可指定 mysql 本地套接字 pdo_mysql.default_socket = /tmp/mysql.sock #指定数据库本地套接字地址 mysqli.default_socket = /tmp/mysql.sock #指定数据库本地套接字地址 - #修改 /opt/php/etc/php-fpm.conf 的下面选项 + + # 修改 /opt/php/etc/php-fpm.conf 的下面选项 user = nobody group = nobody + # php 与 nginx 同机可指定 php 套接字,供 nginx 配置使用 #listen = 127.0.0.1:9000 listen = /dev/shm/phpfpm.sock @@ -81,6 +90,7 @@ categories: ["zabbix"] listen.group = nobody listen.mode = 0660 ``` + - 启动 ```bash /opt/php/sbin/php-fpm @@ -93,25 +103,30 @@ categories: ["zabbix"] - 下载 [nginx-1.12.1.tar.gz](http://nginx.org/download/nginx-1.12.1.tar.gz) - 安装 ```bash - #解压 + # 解压 tar zxf nginx-1.12.1.tar.gz -C /root/ cd /root/nginx-1.12.1/ - #安装依赖包 + + # 安装依赖包 yum install pcre pcre-devel openssl openssl-devel - #创建安装目录 + + # 创建安装目录 mkdir /opt/nginx-1.12.1 ln -s /opt/nginx-1.12.1 /opt/nginx - #检查编译环境 + + # 检查编译环境 ./configure --prefix=/opt/nginx \ --with-http_ssl_module --with-pcre \ --with-http_stub_status_module - #编译安装 + + # 编译安装 make make install ``` + - 配置 - ```c - #在 /opt/nginx/conf/nginx.conf 中配置 php + ``` + # 在 /opt/nginx/conf/nginx.conf 中配置 php server { listen 80; index index.php index.html index.html; @@ -135,6 +150,7 @@ categories: ["zabbix"] } } ``` + - 启动 ```bash /opt/nginx/sbin/nginx @@ -146,21 +162,26 @@ categories: ["zabbix"] - 下载 [zabbix-3.0.10.tar.gz](https://jaist.dl.sourceforge.net/project/zabbix/ZABBIX%20Latest%20Stable/3.0.10/zabbix-3.0.10.tar.gz) - 安装 ```bash - #解压 + # 解压 tar zxf zabbix-3.0.10.tar.gz -C /root/ cd /root/zabbix-3.0.10/ - #安装依赖包 + + # 安装依赖包 yum install snmp-devel curl-devel - #创建安装目录 + + # 创建安装目录 mkdir /opt/zabbix-server-3.0.10 ln -s /opt/zabbix-server-3.0.10 /opt/zabbix-server - #检查编译环境 + + # 检查编译环境 ./configure --prefix=/opt/zabbix-server/ --enable-server \ - --enable-agent --with-mysql --with-net-snmp --with-libcurl --with-libxml2 - #编译安装 + --enable-agent --with-mysql --with-net-snmp --with-libcurl --with-libxml2 + + # 编译安装 make make install ``` + - 创建数据库 ```bash mysql -uroot -p12345678 @@ -174,24 +195,28 @@ categories: ["zabbix"] mysql -uzbx -pzbx_pass db_zbx < database/mysql/images.sql mysql -uzbx -pzbx_pass db_zbx < database/mysql/date.sql ``` + - 配置 ```ini - #在 /opt/zabbix-server/etc/zabbix_server.conf 中,修改如下配置 + # 在 /opt/zabbix-server/etc/zabbix_server.conf 中,修改如下配置 DBHost=localhost DBName=db_zbx DBUser=zbx DBPassword=zbx_pass - #这里的数据库是 mysql 且 DBHost 配置为 localhost,zabbix 会使用 mysql.sock 连接 mysql + + # 这里的数据库是 mysql 且 DBHost 配置为 localhost,zabbix 会使用 mysql.sock 连接 mysql DBSocket=/tmp/mysql.sock DBPort=3306 AllowRoot=1 - #在 /opt/zabbix-server/etc/zabbix_agentd.conf 中,修改如下配置 + + # 在 /opt/zabbix-server/etc/zabbix_agentd.conf 中,修改如下配置 EnableRemoteCommands=1 Server=127.0.0.1 ServerActive=127.0.0.1 Hostname=127.0.0.1 AllowRoot=1 ``` + - 启动 ```bash /opt/zabbix-server/sbin/zabbix_server @@ -203,6 +228,7 @@ categories: ["zabbix"] ```bash cp -ar frontends/php /opt/nginx/html/zabbix ``` + - 浏览器打开 http://192.168.1.100/zabbix/ - 根据界面提示配置数据库及相关 zabbix 信息,生成配置文件 /opt/nginx/html/zabbix/conf/zabbix.conf.php - 修改 /opt/nginx/html/zabbix/conf/zabbix.conf.php @@ -216,32 +242,37 @@ categories: ["zabbix"] - 浏览器输入 http://192.168.1.100/zabbix/ - 默认用户名: admin ,默认密码: zabbix -# 在被监控服务器 (192.168.1.101) 上安装 Zabbix Agent +# 安装 Zabbix Agent - 推荐 Zabbix 3.0 及以上版本。 - 安装方式很多,这里使用官方源码编译: - 下载 [zabbix-3.0.10.tar.gz](https://jaist.dl.sourceforge.net/project/zabbix/ZABBIX%20Latest%20Stable/3.0.10/zabbix-3.0.10.tar.gz) (同 server) - 安装 ```bash - #解压 + # 解压 tar zxf zabbix-3.0.10.tar.gz -C /root/ cd /root/zabbix-3.0.10/ - #创建安装目录 + + # 创建安装目录 mkdir /opt/zabbix - #检查编译环境 + + # 检查编译环境 ./configure --prefix=/opt/zabbix --enable-agent - #编译安装 + + # 编译安装 make make install ``` + - 配置 ```ini - #在 /opt/zabbix/etc/zabbix-agentd.conf 中,修改如下配置 + # 在 /opt/zabbix/etc/zabbix-agentd.conf 中,修改如下配置 EnableRemoteCommands=1 Server=192.168.1.100 ServerActive=192.168.1.100 Hostname=192.168.1.101 AllowRoot=1 ``` + - 启动 ```bash /opt/zabbix/sbin/zabbix_agentd