Docker nginx 反向代理设置

缘起

最近在公司搭建了一个基于 Gogs 的代码管理系统,以及基于 Kanboard 的任务管理系统等几个内部系统。由于部署在同一台机器上,基于不同的端口区分不同的服务。比如:

  • Git 服务 http://10.10.1.110:10080
  • 任务管理系统http://10.10.1.110:8888
  • 其他

为了更好的使用,通过内部域名区分,比如 :

  • Git 服务 http://gogs.vking.io
  • 任务管理系统 http://task.vking.io
  • 其他

注:vking.io 是内部域名,可通过 dnsmasq (http://www.thekelleys.org.uk/dnsmasq/doc.html) 配置。

方案一

现有服务都是通过 Docker 部署,nginx 同样通过 Docker 部署,使用官方提供的镜像即可。

  • 新建 nginx 配置文件, nginx.conf,存放路径为 /srv/docker/nginx/nginx.conf
# user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}
# daemon off;
  • 新建反向代理设置文件 reverse-proxy.conf,存放路径为 /srv/docker/nginx/conf.d/reverse-proxy.conf
# If we receive X-Forwarded-Proto, pass it through; otherwise, pass along the
# scheme used to connect to this server
map $http_x_forwarded_proto $proxy_x_forwarded_proto {
  default $http_x_forwarded_proto;
  ''      $scheme;
}
# If we receive X-Forwarded-Port, pass it through; otherwise, pass along the
# server port the client connected to
map $http_x_forwarded_port $proxy_x_forwarded_port {
  default $http_x_forwarded_port;
  ''      $server_port;
}
# If we receive Upgrade, set Connection to "upgrade"; otherwise, delete any
# Connection header that may have been passed to this server
map $http_upgrade $proxy_connection {
  default upgrade;
  '' close;
}
# Apply fix for very long server names
server_names_hash_bucket_size 128;
# Default dhparam
ssl_dhparam /etc/nginx/dhparam/dhparam.pem;
# Set appropriate X-Forwarded-Ssl header
map $scheme $proxy_x_forwarded_ssl {
  default off;
  https on;
}
gzip_types text/plain text/css application/javascript application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
log_format vhost '$host $remote_addr - $remote_user [$time_local] '
                 '"$request" $status $body_bytes_sent '
                 '"$http_referer" "$http_user_agent"';
access_log off;

# HTTP 1.1 support
proxy_http_version 1.1;
proxy_buffering off;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $proxy_connection;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $proxy_x_forwarded_proto;
proxy_set_header X-Forwarded-Ssl $proxy_x_forwarded_ssl;
proxy_set_header X-Forwarded-Port $proxy_x_forwarded_port;
# Mitigate httpoxy attack (see README for details)
proxy_set_header Proxy "";
server {
    server_name _; # This is just an invalid value which will never trigger on a real hostname.
    listen 80;
    access_log /var/log/nginx/access.log vhost;
    return 503;
}

# gogs.vking.io
upstream gogs.vking.io {
    # gogs
    server gogs:3000;
}

server
{
    server_name gogs.vking.io;
    listen 80;

    location / {
        proxy_pass http://gogs.vking.io;
    }
    access_log /var/log/nginx/access.log vhost;
}

# task.vking.io
upstream task.vking.io {
    # kanboard
    server kanboard:80;
}

server
{
    server_name task.vking.io;
    listen 80;

    location / {
        proxy_pass http://task.vking.io;
    }
    access_log /var/log/nginx/access.log vhost;
}

gogs 启动命令

docker container run -d --name gogs 
    --restart always 
    -p 10022:22  
    -p 10080:3000 
    --network gogs-net 
    -v /srv/docker/gogs:/data 
    gogs/gogs:latest

注: upstream gogs.vking.io 中的 server 中的 gogs:3000 分别指容器名称和原始expose 的端口。

  • 启动容器
docker container run -d --name nginx 
    --restart always 
    -p 80:80 
    --network gogs-net 
    -v /srv/docker/nginx/nginx.conf:/etc/nginx/nginx.conf 
    -v /srv/docker/nginx/conf.d:/etc/nginx/conf.d 
    nginx:alpines

注:–network gogs-net 指定三个容器在同一网络,如果用默认的 bridge的话,不需要设置

方案二

因为这些服务都是部署在一台机器上的,可以通过 Docker 的自动服务发现部署,原理见此。

  • gogs
docker container run -d --name gogs 
    --restart always 
    -p 10022:22  -p 10080:3000 
    --network gogs-net 
    -e VIRTUAL_HOST=gogs.vking.io 
    -e VIRTUAL_PORT=3000 
    -v /opt/docker/gogs:/data 
    gogs/gogs:latest
  • Kanboard
docker container run -d --name kanboard 
    --restart always 
    -p 8888:80 
    --network gogs-net 
    -e VIRTUAL_HOST=task.vking.io 
    -e VIRTUAL_PORT=80 
    -v /srv/docker/kanboard/data:/var/www/app/data 
    -v /srv/docker/kanboard/plugins:/var/www/app/plugins 
    kanboard/kanboard:latest
  • nginx
docker container run -d --name nginx 
    --restart always 
    -p 80:80 
    --network gogs-net 
    -v /var/run/docker.sock:/tmp/docker.sock:ro 
    jwilder/nginx-proxy:alpine

注:关键是容器通过 -e VIRTUAL_HOST 指定 url,通过 -e VIRTUAL_PORT=80 指定端口,同样端口也必须是原始镜像 expose 的端口。

延伸

目前服务都是通过 shell 启动,可改成通过 Docker Compose 统一编排任务,把 dnsmasq+nginx+gogs+… 等统一管理。如果是部署在公网上的话,还可以把 SSL 证书到期自动刷新等一起编排。

—EOF—

Apache配置http跳转https教程

用我的步骤前,请一定要保证自己的网站能够用https正常打开;方法也是非常的简单,具体步骤如下:

一、登陆服务器

不管你的服务器是linux还是windos,原理都是一样的,我拿windos服务器来举例吧!
登陆windos服器方法很简单,需要“远程桌面连接”。
我们直接点击左下角“开始” =》 “运行”,(或使用“WIN+R”快捷键),再输入”mstsc”即可打开远程桌面连接,输入你的IP+用户名+密码即可远程连接成功;

二、打开url重定向伪静态规则支持

1、打开Apache/conf/httpd.conf;

2、找到 #LoadModule rewrite_module modules/mod_rewrite.so;

3、去掉前面的#号;#LoadModule rewrite_module modules/mod_rewrite.so

未分类

三、修改网站目录的段:Directory

1、打开Apache/conf/httpd.conf;

2、找到你网站目录的段,例如我的是:“C:phpStudyPHPTutorialWWW”

3、修改其中的 AllowOverride None 为 AllowOverride All;

未分类

四、保存并重启apache服务

五、设置重定向伪静态规则

1、在你网站目录下放一个.htaccess文件。注意:windows环境下,不能把文件直接改名为.htaccess,会提示你必须输入文件名。所以我们先新建一个“新建文本文档.txt”文档,再用记事本打开,选择另存为,保存类型选择“所有文件(.)”,文件名输入“.htaccess”,保存。这样便生成了一个.htaccess文件。

2、打开并编辑.htaccess文件,写入如下规则:

RewriteEngine on
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{REQUEST_URI} !^/tz.php
RewriteRule (.*) https://%{SERVER_NAME}/$1 [R]

解释:

%{SERVER_PORT} —— 访问端口
%{REQUEST_URI} —— 比如如果url是 https://www.fujieace.com/tz.php,则是指 /tz.php
%{SERVER_NAME} —— 比如如果url是 https://www.fujieace.com/tz.php,则是指 www.fujieace.com

以上规则的意思是:

如果访问的url的端口不是443,且访问页面不是tz.php,则应用RewriteRule这条规则。
这样便实现了:访问了 https://www.fujieace.com/index.php 或者 https://www.fujieace.com/admin/index.php 等页面的时候会自动跳转到 https://www.fujieace.com/index.php 或者 https://www.fujieace.com/admin/index.php,
但是访问 https://www.fujieace.com/tz.php 的时候就不会做任何跳转,也就是说 https://www.fujieace.com/tz.php 和 https://www.fujieace.com/tz.php 两个地址都可以访问。

apache https配置

1、修改httpd.conf,将以下注释项放开

#LoadModule ssl_module modules/mod_ssl.so
#LoadModule socache_shmcb_module 
#modules/mod_socache_shmcb.so
#Include conf/extra/httpd-mpm.conf
#Include conf/extra/httpd-ssl.conf

2、修改httpd-ssl.conf,配置以下配置项

SSLCertificateKeyFile “”    //服务器私钥位置
SSLCertificateFile “”   //服务器证书位置
SSLCACertificatePath “”  //CA根证书位置

3、放开将注释项

#SSLVerifyClient require
#SSLVerifyDepth  10
修改SSLVerifyDepth 为1

4、执行httpd.exe

-t检查语法配置是否有误,一般都是文件路径的问题。
重新配置vhost,端口改443,重启apache,验证是否生效。

通过apache创建一个yum仓库

通过Apache创建一个自己的yum仓库,当然你也可以使用ftp,本文只是一个简单的演示。

当前演示环境,Centos7.4,关闭selinux,关闭防火墙,当前ip192.168.1.108

1、挂载光盘镜像

mount /dev/cdrom /mnt

2、安装Apache并启动服务

yum install httpd -y
systemctl start httpd
systemctl enable httpd

此时打开http://192.168.1.108即可看到Testing 123..

3、拷贝光盘镜像文件

这里你可以拷贝光盘镜像文件到/var/www/html目录,我这里直接使用了软连接

ln -sv /mnt/ /var/www/html/

此时打开http://192.168.1.108/mnt即可看到如下页面

未分类

4、配置yum仓库

vi /etc/yum.repos.d/isoyum.repo
[isoyum]
name=isoyum
baseurl=http://192.168.1.108/mnt/
gpqcheck=1
gpqkey=http://192.168.1.108/mnt/RPM-GPG-KEY-CentOS-7

配置完成后执行,即可看到新添加的yum仓库已经生效了

yum clean all && yum makecache

未分类

nginx安装lua/replace-filter-nginx-module

nginx加载lua和replace-filter-nginx-module模块

一、lua部分

首先下载和安装部分模块

1、下载安装LuaJIT

官网:http://luajit.org/
下载链接:http://luajit.org/download/LuaJIT-2.1.0-beta3.tar.gz

wget http://luajit.org/download/LuaJIT-2.1.0-beta3.tar.gz
tar zxvf LuaJIT-2.1.0-beta3.tar.gz
cd LuaJIT-2.1.0-beta3
make PREFIX=/usr/local/luajit-2.1 
make install PREFIX=/usr/local/luajit-2.1

设置好环境变量

export LUAJIT_LIB=/usr/local/luajit-2.1/lib
export LUAJIT_INC=/usr/local/luajit-2.1/include/luajit-2.1

2、下载ngx_devel_kit

wget https://github.com/simplresty/ngx_devel_kit/archive/v0.3.1rc1.tar.gz
tar zxvf v0.3.1rc1.tar.gz

3、下载lua-nginx-module

wget https://github.com/openresty/lua-nginx-module/archive/v0.10.12rc2.tar.gz
tar zxvf v0.10.12rc2.tar.gz

4、下载安装sregex

wget https://github.com/openresty/sregex/archive/v0.0.1.tar.gz
cd sregex-0.0.1
make
make install

需要做软链

ln -s /usr/local/lib/libsregex.so.0.0.1 /usr/lib64/libsregex.so.0
ln -s /usr/local/lib/libsregex.so.0.0.1 /usr/lib/libsregex.so.0

否则报错:

/usr/local/nginx/sbin/nginx: error while loading shared libraries: libsregex.so.0: cannot open shared object file: No such file or directory

5、下载replace-filter-nginx-module

wget https://github.com/openresty/replace-filter-nginx-module/archive/v0.01rc5.tar.gz
tar zxvf v0.01rc5.tar.gz

6、安装nginx加载以上模块

./configure --user=www --group=www --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module  --with-http_realip_module --add-module=../ngx_http_substitutions_filter_module-0.6.4/ --with-http_sub_module --add-module=../ngx_devel_kit-0.3.1rc1 --add-module=../lua-nginx-module-0.10.11 --with-ld-opt=-Wl,-rpath,/usr/local/luajit-2.1/lib --add-module=../replace-filter-nginx-module-0.01rc5/
make
make install

安装完毕

lua 模块管理的一点改进

lua 从 5.2 开始,简化了 5.1 中的模块管理方式,然后一直保持到现在这个样子。

模块用 require 加载,同名模块在一个 vm 中只加载一次,第 2 次开始会返回上次加载的结果。加载模块时会利用 package.path 或 package.cpath 中定义的字符串模板,把模块名转换为文件名,依次尝试打开文件。

我在新项目中,由于整合了不少模块,感觉现有的这套机制有点点不够用。所以我做了一点点小改动,支持了类似 python 的模块管理那样的相对机制。当在一个模块中 require 另一个模块时,会先尝试加载相对路径上的模块,再尝试绝对路径。这样可以方便我们集成独立开始的模块,并放在独立的名字空间中。也方便给模块内置测试子模块。

例如,我独立开发了一个叫 foobar 的模块,它自己有一个子模块叫 foobar.baz ,在集成到系统中时,我希望把它们一起放在 common 名字空间下。使用的时候可以用 require “common.foobar” 来引用。

如果直接用 lua 原生的模块管理机制,我需要修改 foobar 主模块的代码,把里面的 require “foobar.baz” 改成 require “common.foobar.baz” 。同理,如果我不满意 foobar 这个名字,想换名也很麻烦。

所以我希望在新机制下,foobar 的主模块引用自己的子模块 baz,只需要 require “baz” 即可。如果同一目录下有 baz.lua 这个文件,就优先加载它。而外部模块也可以通过 require “foobar.baz” 直接引用这个子模块。

新机制最好可以兼容原生机制,所以不必另起一套模块管理代码。我们要做的只是获取当前模块的名字,在 foobar 主模块中调用 require 时,尝试给参数加上 foobar. 的前缀,引入失败再按原生路径尝试。

好在 lua 原生机制已经把当前模块名作为参数传递进来了。我们只需要实现这么一个函数:

local loaded = package.loaded
local searchpath = package.searchpath

function import(modname)
    if modname then
        local prefix = modname:match "(.*%.).*$" or (modname .. ".")
        return function(name)
            local fullname = prefix .. name
            local m = loaded[fullname] or loaded[name]
            if m then
                return m
            end
            if searchpath(fullname, package.path) then
                return require(fullname)
            else
                return require(name)
            end
        end
    else
        return require
    end
end

这个 import 会生成一个模块导入函数,完成以上逻辑。我把这个函数定义成了全局函数,在项目开头就引入。然后,在每个模块的最前面加入这样一行:

local require = import and import(...) or require

如果定义了 import 则用 import 生成一个 require 代替原生版本;否则直接使用原生版本。

另外,我更倾向于用目录来管理模块。即使一个模块只有一个文件,也放在一个单独的目录中。lua 原生模板的约定是 ?/init.lua 用目录中的 init.lua 作为主模块的入口,我更喜欢 ?/?.lua 直接用目录名同名文件做主入口。

AWS 时间同步服务chrony,Amazon Linux设置时间

Amazon提供可从实例访问的Amazon Time Sync服务,以前在AWS实例进行时间同步需要与外部的服务器进行NTP通信,但现在实例无需访问Internet就可进行时间同步。

Amazon Time Sync的特点如下。

  • 无需访问Internet
  • 无需配置安全组规则或网络ACL
  • 使用chrony 客户端
  • 自动消除在 UTC 中添加的任何闰秒
  • 使用IP地址为 169.254.169.123

cat /etc/system-release 命令,确认当前的Amazon Linux版本。

$ cat /etc/system-release
Amazon Linux AMI release 2017.03

Amazon Linux配置Amazon Time Sync Service

登陆到EC2实例后,yum remove 命令卸载NTP服务。

# yum remove ntp* -y

卸载ntp服务之后, yum install命令安装chrony服务。

# yum install chrony -y

确认 /etc/chrony.conf 文件里包含以下配置。

server 169.254.169.123 prefer iburst

最后 service 命令启动chronyd服务,并使用 chkconfig 命令设定开机自动启动。

# service chronyd start
# chkconfig chronyd on

更多详细信息,参照 https://docs.aws.amazon.com/zh_cn/AWSEC2/latest/UserGuide/set-time.html

三款简单而优秀的 Linux 网络监视工具

你可以通过这三个 Linux 命令了解当前网络的大量信息。iftop 通过进程号跟踪网络连接,nethogs 快速告知你哪些进程在占用你的带宽,而 vnstat 以一个良好的轻量级守护进程在后台运行,并实时记录你的网络使用情况。

iftop

令人称赞的 iftop 可以监听您指定的网络接口,并以 top 的样式呈现。

这是一个不错的小工具,可以用于找出网络拥塞,测速和维持网络流量总量。看到自己到底在用多少带宽往往是非常惊人的,尤其是对于我们这些仍然记得电话线路、调制解调器,“高速”到令人惊叫的 kb 和实时波特率的老人们。我们在很久之前就不再使用波特率,转而钟情于比特率。波特率用于衡量信号变化,尽管有时候与比特率相同,但大多数情况下并非如此。

如果你只有一个网络接口,直接运行 iftop 即可。不过 iftop 需要 root 权限:

$ sudo iftop

如果你有多个网络接口,那就指定你要监控的接口:

$ sudo iftop -i wlan0

就像 top 命令一样,你可以在命令运行时更改显示选项:

  • h 切换帮助界面。
  • n 是否解析域名。
  • s 切换源地址的显示,d 则切换目的地址的显示。
  • S 是否显示端口号。
  • N 是否解析端口;若关闭解析则显示端口号。
  • t 切换文本显示界面。默认的显示方式需要 ncurses。我个人认为图 1 的显示方式在组织性和可读性都更加良好。
  • p 暂停显示更新。
  • q 退出程序。

未分类

当你切换显示设置的时候,iftop 并不会中断监测流量。当然你也可以单独监测一台主机。而这需要该主机的 IP 地址和子网掩码。现在,我很好奇 Pandora(LCTT 译注:一家美国的电台公司)能给我贫瘠的带宽带来多大的负载。因此我首先使用 dig 命令找到他们的 IP 地址:

$ dig A pandora.com
[...]
;; ANSWER SECTION:
pandora.com.            267     IN      A       208.85.40.20
pandora.com.            267     IN      A       208.85.40.50

那子网掩码呢?ipcalc 会告诉我们:

$ ipcalc -b 208.85.40.20
Address:   208.85.40.20   
Netmask:   255.255.255.0 = 24
Wildcard:  0.0.0.255  
=>
Network:   208.85.40.0/24 

现在,将 IP 地址和子网掩码提供给 iftop:

$ sudo iftop -F 208.85.40.20/24 -i wlan0

很棒的不是么?而我也很惊奇地发现,Pandora 在我的网络上,每小时大约使用 500kb。并且就像大多数流媒体服务一样,Pandora 的流量在迅速增长,并依靠缓存稳定下来。

你可以使用 -G 选项对 IPv6 地址执行相同的操作。查阅友好的 man 可以帮助你了解 iftop 的其他功能,包括使用个人配置文件自定义你的默认选项,以及使用自定义过滤(请参阅 PCAP-FILTER 来获取过滤指南)。

nethogs

当你想要快速了解是谁在吸取你的带宽的时候,nethogs 是个快速而简单的方法。你需要以 root 身份运行并指定要监听的接口。它会给你显示大量的应用程序及其进程号,所以如果你想的话,你可以借此杀死任一进程。

$ sudo nethogs wlan0
nethogs version 0.8.1
PID USER   PROGRAM              DEV    SENT   RECEIVED       
7690 carla /usr/lib/firefox     wlan0 12.494 556.580 KB/sec
5648 carla .../chromium-browser wlan0  0.052   0.038 KB/sec
TOTAL                                 12.546 556.618 KB/sec 

nethogs 并没有多少选项:在 kb/s、kb、b、mb之间循环,按接收和发送的数据包排序,调整刷新延迟。具体请看man nethogs,或者是运行 nethogs -h。

vnstat

vnstat是最容易使用的网络数据收集工具。它十分轻量并且不需要 root 权限。它以守护进程在后台运行,因此可以实时地记录你的网络数据。单个 vnstat 命令就可以显示所累计的数据。

$ vnstat -i wlan0
Database updated: Tue Oct 17 08:36:38 2017
   wlan0 since 10/17/2017
          rx:  45.27 MiB      tx:  3.77 MiB      total:  49.04 MiB
   monthly
                     rx      |     tx      |    total    |   avg. rate
     ------------------------+-------------+-------------+---------------
       Oct '17     45.27 MiB |    3.77 MiB |   49.04 MiB |    0.28 kbit/s
     ------------------------+-------------+-------------+---------------
     estimated        85 MiB |       5 MiB |      90 MiB |
   daily
                     rx      |     tx      |    total    |   avg. rate
     ------------------------+-------------+-------------+---------------
         today     45.27 MiB |    3.77 MiB |   49.04 MiB |   12.96 kbit/s
     ------------------------+-------------+-------------+---------------
     estimated       125 MiB |       8 MiB |     133 MiB |

默认情况下它会显示所有的网络接口。使用 -i 选项来选择某个接口。也可以像这样合并多个接口的数据:

$ vnstat -i wlan0+eth0+eth1

你可以通过这几种方式过滤数据显示:

  • -h 按小时显示统计信息。
  • -d 按天显示统计信息.
  • -w 和 -m 分别按周和月份来显示统计信息。
  • 使用 -l 选项查看实时更新。

以下这条命令将会删除 wlan1 的数据库并不再监视它:

$ vnstat -i wlan1 --delete

而下面这条命令将会为你的一个网络接口创建一个别名。这个例子使用了 Ubuntu 16.04 的一个有线接口名称:

$ vnstat -u -i enp0s25 --nick eth0

默认情况下,vnstat 会监视 eth0。你可以在 /etc/vnstat.conf 对它进行修改,或者在你的家目录下创建你自己的个人配置文件。请参阅 man vnstat 以获取完整的指南。

你也可以安装 vnstati 来创建简单的彩图(图 2):

$ vnstati -s -i wlx7cdd90a0a1c2 -o vnstat.png

未分类

请参阅 man vnstati 以获取完整的选项。

mysqldump备份失败以及解决方法汇总

mysqldump备份失败以及解决方法汇总

1、mysqldump: Error: Query execution was interrupted, maximum statement execution time exceeded when trying to dump tablespaces
mysqldump: Error 3024: Query execution was interrupted, maximum statement execution time exceeded when dumping table $tb_name at row: xxxx

版本:
MySQL 5.7.8+
原因:
max_execution_time过小
处理思路:
① 通过hints,增大N值(文档说,在hints用法中,将N改为0为无限制,但我测下来不生效,可设置成一个较大值如999999解决)
SELECT /*+ MAX_EXECUTION_TIME(N) */ * FROM t1 LIMIT 100000;
② 修改max_execution_time值,将该值设置为较大一个值,或设置为0(不限制)
附录:
该参数5.7.8被添加,单位为ms,动态参数,默认为0,设置为0时意味着SELECT超时不被设置(不限制超时时间)。不作用于存储过程中的SELECT语句,并且只作用于只读的SELECT,如INSERT … SELECT … 是不被作用的。
for more information:
http://blog.itpub.net/29773961/viewspace-2150443/

2、mysqldump: Couldnt execute SHOW FIELDS FROM $view_name: View $db_name.$view_name references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them (1356)

原因:
该view引用了无效的表,列,函数或者定义者。
处理思路:
可以根据报错信息,进入db,执行SHOW CREATE VIEW $view_nameG,查看该view的定义,逐一检查该view的基表,列,或相关函数与用户是否具有相关权限。考虑重建或删除视图。

3、mysqldump: Couldnt execute show create table $view_name: Illegal mix of collations for operation UNION (1271)

原因:
创建view时,使用UNION时存在非法的排序规则组合。
处理思路:
检查该视图定义,检查字符集,考虑重建或删除视图。

4、mysqldump: Couldnt execute SHOW FIELDS FROM $view_name: The user specified as a definer ($user@$host) does not exist (1449)
mysqldump: Couldnt execute show table status like $view_name: SELECT command denied to user @% for column $col_name in table $tb_name (1143)

原因:
该视图的定义者$user@$host不存在。
处理思路:
检查mysql.user表,确认用户是否存在,考虑重建或删除视图。

5、Error: Couldnt read status information for table Income_config ()mysqldump: Couldnt execute show create table Tser_table: Table $db_name.test_table doesnt exist (1146)
mysqldump: Got error: 1049: Unknown database $db_name when selecting the database

原因一:
从lower_case_table_names的0设置成1,导致部分原来含有大写字母的库表“找不到”。
处理思路:
将lower_case_table_names设置回0。
若有必须将lower_case_table_names设置为1,需先设置为0,并将含有大写字母的库表改成小写,再设置为1。

原因二(MySQL 5.5及以下版本可能出现):
表损坏导致该表找不到(InnoDB)。frm和ibd文件都在,但无法SHOW CREATE TABLE xxxG
error log一则:

170820 17:43:17 [Note] Event Scheduler: scheduler thread started with id 1
170820 17:44:48 InnoDB: error: space object of table '$db_name/$tb_name',
InnoDB: space id 4335 did not exist in memory. Retrying an open.
170820 17:44:48 InnoDB: Error: tablespace id and flags in file './$db_name/$tb_name.ibd' are 0 and 0, but in the InnoDB
InnoDB: data dictionary they are 4335 and 0.
InnoDB: Have you moved InnoDB .ibd files around without using the
InnoDB: commands DISCARD TABLESPACE and IMPORT TABLESPACE?
InnoDB: Please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/innodb-troubleshooting-datadict.html
InnoDB: for how to resolve the issue.
170820 17:44:48 InnoDB: cannot calculate statistics for table $db_name/$tb_name
InnoDB: because the .ibd file is missing. For help, please refer to
InnoDB: http://dev.mysql.com/doc/refman/5.5/en/innodb-troubleshooting.html
170820 17:44:48 [ERROR] MySQL is trying to open a table handle but the .ibd file for
table $db_name/$tb_name does not exist.
Have you deleted the .ibd file from the database directory under
the MySQL datadir, or have you used DISCARD TABLESPACE?
See http://dev.mysql.com/doc/refman/5.5/en/innodb-troubleshooting.html
how you can resolve the problem.

处理思路:
从完整备份+binlog还原,对于有主或从的实例,可通过物理备份还原。

6、mysqldump: Error 2020: Got packet bigger than max_allowed_packet bytes when dumping table $tb_name at row: xxxx

原因:
默认的max_allowed_packet过小
处理思路:
在mysqldump时增加max_allowed_packet的大小,如mysqldump –max-allowed-packet=268435456

7、mysqldump: Error 1412: Table definition has changed, please retry transaction when dumping table $tb_name at row: 0

原因:
在备份该表时,表定义被修改。FLUSH TABLE WITH READ LOCK只保证数据一致性,并不保证schema不被修改。
处理思路:
备份时期不做DDL操作。
复现一:

① session1> CREATE TABLE a (id int) ENGINE=InnoDB;
② session2> START TRANSACTION WITH CONSISTENT SNAPSHOT;
③ session1> ALTER TABLE a ADD COLUMN name varchar(32);
④ session2> SELECT * FROM a;
ERROR 1412 (HY000): Table definition has changed, please retry transaction

p.s. 如果③和④调换顺序,则ALTER TABLE无法成功,则会等待MDL。
复现二:

① session1> START TRANSACTION WITH CONSISTENT SNAPSHOT;
② session2> CREATE TABLE b (id int) ENGINE=InnoDB;
③ session1> SELECT * FROM b;
ERROR 1412 (HY000): Table definition has changed, please retry transaction

8、mysqldump: Couldnt execute show create table $tb_name: Unable to open underlying table which is differently defined or of non-MyISAM type or doesnt exist (1168)

原因:
出现在表引擎为MERGE时,备份到该表时,发现该表定义存在问题。可能merge的表不存在,或者该表合并的基表包含非MyISAM引擎的表。
处理思路:
删除或者重建该MERGE表。
复现一(merge表中定义包含了非MyISAM表):

CREATE TABLE t1(id int) ENGINE=InnoDB;
CREATE TABLE t2(id int) ENGINE=MyISAM;
CREATE TABLE merge_t(id int)ENGINE=MERGE UNION=(t1, t2);
SELECT * FROM merge_t;
ERROR 1168 (HY000): Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist

复现二(表不存在):

CREATE TABLE t1(id int) ENGINE=MyISAM;
CREATE TABLE t2(id int) ENGINE=MyISAM;
CREATE TABLE merge_t(id int)ENGINE=MERGE UNION=(t1, t2);
SELECT * FROM merge_t;
Empty set (0.00 sec)    -- 正常返回
DROP TABLE t1;
SELECT * FROM merge_t;
ERROR 1168 (HY000): Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist

附录:
通过check table merge_t可以检查是哪张表有问题,如此处是t1:

[15:20:12] root@localhost [test]> check table merge_tG
*************************** 1. row ***************************
  Table: test.merge_t
     Op: check
Msg_type: Error
Msg_text: Table 'test.t1' is differently defined or of non-MyISAM type or doesn't exist
*************************** 2. row ***************************
  Table: test.merge_t
     Op: check
Msg_type: Error
Msg_text: Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist
*************************** 3. row ***************************
  Table: test.merge_t
     Op: check
Msg_type: error
Msg_text: Corrupt
3 rows in set (0.00 sec)

通过cat表MGR定义结构文件可以检查MERGE表的基表:

[root@host test]# pwd
/data/mysql-data/mysql57/data/test
[root@host test]# cat merge_t.MRG
t1
t2

9、mysqldump: Couldnt execute show create table $tb_name: Table ./$db_name/$tb_name is marked as crashed and last (automatic?) repair failed (144)
mysqldump: Couldnt execute show create table $tb_name: Table ./$db_name/$tb_name is marked as crashed and should be repaired (145)
mysqldump: Error 1194: Table throne_tower is marked as crashed and should be repaired when dumping table $tb_name at row: xxxxx

原因:
mysqldump在拉取表定义时报错,表损坏。
处理思路:
该损坏发生在非事务表如MyISAM,通过mysqlcheck或者repair table修复即可。

10、mysqldump: Couldnt execute SHOW FUNCTION STATUS WHERE Db = $db_name: Cannot load from mysql.$tb_name. The table is probably corrupted (1728)

原因:
字典表不正确,可能是表本身损坏,也有可能是导入了其他版本的mysql schema盖掉了字典表。
处理思路:
repair table修复,若仍无用,则可以尝试mysql_upgrade来修复,或找到对应版本的mysql_system_tables_fix.sql来导入。

11、mysqldump: Couldnt execute show events: Cannot proceed because system tables used by Event Scheduler were found damaged at server start (1577)

原因:
字典表不正确,极大可能是导入了其他版本的mysql schema盖掉了字典表。
处理思路:
尝试mysql_upgrade来修复,或找到对应版本的mysql_system_tables_fix.sql来导入。该报错可能在upgrade操作之后重启实例。

12、mysqldump: Error: Got error 28 from storage engine when trying to dump tablespaces
mysqldump: Couldnt execute show fields from $tb_name: Got error 28 from storage engine (1030)

原因:
@@tmpdir满了。
处理思路:
清除@@tmpdir,可以通过SELECT @@tmpdir;检查具体目录。

13、mysqldump: Lost connection to MySQL server during query (2013)
ERROR 2002 (HY000): Can’t connect to local MySQL server through socket ‘@@socket’ (111)

原因:
mysqldump执行过程中mysqld被关闭。
处理思路:
检查mysqld被关闭的原因,一般常见原因是发生OOM。

14、mysqldump: Couldn’t execute ‘SHOW SLAVE STATUS’: Access denied; you need (at least one of) the SUPER, REPLICATION CLIENT privilege(s) for this operation (1227)

原因:
mysqldump加了–dump-slave参数,缺少SUPER或REPLICATION CLIENT来执行SHOW SLAVE STATUS。
处理思路:
检查mysqldump的用户权限。

15、mysqldump: Couldn’t execute ‘STOP SLAVE SQL_THREAD’: Access denied for user ‘dump’@’localhost’ (using password: YES) (1045)

原因:
mysqldump加了–dump-slave参数,缺少SUPER权限使用STOP SLAVE SQL_THREAD。
处理思路:
检查mysqldump的用户权限。

uwsgi的python2+3多版本共存

1、首先,机器需要有python2和python3的可执行环境。

确保pip和pip3命令可用。原理就是在哪个环境下安装uwsgi。uwsgi启动的时候,就用的哪个python版本

未分类

2、安装virtualenv环境管理工具

未分类

3、创建python2和python3的虚拟环境

未分类

4、进入python2虚拟环境

未分类

5、进入python3虚拟环境

未分类

常规发布应用的时候。可以编写shell脚本执行相应的命令启动即可,如下

未分类