Monthly Archives: 6月 2018

6月 8th, 2018

有时候使用可变变量名是很方便的。就是说,一个变量的变量名可以动态的设置和使用。一个普通的变量通过声明来设置,例如:

一个可变变量获取了一个普通变量的值作为这个可变变量的变量名。在上面的例子中 hello 使用了两个美元符号($)以后,就可以作为一个可变变量的变量了。例如:

这时,两个变量都被定义了:$a 的内容是“hello”并且 $hello 的内容是“world”。因此,以下语句:

与以下语句输出完全相同的结果:

它们都会输出:hello world。

要将可变变量用于数组,必须解决一个模棱两可的问题。这就是当写下 $$a[1] 时,解析器需要知道是想要 $a[1] 作为一个变量呢,还是想要$$a 作为一个变量并取出该变量中索引为 [1] 的值。

解决此问题的语法是,对第一种情况用 ${$a[1]},对第二种情况用 ${$a}[1]。

类的属性也可以通过可变属性名来访问。可变属性名将在该调用所处的范围内被解析。例如,对于 $foo->$bar 表达式,

则会在本地范围来解析 $bar 并且其值将被用于 $foo 的属性名。

对于 $bar 是数组单元时也是一样。

6月 7th, 2018

首先,你得有台云主机Vps。国内的话有阿里云、腾讯云这些。由于一些不可描述的原因,我选择的是部署在香港的 VPS,懂的都懂,其实我这台 VPS 主要是服务于 SS。当然一台买了这个 VPS 只拿来做 SS 服务有点浪费啊,而且部署在 github page 上的静态博客访问其实挺慢的,然后因为不想备案的原因,还无法用到国内大厂的 CDN 加速服务,于是萌生了干脆把博客静态指向到 VPS 的 IP 算了。

然后你还得买个域名,这总不能用 IP 来访问吧,太low。

安装 Nginx

在这里就不累赘了

配置 Nginx

配置文件在 /etc/nginx/nginx.conf

其中配置了两个 server,一个 80 端口的是 HTTP,一个 443 端口的是 HTTPS,这里强制让 80 端口重定向到了 HTTPS。

user root;
worker_processes 4;
pid /run/nginx.pid;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable “msie6”;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_http_version 1.1;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
#include /etc/nginx/conf.d/*.conf;
#include /etc/nginx/sites-enabled/*;
server {
listen 80;
server_name www.anany.vip anany.vip;
return 301 https://$server_name$request_uri;
}
server{
server_name www.anany.vip anany.vip;
listen 443;
location / {
root /root/blog/pages;
index index.html;
}
ssl on;
ssl_certificate /etc/nginx/anany.vip_bundle.crt;
ssl_certificate_key /etc/nginx/anany.vip.key;
}
}
6月 7th, 2018

操作系统:CentOS 7.x 64位

实现目的:安装部署Memcached服务器

一、防火墙设置

CentOS 7.x默认使用的是firewall作为防火墙,这里改为iptables防火墙。

1、关闭firewall:

systemctl stop firewalld.service #停止firewall

systemctl disable firewalld.service #禁止firewall开机启动

2、安装iptables防火墙

yum install iptables-services #安装

vi /etc/sysconfig/iptables #编辑防火墙配置文件

# sample configuration for iptables service

# you can edit this manually or use system-config-firewall

# please do not ask us to add additional ports/services to this default configuration

*filter

:INPUT ACCEPT [0:0]

:FORWARD ACCEPT [0:0]

:OUTPUT ACCEPT [0:0]

-A INPUT -m state –state RELATED,ESTABLISHED -j ACCEPT

-A INPUT -p icmp -j ACCEPT

-A INPUT -i lo -j ACCEPT

-A INPUT -p tcp -m state –state NEW -m tcp –dport 22 -j ACCEPT

-A INPUT -p tcp -m state –state NEW -m tcp –dport 11211 -j ACCEPT

-A INPUT -j REJECT –reject-with icmp-host-prohibited

-A FORWARD -j REJECT –reject-with icmp-host-prohibited

COMMIT

:wq! #保存退出

systemctl restart iptables.service #最后重启防火墙使配置生效

systemctl enable iptables.service #设置防火墙开机启动

/usr/libexec/iptables/iptables.init restart #重启防火墙

二、关闭SELINUX

vi /etc/selinux/config

#SELINUX=enforcing #注释掉

#SELINUXTYPE=targeted #注释掉

SELINUX=disabled #增加

:wq! #保存退出

setenforce 0 #使配置立即生效

三 、系统约定

软件源代码包存放位置:/usr/local/src

源码包编译安装位置:/usr/local/软件名字

四、下载软件包

1、下载libevent

http://ftp.lfs-matrix.net/pub/blfs/conglomeration/libevent/libevent-2.0.22-stable.tar.gz

2、下载memcached

http://memcached.org/files/memcached-1.4.34.tar.gz

五、安装编译工具包

yum install -y apr* autoconf automake bison bzip2 bzip2* cloog-ppl compat* cpp curl curl-devel fontconfig fontconfig-devel freetype freetype* freetype-devel gcc gcc-c++ gtk+-devel gd gettext gettext-devel glibc kernel kernel-headers keyutils keyutils-libs-devel krb5-devel libcom_err-devel libpng libpng-devel libjpeg* libsepol-devel libselinux-devel libstdc++-devel libtool* libgomp libxml2 libxml2-devel libXpm* libxml* libtiff libtiff* make mpfr ncurses* ntp openssl openssl-devel patch pcre-devel perl php-common php-gd policycoreutils telnet t1lib t1lib* nasm nasm* wget zlib-devel

六、安装配置memcached

1、安装libevent

cd /usr/local/src

tar zxvf libevent-2.0.22-stable.tar.gz

cd libevent-2.0.22-stable

./configure –prefix=/usr/local/libevent

make

make install

2、安装memcached

cd /usr/local/src

tar zxvf memcached-1.4.34.tar.gz

cd memcached-1.4.34

./configure –enable-sasl –prefix=/usr/local/memcached -with-libevent=/usr/local/libevent

make

make install

3、测试Memcached

groupadd memcached #创建组

useradd -g memcached memcached -s /bin/false #创建账号

ln -s /usr/local/memcached/bin/memcached /usr/local/bin/memcached #添加软连接

启动Memcache的服务器端的命令为:

/usr/local/memcached/bin/memcached -d -m 4096 -u root -l 192.168.4.6 -p 11211 -c 1024 -P /usr/local/memcached/memcached.pid

或者

/usr/local/memcached/bin/memcached -d -m 4096 -u memcached -l 192.168.4.6 -p 11211 -c 1024

参数说明:

-d选项是启动一个守护进程,

-m是分配给Memcache使用的内存数量,单位是MB,这里是4096MB

-u是运行Memcache的用户,比如root或者memcached

-l是监听的服务器IP地址,这里指定服务器的IP地址192.168.4.6,不设置默认监听服务器所有IP地址

-p是设置Memcache监听的端口,默认为11211

-c选项是最大运行的并发连接数,默认是1024

-P是设置保存Memcache的pid文件,/usr/local/memcached/memcached.pid

开机自启动,在/etc/rc.d/rc.local中加入一行

/usr/local/memcached/bin/memcached -d -m 4096 -u root -l 192.168.4.6 -p 11211 -c 1024 -P /usr/local/memcached/memcached.pid

也可以使用下面的命令:

/usr/local/memcached/bin/memcached -d -m 4096 -p 11211 -u memcached

ip不指定时,默认监听本地所有ip地址,用户最好选择是非root用户,例如memcached

关闭Memcached服务

cat /usr/local/memcached/memcached.pid #查看进程

kill 22856 #结束进程

或者

killall memcached #结束服务

系统运维 www.osyunwei.com 温馨提醒:qihang01原创内容©版权所有,转载请注明出处及原文链接

4、设置Memcached开机启动

vi /etc/rc.d/init.d/memcached

#!/bin/sh

#

# memcached: MemCached Daemon

#

# chkconfig: – 90 25

# description: MemCached Daemon

#

# Source function library.

. /etc/rc.d/init.d/functions

. /etc/sysconfig/network

MEMCACHED=”/usr/local/memcached/bin/memcached”

start()

{

echo -n $”Starting memcached: ”

daemon $MEMCACHED -u memcached -d -m 4096 -p 11211 -c 1024

echo

}

stop()

{

echo -n $”Shutting down memcached: ”

killproc memcached

echo

}

[ -f $MEMCACHED ] || exit 0

# See how we were called.

case “$1″ in

start)

start

;;

stop)

stop

;;

restart|reload)

stop

start

;;

condrestart)

stop

start

;;

*)

echo $”Usage: $0 {start|stop|restart|reload|condrestart}”

exit 1

esac

exit 0

:wq! #保存退出

chmod 775 /etc/rc.d/init.d/memcached #赋予文件执行权限

chkconfig memcached on #设置开机启动

/etc/rc.d/init.d/memcached start #启动

至此,Linux下Memcached服务器部署完成。

6月 7th, 2018

为了像本地一样访问远程主机上的目录,通常我们会在远程主机上使用nfs来导出目录,并在本地主机上mount这个nfs文件系统。如果是Windows系统,则使用cifs或samba的方式来访问。

但可能我们忽略了一个远程连接最通用的工具:ssh。其实很多和远程有关的行为,基于ssh都能完成,即使是实现像NFS一样的功能。

如何通过ssh来挂载远程目录?需要安装fuse-sshfs包,这个包在epel中提供。使用fuse-sshfs包提供的sshfs工具可以基于ssh直接挂载远程目录,不用像NFS一样还要export。
$ yum -y install fuse-sshfs

$ rpm -ql fuse-sshfs
/usr/bin/sshfs
/usr/share/doc/fuse-sshfs-2.5
/usr/share/doc/fuse-sshfs-2.5/AUTHORS
/usr/share/doc/fuse-sshfs-2.5/COPYING
/usr/share/doc/fuse-sshfs-2.5/ChangeLog
/usr/share/doc/fuse-sshfs-2.5/FAQ.txt
/usr/share/doc/fuse-sshfs-2.5/NEWS
/usr/share/doc/fuse-sshfs-2.5/README
/usr/share/man/man1/sshfs.1.gz

例如,挂载192.168.100.150上的根目录”/”到本地的/mnt上。注意:只能挂载远程目录,像普通文件、块设备(如/dev/sda2)等无法挂载。
sshfs root@192.168.100.150:/ /mnt

如此一来,以后可以直接访问本地/mnt来访问远程的根目录。例如复制文件、移动文件、新建文件等等操作。

如果要卸载挂载点。直接umount即可。
umount /mnt

相比于NFS,sshfs更简洁,它是基于fuse模块来实现的,可以认为sshfs所挂载的文件系统是fuse文件系统的一种实现。所谓fuse文件系统,它全称为filesystem in userspace,显然,它是用户空间的文件系统(其实是一个虚拟文件系统),其功能非常强大,可用于实现自己的文件系统。详细信息可以sshfs -h,man sshfs,man fusermount,man mount.fuse。

但是NFS比sshfs要完整的多,nfs毕竟是”小型”分布式文件系统,对数据的一致性、完整性实现的都比较完美,访问权限控制也比sshfs要丰富的多。

总的来说,sshfs可以临时用来快速访问远程文件。

更详细的sshfs,参见下面的

如何使用 SSHFS 通过 SSH 挂载远程的 Linux 文件系统或者目录

写这篇文章的主要目的就是提供一步一步的指导,关于如何使用 SSHFS 通过 SSH 挂载远程的 Linux 文件系统或目录。

这篇文章对于那些无论出于什么目的,希望在他们本地的系统中挂载远程的文件系统的用户或者系统管理员有帮助。我们通过 Linux 系统中的一个安装了 SSHFS 客户端进行实际测试,并且成功的挂载了远程的文件系统。

在我们进一步安装之前,让我们了解一下 SSHFS 的相关内容,以及它是如何工作的。

Sshfs 挂载远程的 Linux 文件系统或者目录

什么是 SSHFS?

SSHFS(Secure SHell FileSystem)是一个客户端,可以让我们通过 SSH 文件传输协议(SFTP)挂载远程的文件系统并且在本地机器上和远程的目录和文件进行交互。

SFTP 是一种通过 SSH 协议提供文件访问、文件传输和文件管理功能的安全文件传输协议。因为 SSH 在网络中从一台电脑到另一台电脑传输文件的时候使用数据加密通道,并且 SSHFS 内置在 FUSE(用户空间的文件系统)内核模块,允许任何非特权用户在不修改内核代码的情况下创建他们自己的文件系统。

在这篇文章中,我们将会向你展示在任意 Linux 发行版上如何安装并且使用 SSHFS 客户端,在本地 Linux 机器上挂载远程的 Linux 文件系统或者目录。

步骤 1:在 Linux 系统上安装 SSHFS

默认情况下,sshfs 包不存在所有的主流 Linux 发行版中,你需要在你的 Linux 系统中启用 epel 仓库,在 Yum 命令行的帮助下安装 SSHFS 及其依赖。

  1. #yum install sshfs
  2. # dnf install sshfs 【在Fedora22+发行版上】
  3. $ sudoapt-get install sshfs 【基于Debian/Ubuntu的系统】

步骤 2:创建 SSHFS 挂载目录

当你安装 SSHFS 包之后,你需要创建一个挂载点目录,在这儿你将要挂载你的远程文件系统。例如,我们在 /mnt/tecmint 下创建挂载目录。

  1. #mkdir/mnt/tecmint
  2. $ sudomkdir/mnt/tecmint 【基于Debian/Ubuntu的系统】

步骤 3:使用 SSHFS 挂载远程的文件系统

当你已经创建你的挂载点目录之后,现在使用 root 用户运行下面的命令行,在 /mnt/tecmint 目录下挂载远程的文件系统。视你的情况挂载目录可以是任何目录。

下面的命令行将会在本地的 /mnt/tecmint 目录下挂载一个叫远程的一个 /home/tecmint 目录。(不要忘了使用你的 IP 地址和挂载点替换 x.x.x.x)。

  1. # sshfs tecmint@x.x.x.x:/home/tecmint/ /mnt/tecmint
  2. $ sudo sshfs -o allow_other tecmint@x.x.x.x:/home/tecmint/ /mnt/tecmint 【基于Debian/Ubuntu的系统】

如果你的 Linux 服务器配置为基于 SSH 密钥授权,那么你将需要使用如下所示的命令行指定你的公共密钥的路径。

  1. # sshfs -o IdentityFile=~/.ssh/id_rsa tecmint@x.x.x.x:/home/tecmint/ /mnt/tecmint
  2. $ sudo sshfs -o allow_other,IdentityFile=~/.ssh/id_rsa tecmint@x.x.x.x:/home/tecmint/ /mnt/tecmint 【基于Debian/Ubuntu的系统】

步骤 4:验证远程的文件系统挂载成功

如果你已经成功的运行了上面的命令并且没有任何错误,你将会看到挂载在 /mnt/tecmint 目录下的远程的文件和目录的列表

  1. #cd/mnt/tecmint
  2. #ls
  3. [root@ tecmint]#ls
  4. 12345.jpg ffmpeg-php-0.6.0.tbz2Linux news-closeup.xsl s3.jpg
  5. cmslogs gmd-latest.sql.tar.bz2 Malware newsletter1.html sshdallow
  6. epel-release-6-5.noarch.rpm json-1.2.1 movies_list.php pollbeta.sql
  7. ffmpeg-php-0.6.0 json-1.2.1.tgz my_next_artical_v2.php pollbeta.tar.bz2

步骤 5:使用 df -hT 命令检查挂载点

如果你运行 df -hT命令,你将会看到远程文件系统的挂载点。

  1. #df-hT

样本输出:

  1. FilesystemTypeSizeUsedAvailUse%Mounted on
  2. udev devtmpfs 730M0730M0%/dev
  3. tmpfs tmpfs 150M4.9M145M4%/run
  4. /dev/sda1 ext4 31G5.5G24G19%/
  5. tmpfs tmpfs 749M216K748M1%/dev/shm
  6. tmpfs tmpfs 5.0M4.0K5.0M1%/run/lock
  7. tmpfs tmpfs 749M0749M0%/sys/fs/cgroup
  8. tmpfs tmpfs 150M44K150M1%/run/user/1000
  9. tecmint@192.168.0.102:/home/tecmint fuse.sshfs 324G55G253G18%/mnt/tecmint

步骤 6:永久挂载远程文件系统

为了永久的挂载远程的文件系统,你需要修改一个叫 /etc/fstab 的文件。照着做,使用你最喜欢的编辑器打开文件。

  1. #vi/etc/fstab
  2. $ sudovi/etc/fstab 【基于Debian/Ubuntu的系统】

移动到文件的底部并且添加下面的一行,保存文件并退出。下面条目表示使用默认的设置挂载远程的文件系统。

  1. sshfs#tecmint@x.x.x.x:/home/tecmint/ /mnt/tecmint fuse.sshfs defaults 00

确保服务器之间允许 SSH 无密码登录,这样系统重启之后才能自动挂载文件系统。

如果你的服务器配置为基于 SSH 密钥的认证方式,请加入如下行:

  1. sshfs#tecmint@x.x.x.x:/home/tecmint/ /mnt/tecmint fuse.sshfs IdentityFile=~/.ssh/id_rsa defaults 00

接下来,你需要更新 fstab 文件使修改生效。

  1. #mount-a
  2. $ sudomount-a 【基于Debian/Ubuntu的系统】

步骤 7:卸载远程的文件系统

为了卸载远程的文件系统,只需要发出以下的命令即可。

  1. #umount/mnt/tecmint
TAGS:
6月 7th, 2018

MariaDB是一个开源的关系数据库管理系统,向后兼容,二进制替换MySQL。它由MySQL的一些原始开发人员以及社区中的许多人开发。随着CentOS 7的发布,MySQL被MariaDB取代为默认的数据库系统。

如果出于任何原因需要安装MySQL,请查看如何在CentOS 7教程上安装MySQL。如果您的应用程序没有任何特定要求,您应该坚持使用MariaDB,这是CentOS 7中的默认数据库系统。

在本教程中,我们将向您展示如何使用官方MariaDB存储库在CentOS 7上安装MariaDB的最新版本。在默认的CentOS仓库中提供的MariaDB服务器版本是5.5版本,不是最新的MariaDB稳定版本。

安装MariaDB

在撰写本文时,MariaDB的最新版本是10.3版本。

创建一个名为MariaDB.repo的存储库文件并添加以下内容:

/etc/yum.repos.d/MariaDB.repo

# MariaDB 10.3 CentOS repository list – created 2018-05-27 07:02 UTC
# http://downloads.mariadb.org/mariadb/repositories/
[mariadb]
name = MariaDB
baseurl = http://yum.mariadb.org/10.3/centos7-amd64
gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
gpgcheck=1

如果您需要安装任何其他版本的MariaDB,请在此[页面](https://downloads.mariadb.org/mariadb/repositories/)上为您需要的MariaDB版本生成一个存储库。

我们将使用yum安装MariaDB服务器和客户端软件包,与其他CentOS软件包相同,方法是键入以下命令:

sudo yum install MariaDB-server MariaDB-client

Yum可能会提示您导入MariaDB GPG密钥:

Retrieving key from https://yum.mariadb.org/RPM-GPG-KEY-MariaDB
Importing GPG key 0x1BB943DB:
Userid    : “MariaDB Package Signing Key <package-signing-key@mariadb.org>”
Fingerprint: 1993 69e5 404b d5fc 7d2f e43b cbcb 082a 1bb9 43db
From      : https://yum.mariadb.org/RPM-GPG-KEY-MariaDB

键入y并按Enter键。

安装完成后,启用并启动MariaDB服务:

sudo systemctl enable mariadb
sudo systemctl start mariadb

一旦MySQL服务启动,我们可以通过输入以下内容来检查它的状态:

sudo systemctl status mariadb

输出示例:

● mariadb.service – MariaDB 10.3.7 database server
Loaded: loaded (/usr/lib/systemd/system/mariadb.service; enabled; vendor preset: disabled)
Drop-In: /etc/systemd/system/mariadb.service.d
└─migrated-from-my.cnf-settings.conf
Active: inactive (dead)
Docs: man:mysqld(8)
https://mariadb.com/kb/en/library/systemd/

并打印MariaDB服务器版本,其中包含:

mysql -V

mysql  Ver 15.1 Distrib 10.3.7-MariaDB, for Linux (x86_64) using readline 5.1

保护MariaDB安全

运行mysql_secure_installation命令来提高MariaDB安装的安全性:

sudo mysql_secure_installation

脚本会提示您设置root用户密码,删除匿名用户,限制root用户对本地计算机的访问权限,并删除测试数据库。 所有步骤都有详细说明,建议对所有问题回答“是”(是)。

从命令行连接到MariaDB

要通过终端连接到MariaDB服务器,我们将使用MariaDB客户端。

您可以通过键入以root用户身份登录到MariaDB服务器:

mysql -u root -p

系统将提示您输入在运行mysql_secure_installation脚本时以前设置的root密码。

一旦你输入密码,你将会看到MariaDB shell,如下所示:

Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 8
Server version: 10.3.7-MariaDB MariaDB Server

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type ‘help;’ or ‘\h’ for help. Type ‘\c’ to clear the current input statement

6月 7th, 2018

自增主键没有持久化是个比较早的bug,这点从其在官方bug网站的id号也可看出(https://bugs.mysql.com/bug.php?id=199)。由Peter Zaitsev(现Percona CEO)于2003年提出。历史悠久且臭名昭著。

首先,直观的重现下。

mysql> create table t1(id int auto_increment primary key);
Query OK, 0 rows affected (0.01 sec)

mysql> insert into t1 values(null),(null),(null);
Query OK, 3 rows affected (0.01 sec)
Records: 3  Duplicates: 0  Warnings: 0

mysql> select * from t1;
+—-+
| id |
+—-+
|  1 |
|  2 |
|  3 |
+—-+
3 rows in set (0.00 sec)

mysql> delete from t1 where id=3;
Query OK, 1 row affected (0.36 sec)

mysql> insert into t1 values(null);
Query OK, 1 row affected (0.35 sec)

mysql> select * from t1;
+—-+
| id |
+—-+
|  1 |
|  2 |
|  4 |
+—-+
3 rows in set (0.01 sec)

虽然id为3的记录删除了,但再次插入null值时,并没有重用被删除的3,而是分配了4。

删除id为4的记录,重启数据库,重新插入一个null值。

mysql> delete from t1 where id=4;
# service mysqld restart
mysql> insert into t1 values(null);
Query OK, 1 row affected (0.00 sec)

mysql> select * from t1;
+—-+
| id |
+—-+
|  1 |
|  2 |
|  3 |
+—-+
3 rows in set (0.00 sec)

可以看到,新插入的null值分配的是3,按照重启前的操作逻辑,此处应该分配5啊。

这就是自增主键没有持久化的bug。究其原因,在于自增主键的分配,是由InnoDB数据字典内部一个计数器来决定的,而该计数器只在内存中维护,并不会持久化到磁盘中。当数据库重启时,该计数器会通过下面这种方式初始化。

SELECT MAX(ai_col) FROM table_name FOR UPDATE;

MySQL 8.0的解决思路

将自增主键的计数器持久化到redo log中。每次计数器发生改变,都会将其写入到redo log中。如果数据库发生重启,InnoDB会根据redo log中的计数器信息来初始化其内存值。为了尽量减小对系统性能的影响,计数器写入到redo log中,并不会马上刷新。具体可参考:https://dev.mysql.com/worklog/task/?id=6204

因自增主键没有持久化而出现问题的常见场景:

1. 业务将自增主键作为业务主键,同时,业务上又要求主键不能重复。

2. 数据会被归档。在归档的过程中有可能会产生主键冲突。

所以,强烈建议不要使用自增主键作为业务主键。刨除这两个场景,其实,自增主键没有持久化的问题并不是很大,远没有想象中的”臭名昭著“。

最后,给出一个归档场景下的解决方案,

创建一个存储过程,根据table2(归档表)自增主键的最大值来初始化table1(在线表)。这个存储过程可放到init_file参数指定的文件中,该文件中的SQL会在数据库启动时执行。

DELIMITER ;;
CREATE PROCEDURE `auto_increment_fromtable2`(IN table1 VARCHAR(255), IN table2 VARCHAR(255))
BEGIN
set @qry = concat(‘SELECT @max1 := (`id` + 1) FROM `’,table1,’` ORDER BY `id` DESC LIMIT 1;’);
prepare stmt from @qry;
execute stmt;
deallocate prepare stmt;
set @qry = concat(‘SELECT @max2 := (`id` + 1) FROM `’,table2,’` ORDER BY `id` DESC LIMIT 1;’);
prepare stmt from @qry;
execute stmt;
deallocate prepare stmt;
IF @max1 < @max2 THEN
set @qry = concat(‘alter table `’,table1,’` auto_increment=’,@max2);prepare stmt from @qry;execute stmt;deallocate prepare stmt;
SELECT ‘updated’ as `status`;
else
SELECT ‘no update needed’ as `status`;
END IF;
END ;;
DELIMITER ;

TAGS:
6月 6th, 2018

Oracle已经发布了他们的开源关系数据库管理系统MySQL 8。这个版本引入了许多改进,最受关注的可能是基于文档的存储,开发人员可以在同一个数据库中使用传统关系数据和“NoSQL”文档数据。该版本还提升了性能,增强了安全性,并改变了默认字符集以促进“移动优先”开发。

MySQL在MySQL 5.7中引入了对JSON的支持,现在在8.0里带来了MySQL文档存储,开发人员可以将无模式JSON文档集合与关系表放在一起使用。MySQL文档存储由一系列技术组成,一个新的客户端协议、X协议以及让MySQL服务器能够使用X协议的X插件。新的X DevAPI是一组异步API,用于在X协议上执行CRUD和SQL操作。MySQL连接器是一组驱动程序,开发人员可以基于驱动程序使用Java、Python、Node、.Net和C ++等主流开发语言来调用API和文档存储。文档存储中还有一个MySQL Shell,提供了交互式的Javascript、Python或SQL接口来支持MySQL服务器的开发和管理。

Geir Høydalsvik自2008年以来一直在MySQL数据库团队中工作,他告诉InfoQ:“文档存储和关系数据库的结合是一个关键特性。用户现在可以拥有一个坚实的数据库系统,可以同时服务于SQL和NoSQL”。

MySQL并不是开源领域中第一个支持关系数据和基于文档数据的数据库,比如PostgreSQL已经推出该特性一段时间了。

与之前的版本相比,MySQL 8.0还带来了显着的性能改进。发行说明指出,MySQL 8.0速度是5.7的两倍。基准测试数据显示,在以每秒查询数量作为衡量手段的情况下,随着用户数量的增加,性能出现差异。基准测试数据还显示,MySQL 8实现了每秒高达180万次查询的新纪录。数据字典元数据的整合提高了可靠性,这些元数据之前以多种文件格式进行存储,并存储在多个位置,现在则存储在一组SQL表中,并使用默认的InnoDB存储引擎。

MySQL 8带来了多项安全性改进,其中之一引入了SQL角色。与大多数应用程序一样,MySQL 8中的角色代表一个指定的授权集合。现在可以在单个会话中创建、授予、删除和应用MySQL角色。数据库还提供了一个新的SQL函数ROLES_GRAPHML(),它返回一个代表角色子图的graphml文档。另一个安全增强是对密码重用的限制。MySQL已经支持密码过期策略,该策略强制要求用户在一段时间之后更改密码,而新版本可以控制用户设置的密码是否有效。这限制了密码重用,从而强制用户在每次更改密码时提供新的增强密码。

默认字符集已从latin-1改为utf8mb4。在移动世界中,emojis和各种各样的字符集需要共存,Unicode/UTF-8编码已经变得无处不在,所以做出了这一变化。由于性能原因,以前的utf8mb3已被弃用。

移动应用的特征之一是使用用户的位置来提供内容,MySQL 8.0基于现有的GIS支持,引入了地理和空间参考系统(SRS)。

8.0版还带来了一些SQL增强功能。其中之一是引入公共表表达式(CTE),这是ANSI SQL 99(又名“SQL 3”)规范的一部分。它们是带有名称的临时结果集,存在于单个语句的作用域内,可以在语句的其他部分进行引用。还增加了一些窗口函数,用于降低代码复杂度。

发布白皮书中可以找到有关MySQL 8的全部细节。

查看英文原文MySQL Version 8 Adds Document Store, Performance and Security Improvements

6月 6th, 2018

曾多次想要在Linux下比较目录a和目录b中文件列表的差别,然后对目录a比目录b中多出的文件、少掉的文件分别做处理。但是,在网上搜索了多次也都没找到能直接处理好的工具。

所以想了很多不少方法,自我感觉都不错,而且网上似乎没有这方面的文章,所以分享出来给大家。如果各位有更好的工具或者方法,盼请留下说明(本文第2部分:图形化的比较结果搜集自网上,我也没有在图形化界面下操作的需要,所以没有多做介绍)

以下是本文有些地方涉及到的目录结构。
[root@node1 ~]# tree directory1 directory2
directory1
├── 1.png
├── 2.png
└── 3.png
directory2
├── 2.png
├── 3.png
└── 4.png

1.命令行输出的结果

方法一:使用diff
diff -r directory1 directory2

但是diff会对每个文件中的每一行都做比较,所以文件较多或者文件较大的时候会非常慢。请谨慎使用。

方法二:使用diff结合tree
diff <(tree -Ci –noreport /mnt/f/自然马) <(tree -Ci –noreport /mnt/i/自然马)
< /mnt/f/自然马

> /mnt/i/自然马
87a88
> xyz.avi
488d488
< rsync.txt
534d533
< 542D0.mp4

说明:
1.tree的-C选项是输出颜色,如果只是看一下目录的不同,可以使用该选项,但在结合其他命令使用的时候建议不要使用该选项,因为颜色也会转换为对应的编码而输出;

2.-i是不缩进,建议不要省略-i,否则diff的结果很难看,也不好继续后续的文件操作;

3.–noreport是不输出报告结果,建议不要省略该选项。

4.该方法效率很高。

方法三:find结合diff
find directory1 -printf “%P\n” | sort > file1
find directory2 -printf “%P\n” | sort | diff file1 –
2d1
< 1.png
4a4
> 4.png

说明:
1.<代表的行是directory1中有而directory2没有的文件,>则相反,是directory2中有而directory1中没有。

2.不要省略-printf “%P\n”,此处的%P表示find的结果中去掉前缀路径,详细内容man find。例如,find /root/ -printf “%P\n”的结果中将显示/root/a/xyz.txt中去掉/root/后的结果:a/xyz.txt。
3.效率很高,输出也简洁。

如果不想使用-printf,那么先进入各目录再find也行。
[root@node1 ~]# (cd /root/a;find . | sort >/tmp/file1)
[root@node1 ~]# (cd /root/b;find . | sort | diff /tmp/file1 -)
2d1
< ./1.png
4a4
> ./4.png

上面将命令放进括号中执行是为了在子shell中切换目录,不用影响当前所在目录。

方法四:使用rsync
rsync -rvn –delete directory1/ directory2 | sed -n ‘2,/^$/{/^$/!p}’
deleting a/xyz.avi
rsync.txt
新建文件夹/542D0.mp4

其中deleting所在的行就是directory2中多出的文件。其他的都是directory中多出的文件。

如果想区分出不同的是目录还是文件。可以加上”-i”选项。
rsync -rvn -i –delete directory1/ directory2 | sed -n ‘2,/^$/{/^$/!p}’
*deleting  a/xyz.avi
>f+++++++++ rsync.txt
>f+++++++++ 新建文件夹/542D0.mp4

其中>f+++++++++中的f代表的是文件,d代表的目录。

上面的rsync比较目录有几点要说明:
1.一定不能缺少-n选项,它表示dry run,也就是试着进行rsync同步,但不会真的同步。

2.第一个目录(directory1/)后一定不能缺少斜线,否则表示将directory1整个目录同步到directory2目录下。

3.其它选项,如”-r -v –delete”也都不能缺少,它们的意义想必都知道。

4.sed的作用是过滤掉和文件不相关的内容。
5.以上rsync假定了比较的两个目录中只有普通文件和目录,没有软链接、块设备等特殊文件。如果有,请考虑加上对应的选项或者使用-a替代-r,否则结果中将出现skipping non-regular file的提示。但请注意,如果有软链接,且加了对应选项(-l或-a或其他相关选项),则可能会出现fileA–>fileB的输出。
6.效率很高,因为rsync的原因,筛选的可定制性也非常强。

2.图形化的比较结果

方法一:使用vimdiff
vimdiff <(cd directory1; find . | sort) <(cd directory2; find . | sort)
# 或者
vimdiff <(find directory1 -printf “%P\n”| sort) <(find directory2 -printf “%P\n”| sort)

方法二:使用meld

meld是python写的一个图形化文件/目录比较工具,所以必须先安装图形界面或设置好图形界面接受协议。它的功能非常丰富,和win下的beyond compare有异曲同工之妙。

meld具体的使用方式就不介绍了。

3.将两目录中不同的文件筛选出来

个人建议使用命令行输出的结果中的方法方法三和方法四,因为它们都能很好地保留目录前缀。

以方法三为例:
find directory1 -printf “%P\n” | sort > file1
find directory2 -printf “%P\n” | sort | diff file1 –

以下是实验所需目录结构:
[root@node1 ~]# tree /root/a;tree /root/b
/root/a
├── 1.png
├── 2.png
└── 3.png

0 directories, 3 files
/root/b
├── 2.png
├── 3.png
├── 4.png
└── xen
└── scripts
└── block-drbd

首先比较这两个目录得到文件列表的差异。
find /root/a -printf “%P\n” | sort > /tmp/file1
find /root/b -printf “%P\n” | sort | diff /tmp/file1 – >diff.txt

然后从diff.txt中过滤出/root/a中多出的文件和/root/b中多出的文件。
# /root/a中多出的文件
awk ‘/</{printf(“%s%s\n”,”/tmp/etc/”,$2)}’ diff.txt
/tmp/etc/1.png

# /root/b中多出的文件
awk ‘/>/{printf(“%s%s\n”,”/tmp/etc/”,$2)}’ diff.txt
/tmp/etc/4.png
/tmp/etc/xen
/tmp/etc/xen/scripts
/tmp/etc/xen/scripts/block-drbd

需要注意的是,如果多了某个目录,则这个目录和其内所有文件都会列出来。如果要将多出的文件复制到其他地方,应当要注意这一点。

如果只想要比较出/root/a和/root/b下的文件和目录的不同,不再递归到子目录中比较。那么可以在find上继续加工一番:
find /root/a -maxdepth 1 -printf “%P\n” | sort > /tmp/file1
find /root/b -maxdepth 1 -printf “%P\n” | sort | diff /tmp/file1 – >diff.txt
# /root/a中多出的文件
awk ‘/</{printf(“%s%s\n”,”/tmp/etc/”,$2)}’ diff.txt
/tmp/etc/1.png

# /root/b中多出的文件
awk ‘/>/{printf(“%s%s\n”,”/tmp/etc/”,$2)}’ diff.txt
/tmp/etc/4.png
/tmp/etc/xen

这样一来,/root/b中多出的文件就是4.png和xen,xen目录中的文件不再列出。

6月 6th, 2018

sudo命令旨在允许用户使用其他用户的安全权限运行程序,默认情况下是root用户。 在本指南中,我们将向您展示如何在CentOS Linux 7.5上创建具有sudo权限的新用户。

创建sudo用户的步骤

1)以root用户身份登录到您的CentOS服务器:

ssh root@server_ip_address

2)使用useradd命令创建一个新的用户帐户:

useradd username

将username替换为您要创建的用户名。

3)使用passwd命令为新用户设置密码:

passwd username

输出:

Changing password for user username.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.

4)将新用户添加到组成员。

usermod -aG wheel username

找到授予sudo访问权的文件中的行

在CentOS默认情况下,组轮中的用户被授予sudo访问权限。

如何使用sudo

切换到新创建的用户:

su – username

要使用sudo,只需在命令前加上sudo和一个空格即可。

sudo ls -l /root

您第一次使用此帐户中的sudo时,您将看到以下标题消息,并且系统会提示您输入用户帐户的密码。

输出:

We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.

[sudo] password for username:

就这样! 如果您有任何问题,请随时留下评论。

6月 6th, 2018

Pip是一个软件包管理系统,它简化了用Python编写的软件包(如Python包索引(PyPI)中的软件包)的安装和管理。在CentOS Linux 7.5上默认不安装Pip,但安装非常简单。

在本教程中,我们将介绍如何使用yum软件包管理器在CentOS 7上安装Pythonpip,并介绍如何使用pip安装和管理Python软件包的基础知识。

前提条件

在全局安装Python模块时,您应该更愿意使用yum来安装发行版提供的Python模块,因为它们已经过测试,可以在CentOS 7上正常运行。只有在没有用于Python模块的rpm包时,才可以使用pip来全局安装Python模块。

在大多数情况下,你只能在虚拟环境中使用pip。 Python虚拟环境允许您将Python模块安装在特定项目的隔离位置,而不是全局安装。这样您就不必担心影响其他Python项目。

添加EPEL存储库

Pip在CentOS 7核心存储库中不可用。要安装pip,我们需要启用EPEL存储库:

sudo yum install epel-release

1

安装Pip

一旦启用EPEL存储库,我们可以使用以下命令安装pip及其所有依赖项:

sudo yum install python-pip

2

验证Pip安装

要验证点是否正确安装,请运行以下命令,该命令将打印pip版本:

pip –version

版本号可能会有所不同,但它看起来像这样:

pip 8.1.2 from /usr/lib/python2.7/site-packages (python 2.7)

3

安装开发工具

开发工具是构建Python模块所必需的,您可以通过以下方式安装它们:

sudo yum install python-devel

4

sudo yum groupinstall ‘development tools’

5

Pip用法

在本节中,我们会考虑一些有用的基本pip命令。 使用pip,我们可以从PyPI,版本控制,本地项目和分发文件安装软件包。 通常你会从PyPI安装软件包。

假设我们想要安装一个名为twisted的包,我们可以通过发出以下命令来实现:

pip install twisted

6

twisted是一个用Python编写的异步网络框架。

卸载程序包运行:

pip uninstall twisted

7

从PyPI搜索软件包:

pip search “twisted”

8

列出已安装的软件包:

pip list

9

要列出过期的软件包:

pip list –outdated

总结

您现在应该在您的CentOS 7服务器上安装pip,并且您可以轻松安装和卸载Python模块。 有关pip的更多信息,请查看pip用户指南。 如果您有任何问题或意见,请随时在下面发表评论。

TAGS: