Nginx上传大文件超时出错解决方法

Nginx上传大文件出现出错超时

上传文件大小:1.4G
上传所使用的组件:swfupload
swfupload返回-220错误码,对应的是错误提示是IO_ERROR。
IO_ERROR #当读取和发送文件时出现了一些错误。通常发生在服务器非预期地关闭了终端连接的时候。

解决:

修改Nginx读取超时间与发请求超时间.

nginx配置参数如下:

fastcgi_connect_timeout 300; #连接超时
fastcgi_read_timeout 600;    #读超时
fastcgi_send_timeout 600;    #写超时

#选项注解:

fastcgi_read_timeout #FastCGI进程向Nginx进程发送response,整个过程的超时时间
fastcgi_send_timeout #Nginx进程向FastCGI进程发送request,整个过程的超时时间

nginx结合jwplayer实现视频流媒体点播

一、nginx简介:

Nginx是一个网页服务器,它能反向代理HTTP, HTTPS, SMTP, POP3, IMAP的协议链接,以及一个负载均衡器和一个HTTP缓存。

Nginx是一款面向性能设计的HTTP服务器,相较于Apache、lighttpd具有占有内存少,稳定性高等优势。与旧版本(<=2.2)的Apache不同,nginx不采用每客户机一线程的设计模型,而是充分使用异步逻辑,削减了上下文调度开销,所以并发服务能力更强。整体采用模块化设计,有丰富的模块库和第三方模块库,配置灵活。 在Linux操作系统下,nginx使用epoll事件模型,得益于此,nginx在Linux操作系统下效率相当高。同时Nginx在OpenBSD或FreeBSD操作系统上采用类似于epoll的高效事件模型kqueue。下图是实现的最终效果。

未分类

未分类

二、流媒体简介:

流媒体(Streaming media)是指将一连串的媒体数据压缩后,经过网络分段发送数据,在网络上即时传输影音以供观赏的一种技术与过程,此技术使得数据包得以像流水一样发送;如果不使用此技术,就必须在使用前下载整个媒体文件。流传输可发送现场影音或预存于服务器上的视频,当观看者在收看这些影音档时,影音数据在送达观赏者的电脑后立即由特定播放软件播放(如Windows Media Player,Real Player,或QuickTime Player)。

未分类

三、安装步骤:

1、 安装nginx

(1). 安装依赖包

yum -y install gcc openssl-devel pcre-devel httpd-tools gcc-c++

未分类

(2). 下载nginx

下载地址:http://nginx.org/download/nginx-1.10.2.tar.gz

wget http://nginx.org/download/nginx-1.10.2.tar.gz

(3). 解压nginx

tar xf nginx-1.10.2.tar.gz

(4). 进入nginx目录

cd nginx-1.10.2/

(5).创建nginx用户

useradd nginx

未分类

(6). 检查配置文件

> ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx
> --with-http_ssl_module --with-http_mp4_module --with-http_flv_module

未分类

(7). 编译并安装

make && make install

未分类

(8). 建立快捷方式

ln -s /usr/local/nginx/sbin/nginx /usr/sbin/

(9). 启动nginx服务

nginx

(10). 检查nginx监听信息

netstat -anptu | grep nginx

未分类

(11). 修改配置

vim /usr/local/nginx/conf/nginx.conf

配置内容

worker_processes  1;
events {
    worker_connections  65535;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  localhost;
        location / {
            root   html;
            index  index.html index.htm;
        }
        location ~ .flv$ {
            flv;
            limit_conn addr 4;
            limit_rate 1024k;
        }
        location ~ .mp4$ {
            mp4;
            limit_conn addr 4;
            limit_rate 1024k;
        }
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root html;
        }
    }
}

未分类

(12). 刷新配置

nginx -s reload #重启nginx,刷新配置

未分类

(13). 浏览器检测

未分类

2、 部署代码

(1). 上传代码、jwplayer、视频

jwplayer下载官网:https://www.jwplayer.com/

> scp -r index.html jwplayer qyz.flv
> [email protected]:/usr/local/nginx/html

未分类

html代码

未分类

(2). 浏览器检测点播效果

输入地址:http://192.168.4.1,点击播放

未分类

Nginx技术原理介绍

Nginx Inc. 联合创始人 Andrew Alexeev 在 AOSA 上发表的文章 [1] ,涵盖 了 Nginx 项目想要解决的问题、程序整体架构、配置文件结构、请求处理流程和开发 Nginx 过程中的心得体会等等话题。本节对该文中提到的关键点进行摘录和整理。

一些信息

  • 发音:( engine x );
  • 俄罗斯软件工程师 Igor Sysoev 于 2004 年发布的开源 Web 服务器软件;
  • 目前,在开源 Web 服务器按市场占有率排列的名单中,Nginx 位列第二名(Apache HTTPD 第一名)(据 2015年8月10日 w3techs 的统计数字,Nginx 已经跃居榜首);
  • Nginx 专注于高性能、高并发和低内存占用;
  • 除基本的 Web 服务功能外,Nginx 还提供了诸如「负载均衡」、「缓存」、「访问控 制」、「带宽控制」、「HTTP/TCP/UDP 反向代理」等功能,它还能高效得和其它各类 应用结合使用;
  • Nginx 使用 C 语言开发,除了 libc, zlib, PCRE 和 OpenSSL 外, 不依赖其它开发库。
  • Nginx 是一个「模块化的」、「基于事件驱动的」、「异步的」、「单线程的」、「非 阻赛的」的 Web 服务器;
  • Nginx 使用 C 语言风格的配置文件;

技术原理

事件驱动 vs. 多进程/线程

  • 1995 年首次发布的 Apache HTTPD,在 2012 年 2.4 稳定版之前,在 Linux 平台上只 能选择 mpm-prefork [6] 或者 mpm-worker [7] 作为并发模式。在这两种工作模式里,Apache 会为每个 HTTP 请求分配独立的进程或 者线程,请求处理完成后,进程或线程才会被回放释放。2.4 版增加了 mpm-event 模式 [8],虽然使用了 epoll, kqueue 等事件驱动机制, 但是请求处理依然由线程完成。
  • 在上世纪90年代,由于操作系统、计算机硬件和当时互联网状态的限制,Apache 选择 上述的并发模型是合理的,并且它也提供了相当丰富的功能和特性。但是,这些特点的 代价是,在每个连接会使用更多的内存资源,不能很好地支持网站非线性伸缩 (nonlinear scalability)。
  • 创建进程和线程(新的堆、栈和执行上下文)内存和 CPU 等资源消耗大;
  • 过多的上下文切换(context switching)会造成 thread thrashing ;
  • 随着硬件、操作系统和网络带宽的发展,它们不再是制约网站规模增长的瓶径:
  • C10K Problem [2]
  • Why threads are a bad idea (for most purposes) – 1995 [4] vs. Why events are a bad idea (for high-concurrency servers) – 2003 [3]
  • 各操作系统对事件驱动的支持
  • Unix-like/Windows – select/poll – 未考证,很早
  • FreeBSD/NetBSD/OpenBSD/OS X – kqueue – 2000
  • Windows/AIX/solaris 10 – IOCP – Windows NT 3.5
  • Linux – epoll – 2.5.44, 2003 年前,2001 年初稿 [5]
  • It’s time for web servers to handle ten thousand clients simultaneously.
  • Lighttpd [10]
  • Nginx [9]
  • libevent [11]
  • libuv [12]

并发模型

以解决 C10K 问题 [2] 为使命的 Nginx,在底层架构上选择了事件驱动机制。事件 驱动机在需要对并发连接和吞吐率提供非线性伸缩 (nonlinear scalability) 的场景中比 多进程/多线程更适合:负载持续上升时,CPU 和内存占用依然在可控的范围内;在普 通硬件配置上,Nginx 就可以服务数以万计的并发连接。

  • 多路复用(multiplexting)、事件通知(event notification);
  • 每个使用单线程的工作进程(worker)通过高效的 runloop 处理数以千记的并发连 接;
  • 工作进程从共享 listening socket ,接收新连接并将其加入到自己的 runloop 中。新连接的分发由操作系统决定(thundering herd 问题 [13]);
  • 对工作进程个数选择的一般建议:
  • CPU 密集型业务,比如,启用了 SSL、数据解压缩等场景下,工作进程个数由 CPU 核 数决定;
  • 磁盘 IO 密集型业务,工作进程个数可以设为 CPU 核数的 1.5 倍到 2 倍;

实现细节

  • Ngnix 会根据不同操作系统的特点进行不同的优化,以提高 IO 性能;

  • 工作进程中的 runloop 是 Nginx 代码中最复杂的部分,它的实现基于异步任务处 理思想。Nginx 通过使用模块化、事件通知、大量的回调函数和仔细调整的计时器等 手段实现异步操作。

  • 基本原则就是尽量使用非阻塞操作;
  • 读写性能不足的硬盘的操作是 Nginx 中唯一可能发生阻塞的地方;

  • Nginx 谨慎地使用系统调用实现了诸如内存池( pool )、片内存分配器 ( slab memory allocator )等高效的数据结构,再加上选取的并发模型,可以有 效节省对 CPU、内存等系统资源的占用。即使在极高的负载下,Nginx 的 CPU 使用率通 常也是很低的。

  • 在某种程度上,Nginx 借鉴了 Apache 的内存分配机制:
  • 它尽可能在内部通过传递指针的方式地减少内存拷贝;
  • Nginx 为每个连接创建一个内存池,为该连接生命期内的各种操作分配内存。比 如,连接内存池可以用来存储请求包头和包体数据,可以用来创建请求结构体 ( ngx_http_request_t )。Nginx 在关闭连接时,释放连接内存池;
  • Nginx 还会为请求分配请求内存池,为该请求生命期内的各种操作分配内存。比 如,与该请求相关的变量值,解析后的请求包头信息等。Nginx 在请求处理完毕后 ,释放请求内存池;
  • Nginx 使用 slab memory allocator 管理共享内存。共享内存一般用来存储 acept mutex, cache metadata, SSL session cache 等需要在进程间共 享的数据。同时,Nginx 使用 mutex semaphore 等加锁机制保证共享数据的 安全。

  • Nginx 提供了针对阻塞磁盘 IO 的优化措施: sendfile, AIO, thread pool (1.7.11+);

  • 除了 master 进程和 worker 进程,Nginx 还会启动 cache loader 进程 和 cache manager 进程,这些进程之间使用共享内存作为主要通信方式。

  • master 进程的主要工作如下:
  • 读取和验证配置文件;
  • 创建、绑定和并闭 socket;
  • 启动和停止 worker 进程,并按照配置的工作进程个数维护工作进程;
  • 在不中断服务的前提下,重新加载配置文件;
  • 实现 Nginx 二进制热切换;
  • 根据信号重新打开日志文件;
  • 编译内嵌 Perl 脚本;
  • worker 进程负责接收和处理客户端连接、反向代理客户端请求和响应过滤 等等 Nginx 的对外提供其它功能;
  • cache loader 进程负责遍历和检查磁盘缓存数据,并使用获取到的缓存元数据为 Nginx 建立内存数据库,加快运行期间的缓存查找速度;
  • 每个被缓存的响应都作为独立文件存储于文件系统中;
  • 用户可以通过配置文件控制缓存目录的分级结构;
  • 从 upstream 得到的响应数据会先存储到临时文件中,随后将响应数据发送给 客户端后,Nginx 将此临时文件挪到缓存目录下;
  • cache manager 进程长驻后台,并负责维护缓存数据的有效性,清理过期缓存数 据;

  • try_files 配置项和配置文件变量 (variables) 是 Nginx 独有的特性;

The try_files directive was initially meant to gradually replace
conditional ``if`` configuration statements in a more proper way, and it
was designed to quickly and efficiently try/match against different
URI-to-content mappings...adopt its use whenever applicable.
Variables in Nginx were developed to provide an additional
even-more-powerful mechanism to control run-time configuration of a web
server. Variables are optimized for quick evaluation and are internally
pre-compiled to indices. Evaluation is done on command; i.e., the value
of a variable is typically calculated only once and cached for the
lifetime of a particular request. Variables can be used with different
configuration directives, providing additional flexibility for describing
conditional request process behavior.

模块分类

Nginx 是一个模块化/插件化的程序,1.9.11 版本之前,Nginx 只支持静态链接模块 代码,从 1.9.11 版本之后,才引入动态加载模块的功能。

Nginx 代码由一个核心模块(core module)和很多功能模块组成(funcional module), 核心模块实现了 Web 服务器的基础、Web 和 Mail 反向代理功能等,为 Nginx 提供了 底层网络协议支持,构造了必要的运行环境,并保证其它不同功能模块的无封结合。而 其它模块则负责提供应用协议相关的特性。

在核心模块和功能模块之间,还有像 http, mail 这样的中层模块(upper-level module),它们为功能模块提供了核心模块和其它底层功能的抽像。这些模块也根据应用 层协议决定「事件」的处理顺序,同时,它们和核心模块结合,维护其它相关功能模块的 调用顺序。

功能模块分为: event module, phase handler, output filter, variable handler, protocol, upstream, 和 balancer 。

Nginx 为模块提供了很多不同的调用时机,模块初始化时可以为不同的时机注册不同的 回调函数。时机到来时,Nginx 就会调用相应的回调函数。Nginx 提供的调用时机有:

* Before the configuration file is read and processed.
* For each configuration directive for the the location and the server
  where it appears
* When the main configuration is initialized.
* When the server is initialized.
* When the server configuration is merged with the main configuration.
* When the location configuration is initialized or merged with its parent
  server configuration.
* When the master process starts or exits.
* When a new worker process starts or exits.
* When handling a request.
* When filtering the response header and the body.
* When picking, initiating and reinitiating a request to an upstream
  server.
* When process the response from and upstream server.
* When finishing an interation with an upstream server.

请求处理

  • 一个 HTTP 请求的处理流程如下:
1. Client sends HTTP request.
2. Nginx core choose the appropriate phase handler based on the configured
location matching the request.
3. If configured to do so, a load balancer picks an upstream server for
proxying.
4. Phase handler does its job and passes each outout buffer to the first filter.
5. First filter passes the outout to the second filter (and so on).
6. Final response is send to the client.
  • Nginx 将 HTTP 请求的处理过程分成了几个阶段,每个阶段都有相应的处理函数( phase handler )。阶段处理函数由配置文件 location {} 中的配置项决定。 HTTP 请求包头接受完毕后,Nginx 为该请求匹配合适的虚拟主机,随后请求会再交由 如下几个阶段的处理函数处理:
1. server rewrite phase
2. location phase
3. location rewrite phase (which can bring the request back to the previous phase)
4. access control phase
5. try_files phase
6. content phase (content handler first, then content phase handler)
7. log phase
  • Nginx 为 HTTP 请求生成响应数据后,将响应数据交给 filter 模块处理。 filter 模块可以分别对响应头和响应体进行处理。据此, filter 模块 可以分为 header filter 和 body filter 两大类;

  • header filter 主要工作步骤如下:

1. Decide whether to operate on this response.
2. Operate on the response
3. Call the next filter.
  • body filter 用于操作响应包体。比如,使用 gzip 压缩响应数据, 使用 chunked 编码响应数据等;

  • 两个特殊的 filter : copy filter 负责填充用于存放响应数据的内存 缓冲区(比如,使用临时文件的数据); postpone filter 负责子请求 (subrequest)相关的处理。

  • 子请求 (subrequest)是 Nginx 的强大特性之一,它是请求处理逻辑中非常重 要的一环。通过子请求机制,Nginx 可以:

  • 将不同 URL 的请求响应数据返回给当前请求(即主请求);

  • 将多个子请求的响应数据合并,返回给当前请求;

  • 将子请求再分裂为更多的子请求(sub-subrequest),子子请求( sub-sub-subrequest),形成子请求的层次关系;

  • 使用子请求读取磁盘文件、访问 Upstream 服务器等;

  • 在 filter 中,根据当前请求的响应数据触发子请求,例如:

For example, the SSI module uses a filter to parse the contents of the
returned document, and then replaces ``include`` directives with the
contents of specified URLs. Or, it can be an example of making a filter
that treats the entire contents of a document as a URL to be retrieved,
and then appends the new document to the URL itself.

最后

从上面的描述可以看出,Nginx 各模块结合紧密,模块逻辑复杂,使用 C 开发模块难度 较高,开发效率较低。幸运的是, lua-nginx-module, stream-lua-nginx-module 等第三方模块和官方 ngx-http-js-module 模块出现,降低的模块开发的门槛。开发 者借助它们,甚至可以开发运行于 Nginx 内部的业务应用了。

Lession learned:

There is always room for improvement.

It is worth avoiding the dilution of development efforts on something that
is neither the developer's core competence or the target application.

nfs故障排查思路介绍

之前开发时就碰到过nfs客户端卡住的情况,umount -f /mnt提示device is busy,并且尝试访问挂载目录、df -h等操作都会使终端卡住,ctrl+c也不能强行退出。

当时忙着赶进度,没研究这个问题。最近倒出功夫研究一下,顺便学习一下nfs的优化。
造成这种现象的原因是nfs服务器/网络挂了,nfs客户端默认采用hard-mount选项,而不是soft-mount。他们的区别是
soft-mount: 当客户端加载NFS不成功时,重试retrans设定的次数.如果retrans次都不成功,则放弃此操作,返回错误信息 “Connect time out”
hard-mount: 当客户端加载NFS不成功时,一直重试,直到NFS服务器有响应。hard-mount 是系统的缺省值。在选定hard-mount 时,最好同时选 intr , 允许中断系统的调用请求,避免引起系统的挂起。当NFS服务器不能响应NFS客户端的 hard-mount请求时, NFS客户端会显示
“NFS server hostname not responding, still trying”

下面列出mount关于nfs相关的参数

(1)-a:把/etc/fstab中列出的路径全部挂载。
(2)-t:需要mount的类型,如nfs等。
(3)-r:将mount的路径定为read only。
(4)-v mount:过程的每一个操作都有message传回到屏幕上。
(5)rsize=n:在NFS服务器读取文件时NFS使用的字节数,默认值是4096个字节。
(6)wsize=n:向NFS服务器写文件时NFS使用的字节数,默认值是4096个字节。
(7)timeo=n:从超时后到第1次重新传送占用的1/7秒的数目,默认值是7/7秒。
(8)retry=n:在放弃后台mount操作之前可以尝试的次数,默认值是7 000次。
(9)soft:使用软挂载的方式挂载系统,若Client的请求得不到回应,则重新请求并传回错误信息。
(10)hard:使用硬挂载的方式挂载系统,该值是默认值,重复请求直到NFS服务器回应。
(11)intr:允许NFS中断文件操作和向调用它的程序返回值,默认不允许文件操作被中断。
(12)fg:一直在提示符下执行重复挂载。
(13)bg:如果第1次挂载文件系统失败,继续在后台尝试执行挂载,默认值是失败后不在后台处理。
(14)tcp:对文件系统的挂载使用TCP,而不是默认的UDP。

如#mount -t nfs -o soft 192.168.1.2:/home/nfs /mnt

至于传输尺寸的选择,可以进行实际测试:

time dd if=/dev/zero of=/mnt/nfs.dat bs=16k count=16384

即向nfs服务器上的nfs.dat文件里写入16384个16KB的块(也有经验说文件大小可以设定为nfs服务器内存的2倍)。
得到输出如:

输出了 16384+0 个块
user    0m0.200s
输出了 66535+0 个块
user    0m0.420s
192.168.1.4:/mnt  /home/nfs  nfs   rsize=8192,wsize=8192,timeo=10,intr

重新挂载nfs服务器,调整读写块大小后重复上述过程,可以找到最佳传输尺寸。

NFS服务器的故障排除

故障排除思路:

NFS出现了故障,可以从以下几个方面着手检查。

(1)NFS客户机和服务器的负荷是否太高,服务器和客户端之间的网络是否正常。
(2)/etc/exports文件的正确性。
(3)必要时重新启动NFS或portmap服务。

运行下列命令重新启动portmap和NFS:

service portmap restart
service nfs start

(4)检查客户端中的mount命令或/etc/fstab的语法是否正确。
(5)查看内核是否支持NFS和RPC服务。

普通的内核应有的选项为CONFIG_NFS_FS=m、CONFIG_NFS_V3=y、CONFIG_ NFSD=m、CONFIG_NFSD_V3=y和CONFIG_SUNRPC=m。
我们可以使用常见的网络连接和测试工具ping及tracerroute来测试网络连接及速度是否正常,网络连接正常是NFS作用的基础。rpcinfo命令用于显示系统的RPC信息
,一般使用-p参数列出某台主机的RPC服务。用rpcinfo-p命令检查服务器时,应该能看到portmapper、status、mountd nfs和nlockmgr。用该命令检查客户端时,应
该至少能看到portmapper服务。

使用nfsstat命令查看NFS服务器状态

nfsstat命令显示关于NFS和到内核的远程过程调用(RPC)接口的统计信息,也可以使用该命令重新初始化该信息。如果未给定标志,默认是nfsstat -csnr命令。使用该命令显示每条信息,但不能重新初始化任何信息。

nfsstat命令的主要参数如下。

(1)-b:显示NFS V4服务器的其他统计信息。
(2)c:只显示客户机端的NFS和RPC信息,允许用户仅查看客户机数据的报告。nfsstat命令提供关于被客户机发送和拒绝的RPC和NFS调用数目的信息。
要只显示客户机NFS或者RPC信息,将该参数与-n或者-r参数结合。
(3)-d:显示与NFS V4授权相关的信息。
(4)-g:显示RPCSEC_GSS信息。
(5)-m:显示每个NFS文件系统的统计信息,该文件系统和服务器名称、地址、安装标志、当前读和写大小,以及重新传输计数
(6)-n:为客户机和服务器显示NFS信息。要只显示NFS客户机或服务器信息,将该参数与-c和-s参数结合。
(7)-r:显示RPC信息。
(8)-s:显示服务器信息。
(9)-t:显示与NFS标识映射子系统的转换请求相关的统计信息,要只显示NFS客户机或服务器信息,将-c和-s选项结合。
(10)-4:当与-c、-n、-s或-z参数组合使用时,将包含NFS V4客户机或服务器的信息,以及现有的NFS V2和V3数据。
(11)-z:重新初始化统计信息。该参数仅供root用户使用,并且在显示上面的标志后可以和那些标志中的任何一个组合到统计信息的零特殊集合。

要显示关于客户机发送和拒绝的RPC和NFS调用数目的信息,输入:

nfsstat -c

要显示和打印与客户机NFS调用相关的信息,输入如下命令:

nfsstat -cn

要显示和打印客户机和服务器的与RPC调用相关的信息,输入如下命令:

nfsstat -r

要显示关于服务器接收和拒绝的RPC和NFS调用数目的信息,输入如下命令:

nfsstat –s

mysql主(master)从(slave)数据库复制的配置

主从数据库作用:

1、 对数据库进行读写分离,提高系统性能。主服务器专注于写操作,从数据库专注于读操作。
2、 从(slave)数据库在不破坏主数据库数据的情况下,执行数据备份。
3、 用主数据库产生实时数据,从(slave)数据库进行数据的分析。
4、 远程数据分布:创建远程站点的本地数据副本,不需要永久的访问主服务器。

步骤:

1、修改主服务器数据库的配置文件(my.ini或my.cnf),配置如下内容。

[mysqld]   
log-bin=mysql-bin   
server-id=156       //这里一般去服务器ip位数  

2、 为执行复制的从数据创建用户、密码,并分配权限。

mysql> CREATE USER 'cenliming'@'%' IDENTIFIED BY 'password';   //'%'代表允许 该用户远程访问数据库   
mysql> GRANT  REPLICATION  SLAVE ON  *.*   TO 'user'@'%';  

注意:如果在本地测试,要配置本地数据库允许远程连接。

3、 获取二进制日志文件信息,若显示为空,请重启数据库即可查看到。

mysql > SHOW MASTER STATUS;     
+------------------+----------+--------------+------------------+   
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |   
+------------------+----------+--------------+------------------+   
| mysql-bin.000003 | 73       | test         | manual,mysql     |   
+------------------+----------+--------------+------------------+

(File:日志文件名 Position: 文件坐标)

4、 在主数据库中释放表锁,在从数据库中进行相关配置。 a. 主数据库释放锁:

mysql> UNLOCK TABLES;  

修改从数据库配置文件,配置server-id:

[mysqld]   
server-id=232  

在从数据库中进行连接主数据库的配置:

mysql> CHANGE MASTER TO  
    ->     MASTER_HOST='master_host_name',   
    ->     MASTER_USER='replication_user_name',   
    ->     MASTER_PASSWORD='replication_password',   
    ->     MASTER_LOG_FILE='recorded_log_file_name',   
    ->     MASTER_LOG_POS=recorded_log_position;

5、 启动从服务器并查看状态:

mysql> start  slave;     //停止用 stop   
mysql>show slave stausG;  

未分类

Slave_IO_Running状态不为YES,说明从数据库未能成功连接到主数据库。 配置成功后,你对主数据库的更新操作都会更新到从数据库(异步处理)。

mysql主从配置步骤

基础环境

  • 系统:linux
  • mysql版本:5.5
  • 主服务器IP:192.168.1.101
  • 从服务器IP:192.168.1.102

1、 主服务器(master)要打开二进制日志
2、 从服务器(slave)要打开relay日志
3、 在主服务器(master)上建立replcation账号授权给从服务器(slave)
4、 修改从服务器(slave)的master服务器
5、 启动slave

操作步骤:

1、 主库的操作

vim /etc/my.cnf

然后在[mysqld]下添加如下配置

#给服务器起一个唯一的id
server-id=1
#开启二进制日志
log-bin=mysql-bin
#指定日志格式
binlog-format=mixed

保存后重启mysql

2、 从库操作

vim /etc/my.cnf

然后在[mysqld]下添加如下配置

#给服务器起一个唯一的id
server-id=2
#从服务器中继日志
relay-log=mysql-relay

保存后重启mysql

3、 在主服务器上创建相应的复制账号

grant replication client,replication slave on *.* to replName@’192.168.%.%’ identified by ‘123456’;

其中是replName是帐号名,123456是密码,这两项都可以自己修改

4、 在从服务器通过语句指定要复制的主服务器(注意,可以一主多从,不可一从多主).

change master to 
master_host=’192.168.1.101’, 
master_user=’replName’, 
master_password=’123456’, 
master_log_file=’mysql-bin.000001’, 
master_log_pos=0;

说明:

  • master_host是主服务器IP
  • master_user是刚才设置的主服务器复制帐号
  • master_password是刚才设置的主服务器复制帐号密码
  • master_log_file是主服务器二进制日志文件
  • master_log_pos是复制二进制文件的开始点
  • master_log_pos和master_log_file可以在主数据库中通过执行show master status;获取到

5、 启动slave

slave start

注意防火墙设置

主主配置

主从配置搞完以后,主主配置就很简单了,

基本思路:

1、 2台服务器都设置上2进制日志和relay日志
2、 都设置上replcation复制账号
3、 都设置对方为自己的master

开启mysql general log记录sql日志

对于在线的mysql修改如下:

mysql> show variables like 'general%';
Current database: loldb***
+------------------+------------------------+
| Variable_name | Value |
+------------------+------------------------+
| general_log | OFF |
| general_log_file | /data/mysql/var/s4.log |
+------------------+------------------------+
2 rows in set (0.03 sec)
mysql> SET GLOBAL general_log = 1;

然后去查看/data/mysql/var/s4.log 文件的内容,就可以看到sql语句

或在配置文件/etc/my.cnf里面[mysqld]下添加:

log = /data/mysql/var/s4.log

重启mysqld服务

例如类似的文件内容如下;

未分类

MySQL变量的用法

在编写存储过程中,有时需要使用变量,保存数据处理过程中的值
MySQL中,变量可以在子程序中,声明并使用,作用范围在BEGIN……END程序中

定义变量

在存储过程中,使用DECLARE语句,定义变量
语法格式

DECLARE var_name[,varname]……date_type[DEFAULT value]

参数说明

  • Var_name,为局部变量的名称
  • DEFAULT value,子句给变量提供一个默认值,该值除了可以声明为一个常数之外,还可以被指定为一个表达式
  • 如果,没有DEFAULT子句,变量的初始值为NULL

定义一个名称为myvariable的变量,类型为INT类型,默认值为100

DECLARE myvariable INT DEFAULT 100;

使用SET为变量赋值

定义变量之后,为变量赋值,改变变量的默认值
mysql中,使用SET语句为变量赋值

SET var_name=expr [,var_name=expr]……;

MySQL中
允许不同的变量类型,局域声明变量及全局变量,可以混合起来
允许把局部变量,和一些只对系统变量有意义的选项合并起来

SET a=x,b=y,……

声明三个变量,分别为var1、var2、var3,数据类型为INT,使用SET为变量赋值

DECLARE var1,var2,var3 int;
SET var1=10,var2=20;
SET var3=var1+var2;

使用SELECT……INTO为变量赋值

此外,除了使用SET为变量赋值
MySQL中,可以使用SELECT……INTO为一个或多个变量赋值
该语句可以把选定的列,直接存储到对应位置的变量
语法格式

SELECT col_name[……] INTO var_name [……] table_expr;

参数说明

  • Col_name,表示字段名称
  • Var_name,表示定义的变量名称
  • Table_expr,表示查询条件表达式,包括表名称和WHERE子句

声明变量s_grade和s_gender,通过SELECT……INTO语句,查询指定记录,并为变量赋值

未分类

上述语句,将student表中,name为rose的同学的成绩和性别,分别存入到了变量s_grade和s_gender中。

oracle数据库迁移到MySQL的三种方法

本文主要总结了oracle数据库迁移到MySQL的方法,方法包括手动方式导入导出、使用工具Navicat 进行导入、使用工具DBMover 的OracleToMySQL 进行导入和使用工具intelligent-converters 的 oracle-to-mysql 进行导入,需要的朋友可以参考下。

之前搭建了一个ExtJS + spring + Oracle 的这样一个报表系统的框架。 因为其他部门的要求, 也需要这个Framework 进行一些特殊的定制。

但是有一个问题是 Oracle 的数据库是需要收费的, 个人使用倒没什么问题, 公司使用的话就会有侵权的问题了。
而MySQL 则是完全免费的。

所以使用 ExtJS + Spring + MySQL 这样的组合应该就没什么问题了。

理论上来说, MySQL 已经被Oracle 收购, 这两者之间的Migrate 应该比较容易, 但实际的迁移还是有一些问题, 以下就说一说一些实现的方式和问题。

方式一: 手动方式导入导出

手动的方式导入, 就是操作步骤会比较繁琐一些。

对Table 的结构和数据:

1、 使用 SQL Developer 把 oracle 的 table 的schema 和 Data(.sql 和 .xls) 导出

2、 使用 MySQL 的 WorkBench 创建 Table 和导入数据。

这里语法上会稍微有一些不同, 所以需要略微做一些调整。

对于View 来说, 特别是复杂的有子查询的Oracle View 说, 要导入到MySQL 看起来就不是那么容易了。

方式二: 使用工具Navicat 进行导入

1、 新建数据库的连接,建立需要迁移的Oracle 和 MySQL 的数据库连接。

另外, 建立Oracle 连接的时候还需要下载一个oci.dll 的文件。

下载地址:http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html

下载之后, 解压到某个目录:

在 Navicat 的 工具 –> 选项 下做类似如下设置:

未分类

细部可以参见:http://wiki.navicat.com/wiki/index.php/Instant_client_required

完成设置后, 重启 navicat

2、 设置过连接之后,接下来就可以进行表和数据的migrate了

点击: 工具 –》 数据传输

在 “常规” 的标签页中设置需要 migrate 的连接

在 “高级” 的标签页中 ,设置需要 migrate 哪些具体的内容:

配置完成之后,点 “开始” 就可以了。

基本上:对于Table的结构和数据的迁移的话,基本上没什么问题。

但是对于View的导入,因为MySQL的View的语法不能有子查询语句。

在Navite上,可以看到从Oracle导入到MySQL的时候,View 的Checkbox 不能选取。

方式三:使用工具DBMover的OracleToMySQL进行导入

DBMover这个网站也提供了Oracle到MySQL 迁移的工具。

下载地址是:http://dbmover.com/download/oracletomysql_cn.zip

这也是一个收费的软件,试用版的限制是:允许迁移的记录条数累计为10万条。

下载安装,启动后会先要求输入数据库连接的信息,一直配置完成之后这里就只能看到table 了。

和Navicat比较起来,感觉这个显得简单,只能migrate table,而且使用上也不是很方便。

下一次Migrate又得重头到尾输入一次,没办法记住之前配置的连接。

MySQL高性能表设计规范

良好的逻辑设计和物理设计是高性能的基石, 应该根据系统将要执行的查询语句来设计schema, 这往往需要权衡各种因素。

一、选择优化的数据类型

MySQL支持的数据类型非常多, 选择正确的数据类型对于获得高性能至关重要。

更小的通常更好

更小的数据类型通常更快, 因为它们占用更少的磁盘、 内存和CPU缓存, 并且处理时需要的CPU周期也更少。

简单就好

简单数据类型的操作通常需要更少的CPU周期。 例如, 整型比字符操作代价更低, 因为字符集和校对规则(排序规则 )使字符比较比整型比较更复杂。

尽量避免NULL

如果查询中包含可为NULL 的列, 对MySQL来说更难优化, 因为可为NULL 的列使得索引、 索引统计和值比较都更复杂。 可为NULL的列会使用更多的存储空间, 在MySQL里也需要特殊处理。 当可为NULL的列被索引时, 每个索引记录需要一个额外的字节, 在MyISAM里甚至还可能导致固定大小的索引(例如只有一个整数列的索引)变成可变大小的索引。
当然也有例外, 例如InnoDB 使用单独的位 (bit) 存储NULL值, 所以对于稀疏数据有很好的空间效率。

1. 整数类型

有两种类型的数字:整数 (whole number) 和实数 (real number) 。 如果存储整数, 可以使用这几种整数类型:TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT。分别使用8,16, 24, 32, 64位存储空间。

整数类型有可选的 **UNSIGNED ** 属性,表示不允许负值,这大致可以使正数的上限提高一倍。 例如 TINYINT. UNSIGNED 可以存储的范围是 0 – 255, 而 TINYINT 的存储范围是 -128 -127 。

有符号和无符号类型使用相同的存储空间,并具有相同的性能 , 因此可以根据实际情况选择合适的类型。

你的选择决定 MySQL 是怎么在内存和磁盘中保存数据的。 然而, 整数计算一般使用64 位的 BIGINT 整数, 即使在 32 位环境也是如此。( 一些聚合函数是例外, 它们使用DECIMAL 或 DOUBLE 进行计算)。

MySQL 可以为整数类型指定宽度, 例如 INT(11), 对大多数应用这是没有意义的:它不会限制值的合法范围,只是规定了MySQL 的一些交互工具(例如 MySQL 命令行客户端)用来显示字符的个数。 对于存储和计算来说, INT(1) 和 INT(20) 是相同的。

2. 实数类型

实数是带有小数部分的数字。 然而, 它们不只是为了存储小数部分,也可以使用DECIMAL 存储比 BIGINT 还大的整数。

FLOAT和DOUBLE类型支持使用标准的浮点运算进行近似计算。
DECIMAL类型用于存储精确的小数。
浮点和DECIMAL类型都可以指定精度。 对于DECIMAL列, 可以指定小数点前后所允许的最大位数。这会影响列的空间消耗。

有多种方法可以指定浮点列所需要的精度, 这会使得MySQL选择不同的数据类型,或者在存储时对值进行取舍。 这些精度定义是非标准的,所以我们建议只指定数据类型,不指定精度。

浮点类型在存储同样范围的值时, 通常比DECIMAL使用更少的空间。FLOAT使用4个字节存储。DOUBLE占用8个字节,相比FLOAT有更高的精度和更大的范围。和整数类型一样, 能选择的只是存储类型; MySQL使用DOUBLE作为内部浮点计算的类型。

因为需要额外的空间和计算开销,所以应该尽量只在对小数进行精确计算时才使用DECIMAL。但在数据最比较大的时候, 可以考虑使用BIGINT代替DECIMAL, 将需要存储的货币单位根据小数的位数乘以相应的倍数即可。

3. 字符串类型

VARCHAR

用于存储可变⻓字符串,长度支持到65535
需要使用1或2个额外字节记录字符串的长度
适合:字符串的最大⻓度比平均⻓度⼤很多;更新很少

CHAR

定⻓,⻓度范围是1~255
适合:存储很短的字符串,或者所有值接近同一个长度;经常变更

慷慨是不明智的

使用VARCHAR(5)和VARCHAR(200)存储’hello’的空间开销是一样的。 那么使用更短的列有什么优势吗?

事实证明有很大的优势。 更长的列会消耗更多的内存, 因为MySQL通常会分配固定大小的内存块来保存内部值。 尤其是使用内存临时表进行排序或操作时会特别糟糕。 在利用磁盘临时表进行排序时也同样糟糕。

所以最好的策略是只分配真正需要的空间。

4. BLOB和TEXT类型

BLOB和 TEXT都是为存储很大的数据而设计的字符串数据类型, 分别采用 二进制和字符方式存储 。

与其他类型不同, MySQL把每个BLOB和TEXT值当作一个独立的对象处理。 存储引擎在存储时通常会做特殊处理。 当BLOB和TEXT值太大时,InnoDB会使用专门的 “外部“存储区域来进行存储, 此时每个值在行内需要1 – 4个字节存储 存储区域存储实际的值。

BLOB 和 TEXT 之间仅有的不同是 BLOB 类型存储的是二进制数据, 没有排序规则或字符集, 而 TEXT类型有字符集和排序规则

5. 日期和时间类型

大部分时间类型都没有替代品, 因此没有什么是最佳选择的问题。 唯一的问题是保存日期和时间的时候需要做什么。 MySQL提供两种相似的日期类型: DATE TIME和 TIMESTAMP。

但是目前我们更建议存储时间戳的方式,因此该处不再对 DATE TIME和 TIMESTAMP做过多说明。

6. 其他类型

6.1选择标识符

在可以满足值的范围的需求, 井且预留未来增长空间的前提下, 应该选择最小的数据类型。

整数类型

整数通常是标识列最好的选择, 因为它们很快并且可以使用AUTO_INCREMENT。

ENUM和SET类型

对于标识列来说,EMUM和SET类型通常是一个糟糕的选择, 尽管对某些只包含固定状态或者类型的静态 ”定义表” 来说可能是没有问题的。ENUM和SET列适合存储固定信息, 例如有序的状态、 产品类型、 人的性别。

字符串类型

如果可能, 应该避免使用字符串类型作为标识列, 因为它们很消耗空间, 并且通常比数字类型慢。

对于完全 “随机” 的字符串也需要多加注意, 例如 MDS() 、 SHAl() 或者 UUID() 产生的字符串。 这些函数生成的新值会任意分布在很大的空间内, 这会导致 INSERT 以及一些SELECT语句变得很慢。如果存储 UUID 值, 则应该移除 “-“符号。

6.2特殊类型数据

某些类型的数据井不直接与内置类型一致。 低千秒级精度的时间戳就是一个例子,另一个例子是以个1Pv4地址,人们经常使用VARCHAR(15)列来存储IP地址,然而, 它们实际上是32位无符号整数, 不是字符串。用小数点将地址分成四段的表示方法只是为了让人们阅读容易。所以应该用无符号整数存储IP地址。MySQL提供INET_ATON()和INET_NTOA()函数在这两种表示方法之间转换。

二、表结构设计

1. 范式和反范式

对于任何给定的数据通常都有很多种表示方法, 从完全的范式化到完全的反范式化, 以及两者的折中。 在范式化的数据库中, 每个事实数据会出现并且只出现一次。 相反, 在反范式化的数据库中, 信息是冗余的, 可能会存储在多个地方。

范式的优点和缺点

为性能提升考虑时,经常会被建议对 schema 进行范式化设计,尤其是写密集的场景。

  • 范式化的更新操作通常比反范式化要快。
  • 当数据较好地范式化时,就只有很少或者没有重复数据,所以只需要修改更少的数据。
  • 范式化的表通常更小,可以更好地放在内存里,所以执行操作会更快。
  • 很少有多余的数据意味着检索列表数据时更少需要 DISTINCT 或者 GROUP BY语句。

反范式的优点和缺点

不需要关联表,则对大部分查询最差的情况——即使表没有使用索引——是全表扫描。 当数据比内存大时这可能比关联要快得多,因为这样避免了随机I/0。

单独的表也能使用更有效的索引策略。

混用范式化和反范式化

在实际应用中经常需要混用,可能使用部分范式化的 schema 、 缓存表,以及其他技巧。
表适当增加冗余字段,如性能优先,但会增加复杂度。可避免表关联查询。

简单熟悉数据库范式

第一范式(1NF):字段值具有原子性,不能再分(所有关系型数据库系统都满足第一范式);
例如:姓名字段,其中姓和名是一个整体,如果区分姓和名那么必须设立两个独立字段;

第二范式(2NF):一个表必须有主键,即每行数据都能被唯一的区分;
备注:必须先满足第一范式;

第三范式(3NF):一个表中不能包涵其他相关表中非关键字段的信息,即数据表不能有沉余字段;
备注:必须先满足第二范式;

2. 表字段少⽽精

  • I/O高效
  • 字段分开维护简单
  • 单表1G体积 500W⾏行评估
  • 单⾏行不超过200Byte
  • 单表不超过50个INT字段
  • 单表不超过20个CHAR(10)字段
  • 建议单表字段数控制在20个以内
  • 拆分TEXT/BLOB,TEXT类型处理性能远低于VARCHAR,强制生成硬盘临时表浪费更多空间。

参考资料:

高性能mysql第三版