So Tired !_! 逆水行舟, 不进则退!

28Feb/17

手把手教你用Strace诊断问题

Posted by Nick Xu

早些年,如果你知道有个 strace 命令,就很牛了,而现在大家基本都知道 strace 了,如果你遇到性能问题求助别人,十有八九会建议你用 strace 挂上去看看,不过当你挂上去了,看着满屏翻滚的字符,却十有八九看不出个所以然。本文通过一个简单的案例,向你展示一下在用 strace 诊断问题时的一些套路。

strace是Linux环境下的一款程序调试工具,用来监察一个应用程序所使用的系统调用及它所接收的系统信息。追踪程序运行时的整个生命周期,输出每一个系统调用的名字,参数,返回值和执行消耗的时间等。
strace常用参数:
-p 跟踪指定的进程
-f 跟踪由fork子进程系统调用
-F 尝试跟踪vfork子进程系统调吸入,与-f同时出现时, vfork不被跟踪
-o filename 默认strace将结果输出到stdout。通过-o可以将输出写入到filename文件中
-ff 常与-o选项一起使用,不同进程(子进程)产生的系统调用输出到filename.PID文件
-r 打印每一个系统调用的相对时间
-t 在输出中的每一行前加上时间信息。 -tt 时间确定到微秒级。还可以使用-ttt打印相对时间
-v 输出所有系统调用。默认情况下,一些频繁调用的系统调用不会输出
-s 指定每一行输出字符串的长度,默认是32。文件名一直全部输出
-c 统计每种系统调用所执行的时间,调用次数,出错次数。
-e expr 输出过滤器,通过表达式,可以过滤出掉你不想要输出

如下真实案例,如有雷同,实属必然!让我们看一台高负载服务器的 top 结果:

top

技巧:运行 top 时,按「1」打开 CPU 列表,按「shift+p」以 CPU 排序。

在本例中大家很容易发现 CPU 主要是被若干个 PHP 进程占用了,同时 PHP 进程占用的比较多的内存,不过系统内存尚有结余,SWAP 也不严重,这并不是问题主因。

不过在 CPU 列表中能看到 CPU 主要消耗在内核态「sy」,而不是用户态「us」,和我们的经验不符。Linux 操作系统有很多用来跟踪程序行为的工具,内核态的函数调用跟踪用「strace」,用户态的函数调用跟踪用「ltrace」,所以这里我们应该用「strace」:

shell> strace -p <PID>

不过如果直接用 strace 跟踪某个进程的话,那么等待你的往往是满屏翻滚的字符,想从这里看出问题的症结并不是一件容易的事情,好在 strace  可以按操作汇总时间:

shell> strace -cp <PID>

通过「c」选项用来汇总各个操作的总耗时,运行后的结果大概如下图所示:

strace -cp <PID>

很明显,我们能看到 CPU 主要被 clone 操作消耗了,还可以单独跟踪一下 clone:

shell> strace -T -e clone -p <PID>

通过「T」选项可以获取操作实际消耗的时间,通过「e」选项可以跟踪某个操作:

strace -T -e clone -p <PID>

很明显,一个 clone 操作需要几百毫秒,至于 clone 的含义,参考 man 文档:

clone() creates a new process, in a manner similar to fork(2). It is actually a library function layered on top of the underlying clone() system call, hereinafter referred to as sys_clone. A description of sys_clone is given towards the end of this page.

Unlike fork(2), these calls allow the child process to share parts of its execution context with the calling process, such as the memory space, the table of file descriptors, and the table of signal handlers. (Note that on this manual page, “calling process” normally corresponds to “parent process”. But see the description of CLONE_PARENT below.)

简单来说,就是创建一个新进程。那么在 PHP 里什么时候会出现此类系统调用呢?查询业务代码看到了 exec 函数,通过如下命令验证它确实会导致 clone 系统调用:

shell> strace -eclone php -r 'exec("ls");'

如果想要追踪多个fpm进程可以用以下脚本:

strace -eall -c $(ps auxf|grep -E '(9013|9014|9015)'|awk '{if ($1="www-data") print "-p "$2}')

 

最后再考大家一个题:如果我们用 strace 跟踪一个进程,输出结果很少,是不是说明进程很空闲?其实试试 ltrace,可能会发现别有洞天。记住有内核态和用户态之分。

Filed under: Linux Comments Off
17Jan/17

Ubuntu解决RTNETLINK answers: File exists

Posted by Nick Xu

出现这种问题有两种原因

1.有两个网关时候

在ip地址配置中有两个网关

    auto eth0
    iface eth0 inet static
    address 192.168.5.21
    netmask 255.255.2550
    gateway 192.168.5.1

    # VM traffic interface
    auto eth1
    iface eth1 inet static
    address 192.168.5.22
    netmask 255.255.255.0
    gateway 192.168.5.1

eth0eth1有不同ip但是有都配置的网关,这时候一个启动后,另一个启动失败

RTNETLINK answers: File exists
Failed to bring up eth2.

如果你修改后,还是出现这种情况,就要对eth0eth1进行下刷新

    ip addr flush dev eth0
    ip addre flush dev eth1
    ifdown eth0 && ifup eth0 && ifdown eth1 && ifup eth1

2.当删除桥接或者其他,把网络改正确,还是出现这种问题

#确保网络配置已经正确的情况下
ip addr flush dev eth0
#重启网络配置

ip addr flush also dumps all the deleted addresses in the format described in the previous subsection
这个命令刷新已经删除的先前已经选择的地址格式

13Jan/17

tsar 的使用说明

Posted by Nick Xu

系统模块

cpu

字段含义

  • user: 表示CPU执行用户进程的时间,通常期望用户空间CPU越高越好.
  • sys: 表示CPU在内核运行时间,系统CPU占用率高,表明系统某部分存在瓶颈.通常值越低越好.
  • wait: CPU在等待I/O操作完成所花费的时间.系统部应该花费大量时间来等待I/O操作,否则就说明I/O存在瓶颈.
  • hirq: 系统处理硬中断所花费的时间百分比
  • sirq: 系统处理软中断所花费的时间百分比
  • util: CPU总使用的时间百分比
  • nice: 系统调整进程优先级所花费的时间百分比
  • steal: 被强制等待(involuntary wait)虚拟CPU的时间,此时hypervisor在为另一个虚拟处理器服务
  • ncpu: CPU的总个数

采集方式

CPU的占用率计算,都是根据/proc/stat计数器文件而来,stat文件的内容基本格式是:

cpu  67793686 1353560 66172807 4167536491 2705057 0 195975 609768
cpu0 10529517 944309 11652564 835725059 2150687 0 74605 196726
cpu1 14380773 127146 13908869 832565666 150815 0 31780 108418

cpu是总的信息,cpu0,cpu1等是各个具体cpu的信息,共有8个值,单位是ticks,分别是

User time, 67793686 Nice time, 1353560 System time, 66172807 Idle time, 4167536491 Waiting time, 2705057 Hard Irq time, 0 SoftIRQ time, 195975 Steal time, 609768

CPU总时间=user+system+nice+idle+iowait+irq+softirq+Stl
各个状态的占用=状态的cpu时间%CPU总时间*100%
比较特殊的是CPU总使用率的计算(util),目前的算法是:
util = 1 - idle - iowait - steal

mem

字段含义

  • free: 空闲的物理内存的大小
  • used: 已经使用的内存大小
  • buff: buff使用的内存大小,buffer is something that has yet to be "written" to disk.
  • cach: 操作系统会把经常访问的东西放在cache中加快执行速度,A cache is something that has been "read" from the disk and stored for later use
  • total: 系统总的内存大小
  • util: 内存使用率

采集方法

内存的计数器在/proc/meminfo,里面有一些关键项

    MemTotal:      7680000 kB
    MemFree:        815652 kB
    Buffers:       1004824 kB
    Cached:        4922556 kB

含义就不解释了,主要介绍一下内存使用率的计算算法:
util = (total - free - buff - cache) / total * 100%

load

字段含义

  • load1: 一分钟的系统平均负载
  • load5: 五分钟的系统平均负载
  • load15:十五分钟的系统平均负载
  • runq: 在采样时刻,运行队列的任务的数目,与/proc/stat的procs_running表示相同意思
  • plit: 在采样时刻,系统中活跃的任务的个数(不包括运行已经结束的任务)

采集方法

/proc/loadavg文件中保存的有负载相关的数据
0.00 0.01 0.00 1/271 23741
分别是1分钟负载,五分钟负载,十五分钟负载,运行进程/总进程 最大的pid
只需要采集前五个数据既可得到所有信息
注意:只有当系统负载除cpu核数>1的时候,系统负载较高

traffic

字段含义

  • bytin: 入口流量byte/s
  • bytout: 出口流量byte/s
  • pktin: 入口pkt/s
  • pktout: 出口pkt/s

采集方法

流量的计数器信息来自:/proc/net/dev

    face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo:1291647853895 811582000    0    0    0     0          0         0 1291647853895 811582000    0    0    0     0       0          0
    eth0:853633725380 1122575617    0    0    0     0          0         0 1254282827126 808083790    0    0    0     0       0          0

字段的含义第一行已经标示出来,每一行代表一个网卡,tsar主要采集的是出口和入口的bytes/packets
注意tsar只对以eth和em开头的网卡数据进行了采集,像lo这种网卡直接就忽略掉了,流量的单位是byte

tcp

字段含义

  • active:主动打开的tcp连接数目
  • pasive:被动打开的tcp连接数目
  • iseg: 收到的tcp报文数目
  • outseg:发出的tcp报文数目
  • EstRes:Number of resets that have occurred at ESTABLISHED
  • AtmpFa:Number of failed connection attempts
  • CurrEs:当前状态为ESTABLISHED的tcp连接数
  • retran:系统的重传率

采集方法

tcp的相关计数器文件是:/proc/net/snmp

    Tcp: RtoAlgorithm RtoMin RtoMax MaxConn ActiveOpens PassiveOpens AttemptFails EstabResets CurrEstab InSegs OutSegs RetransSegs InErrs OutRsts
    Tcp: 1 200 120000 -1 31702170 14416937 935062 772446 16 1846056224 1426620266 448823 0 5387732

我们主要关注其中的ActiveOpens/PassiveOpens/AttemptFails/EstabResets/CurrEstab/InSegs/OutSegs/RetransSegs
主要关注一下重传率的计算方式:
retran = (RetransSegs-last RetransSegs) / (OutSegs-last OutSegs) * 100%

udp

字段含义

  • idgm: 收到的udp报文数目
  • odgm: 发送的udp报文数目
  • noport:udp协议层接收到目的地址或目的端口不存在的数据包
  • idmerr:udp层接收到的无效数据包的个数

采集方法

UDP的数据来源文件和TCP一样,也是在/proc/net/snmp

    Udp: InDatagrams NoPorts InErrors OutDatagrams
    Udp: 31609577 10708119 0 159885874

io

字段含义

  • rrqms: The number of read requests merged per second that were issued to the device.
  • wrqms: The number of write requests merged per second that were issued to the device.
  • rs: The number of read requests that were issued to the device per second.
  • ws: The number of write requests that were issued to the device per second.
  • rsecs: The number of sectors read from the device per second.
  • wsecs: The number of sectors written to the device per second.
  • rqsize:The average size (in sectors) of the requests that were issued to the device.
  • qusize:The average queue length of the requests that were issued to the device.
  • await: The average time (in milliseconds) for I/O requests issued to the device to be served. This includes the time spent by the requests in queue and the time spent servicing them.
  • svctm: The average service time (in milliseconds) for I/O requests that were issued to the device.
  • util: Percentage of CPU time during which I/O requests were issued to the device (bandwidth utilization for the device).Device saturation occurs when this value is close to 100%.

采集方法

IO的计数器文件是:/proc/diskstats,比如:

    202    0 xvda 12645385 1235409 416827071 59607552 193111576 258112651 3679534806 657719704 0 37341324 717325100
    202    1 xvda1 421 2203 3081 9888 155 63 421 1404 0 2608 11292

每一行字段的含义是:

  • major: 主设备号
  • minor: 次设备号,设备号是用来区分磁盘的类型和厂家信息
  • name: 设备名称
  • rd_ios: 读完成次数,number of issued reads. This is the total number of reads completed successfully
  • rd_merges: 合并读完成次数,为了效率可能会合并相邻的读和写.从而两次4K的读在它最终被处理到磁盘上之前可能会变成一次8K的读,才被计数(和排队),因此只有一次I/O操作
  • rd_sectors: 读扇区的次数,number of sectors read. This is the total number of sectors read successfully.
  • rd_ticks: 读花费的毫秒数,number of milliseconds spent reading. This is the total number of milliseconds spent by all reads
  • wr_ios: 写完成次数,number of writes completed. This is the total number of writes completed successfully
  • wr_merges: 合并写完成次数,number of writes merged Reads and writes which are adjacent to each other may be merged for efficiency. Thus two 4K reads may become one 8K read before it is ultimately handed to the disk, and so it will be counted (and queued) as only one I/O.
  • wr_sectors: 写扇区次数,number of sectors written. This is the total number of sectors written successfully
  • wr_ticks: 写花费的毫秒数,number of milliseconds spent writing. This is the total number of milliseconds spent by all writes.
  • cur_ios: 正在处理的输入/输出请求数,number of I/Os currently in progress. The only field that should go to zero. Incremented as requests are given to appropriate request_queue_t and decremented as they finish.
  • ticks: 输入/输出操作花费的毫秒数
  • aveq: 输入/输出操作花费的加权毫秒数

通过这些计数器可以算出来上面的每个字段的值

double n_ios = rd_ios + wr_ios;
double n_ticks = rd_ticks + wr_ticks;
double n_kbytes = (rd_sectors + wr_sectors) / 2;
st_array[0] = rd_merges / (inter * 1.0);
st_array[1] = wr_merges / (inter * 1.0);
st_array[2] = rd_ios / (inter * 1.0);
st_array[3] = wr_ios / (inter * 1.0);
st_array[4] = rd_sectors / (inter * 2.0);
st_array[5] = wr_sectors / (inter * 2.0);
st_array[6] = n_ios ? n_kbytes / n_ios : 0.0;
st_array[7] = aveq / (inter * 1000);
st_array[8] = n_ios ? n_ticks / n_ios : 0.0;
st_array[9] = n_ios ? ticks / n_ios : 0.0;
st_array[10] = ticks / (inter * 10.0); 


注意:

扇区一般都是512字节,因此有的地方除以2了 ws是指真正落到io设备上的写次数, wrqpms是指系统调用合并的写次数, 它们之间的大小关系没有可比性,因为不知道多少请求能够被合并,比如发起了100个read系统调用,每个读4K,假如这100个都是连续的读,由于硬盘通常允许最大的request为256KB,那么block层会把这100个读请求合并成2个request,一个256KB,另一个144KB,rrqpm/s为100,因为100个request都发生了合并,不管它最后合并成几个;r/s为2,因为最后的request数为2

paritition

字段含义

  • bfree: 分区空闲的字节
  • bused: 分区使用中的字节
  • btotl: 分区总的大小
  • util: 分区使用率

采集方法

首先通过/etc/mtab获取到分区信息,然后通过statfs访问该分区的信息,查询文件系统相关信息,包含:

    struct statfs {
    long f_type; 
    long f_bsiz
    e; 
    long f_blocks; 
    long f_bfree; 
    long f_bavail; 
    long f_files; 
    long f_ffree; 
    fsid_t f_fsid; 
    long f_namelen; 
    };

然后就可以计算出tsar需要的信息,分区的字节数=块数*块大小=f_blocks * f_bsize

pcsw

字段含义

  • cswch: 进程切换次数
  • proc: 新建的进程数

采集方法

计数器在/proc/stat:

    ctxt 19873315174
    processes 296444211

分别代表进程切换次数,以及进程数

tcpx

字段含义

recvq sendq est twait fwait1 fwait2 lisq lising lisove cnest ndrop edrop rdrop pdrop kdrop
分别代表
tcprecvq tcpsendq tcpest tcptimewait tcpfinwait1 tcpfinwait2 tcplistenq tcplistenincq tcplistenover tcpnconnest tcpnconndrop tcpembdrop tcprexmitdrop tcppersistdrop tcpkadrop

采集方法

计数器来自:/proc/net/netstat /proc/net/snmp 里面用到的数据有:

    TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed EmbryonicRsts PruneCalled RcvPruned OfoPruned OutOfWindowIcmps LockDroppedIcmps ArpFilter TW TWRecycled TWKilled PAWSPassive PAWSActive PAWSEstab DelayedACKs DelayedACKLocked DelayedACKLost ListenOverflows ListenDrops TCPPrequeued TCPDirectCopyFromBacklog TCPDirectCopyFromPrequeue TCPPrequeueDropped TCPHPHits TCPHPHitsToUser TCPPureAcks TCPHPAcks TCPRenoRecovery TCPSackRecovery TCPSACKReneging TCPFACKReorder TCPSACKReorder TCPRenoReorder TCPTSReorder TCPFullUndo TCPPartialUndo TCPDSACKUndo TCPLossUndo TCPLoss TCPLostRetransmit TCPRenoFailures TCPSackFailures TCPLossFailures TCPFastRetrans TCPForwardRetrans TCPSlowStartRetrans TCPTimeouts TCPRenoRecoveryFail TCPSackRecoveryFail TCPSchedulerFailed TCPRcvCollapsed TCPDSACKOldSent TCPDSACKOfoSent TCPDSACKRecv TCPDSACKOfoRecv TCPAbortOnSyn TCPAbortOnData TCPAbortOnClose TCPAbortOnMemory TCPAbortOnTimeout TCPAbortOnLinger TCPAbortFailed TCPMemoryPressures
    TcpExt: 0 0 0 80 539 0 0 0 0 0 3733709 51268 0 0 0 80 5583301 5966 104803 146887 146887 6500405 39465075 2562794034 0 689613557 2730596 540646233 234702206 0 44187 2066 94 240 0 114 293 1781 7221 60514 185158 2 2 3403 400 107505 5860 24813 174014 0 2966 7 168787 106151 40 32851 2 0 2180 9862 0 15999 0 0 0

具体字段找到并且获取即可

percpu ncpu

字段含义

字段含义等同cpu模块,只不过能够支持采集具体的每一个cpu的信息

采集方法

等同于cpu模块

pernic

字段含义

字段含义等同traffic模块,只不过能够支持采集具体的每一个网卡的信息

采集方法

等同于traffic模块

应用模块

proc

字段含义

  • user: 某个进程用户态cpu消耗
  • sys: 某个进程系统态cpu消耗
  • total:某个进程总的cpu消耗
  • mem: 某个进程的内存消耗百分比
  • RSS: 某个进程的虚拟内存消耗,这是驻留在物理内存的一部分.它没有交换到硬盘.它包括代码,数据和栈
  • read: 进程io读字节
  • write:进程的io写字节

采集方法

计数器文件

/proc/pid/stat:获取进程的cpu信息
/proc/pid/status:获取进程的mem信息
/proc/pid/io:获取进程的读写IO信息

注意,需要将采集的进程名称配置在/etc/tsar/tsar.conf总的mod_proc on procname,这样就会找到procname的pid,并进行数据采集

nginx

字段含义

  • Accept:总共接收的新连接数目
  • Handle:总共处理的连接数目
  • Reqs:总共产生请求数目
  • Active:活跃的连接数,等于read+write+wait
  • Read:读取请求数据的连接数目
  • Write:向用户写响应数据的连接数目
  • Wait:长连接等待的连接数目
  • Qps:每秒处理的请求数
  • Rt:平均响应时间ms

采集方法

通过nginx的采集模块配置,访问特定地址,具体参见:https://github.com/taobao/tsar-mod_nginx

    location = /nginx_status {
        stub_status on;
    }

请求到的数据是:

    Active connections: 1
    server accepts handled requests request_time
    24 24 7 0
    Reading: 0 Writing: 1 Waiting: 0

需要确保nginx配置该location,并且能够访问curl http://localhost/nginx_status得到上面的数据
如果nginx的端口不是80,则需要在配置文件中指定端口,配置文件是/etc/tsar/tsar.conf,修改mod_nginx on为mod_nginx on 8080

类似的有nginx_code, nginx_domain模块,相应的配置是:

    req_status_zone server "$host" 20M;
    req_status server;
    location /traffic_status {
            req_status_show;
    } 

通过访问curl http://localhost/traffic_status能够得到如下字段的数据
localhost,0,0,2,2,2,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0

请求到的数据每个字段的含义是:

  • kv 计算得到的req_status_zone指令定义变量的值,此时为domain字段
  • bytes_in_total 从客户端接收流量总和
  • bytes_out_total 发送到客户端流量总和
  • conn_total 处理过的连接总数
  • req_total 处理过的总请求数
  • 2xx 2xx请求的总数
  • 3xx 3xx请求的总数
  • 4xx 4xx请求的总数
  • 5xx 5xx请求的总数
  • other 其他请求的总数
  • rt_total rt的总数
  • upstream_req 需要访问upstream的请求总数
  • upstream_rt 访问upstream的总rt
  • upstream_tries upstram总访问次数
  • 200 200请求的总数
  • 206 206请求的总数
  • 302 302请求的总数
  • 304 304请求的总数
  • 403 403请求的总数
  • 404 404请求的总数
  • 416 416请求的总数
  • 499 499请求的总数
  • 500 500请求的总数
  • 502 502请求的总数
  • 503 503请求的总数
  • 504 504请求的总数
  • 508 508请求的总数
  • detail_other 非以上13种status code的请求总数

如果domain数量太多,或者端口不是80,需要进行专门的配置,配置文件内容如下:
port=8080 #指定nginx的端口
top=10 #指定最多采集的域名个数,按照请求总个数排列
domain=a.com b.com #指定特定需要采集的域名列表,分隔符为空格,逗号,或者制表符
在/etc/tsar/tsar.conf中指定配置文件的路径:mod_nginx_domain on /tmp/my.conf

squid

字段含义

  • qps: 每秒请求数
  • rt: 访问平均相应时间
  • r_hit: 请求命中率
  • b_hit: 字节命中率
  • d_hit: 磁盘命中率
  • m_hit: 内存命中率
  • fdused: Number of file desc currently in use
  • fdque: Files queued for open
  • objs: StoreEntries
  • inmem: StoreEntries with MemObjects
  • hot: Hot Object Cache Items
  • size: Mean Object Size

采集方法

访问squid的mgrinfo信息获取,有些字段经过了一些patch,可能不适用外部版本

haproxy

字段含义

  • stat: 状态,1正常
  • uptime:启动持续时间
  • conns: 总的连接数
  • qps: 每秒请求数
  • hit: haproxy开启cache时的命中率
  • rt: 平均响应时间ms

采集方法

haproxy经过了patch,能够在多进程模式下进行统计信息的汇总,然后通过haproxy的本地访问其状态页面admin分析得到

lvs

字段含义

  • stat: lvs状态,1正常
  • conns: 总的连接数
  • pktin: 收到的包数
  • pktout:发出的包数
  • bytin: 收到的字节数
  • bytout:发出的字节数

采集方法

访问lvs的统计文件:/proc/net/ip_vs_stats

apache

参见:https://github.com/kongjian/tsar-apache

tcprt

私有应用,略

swift

私有应用,略

cgcpu/cgmem/cgblkio

私有应用,略

trafficserver

待补充

tmd

私有应用,略

Tagged as: Comments Off
21Dec/16

linux 下使用 rsync 进行文件 同步

Posted by Nick Xu

rsync 介绍

rsync是类unix系统下的数据镜像备份工具——remote sync。

rsync是一个功能非常强大的工具,其命令也有很多功能特色选项,我们下面就对它的选项一一进行分析说明。

它的特性如下:

可以镜像保存整个目录树和文件系统。

可以很容易做到保持原来文件的权限、时间、软硬链接等等。

无须特殊权限即可安装。

快速:第一次同步时 rsync 会复制全部内容,但在下一次只传输修改过的文件。rsync 在传输数据的过程中可以实行压缩及解压缩操作,

因此可以使用更少的带宽。

安全:可以使用scp、ssh等方式来传输文件,当然也可以通过直接的socket连接。

支持匿名传输,以方便进行网站镜像。

rysnc 的官方网站:http://rsync.samba.org/,可以从上面得到最新的版本。关于rsync算法的介绍点这里,还有陈皓blog.

rsync的使用

Rsync的命令格式可以为以下六种:

rsync [OPTION]... SRC DEST

rsync [OPTION]... SRC [USER@]HOST:DEST

rsync [OPTION]... [USER@]HOST:SRC DEST

rsync [OPTION]... [USER@]HOST::SRC DEST

rsync [OPTION]... SRC [USER@]HOST::DEST

rsync [OPTION]... rsync://[USER@]HOST[:PORT]/SRC [DEST]

rsync有六种不同的工作模式:

1. 拷贝本地文件;当SRC和DEST路径信息都不包含有单个冒号":"分隔符时就启动这种工作模式。

2.使用一个远程shell程序(如rsh、ssh)来实现将本地机器的内容拷贝到远程机器。当DEST

路径地址包含单个冒号":"分隔符时启动该模式。

3.使用一个远程shell程序(如rsh、ssh)来实现将远程机器的内容拷贝到本地机器。当SRC

地址路径包含单个冒号":"分隔符时启动该模式。

4. 从远程rsync服务器中拷贝文件到本地机。当SRC路径信息包含"::"分隔符时启动该模式。

5. 从本地机器拷贝文件到远程rsync服务器中。当DEST路径信息包含"::"分隔符时启动该模式。

6. 列远程机的文件列表。这类似于rsync传输,不过只要在命令中省略掉本地机信息即可。

可以man rsync 参考 rsync 文档,了解详细的使用方法,下面解析一些参数的使用:

rsync参数的具体解释如下:

-v, --verbose 详细模式输出

-q, --quiet 精简输出模式

-c, --checksum 打开校验开关,强制对文件传输进行校验

-a, --archive 归档模式,表示以递归方式传输文件,并保持所有文件属性,等于-rlptgoD

-r, --recursive 对子目录以递归模式处理

-R, --relative 使用相对路径信息

-b, --backup 创建备份,也就是对于目的已经存在有同样的文件名时,将老的文件重新命名为~filename。可以使用--suffix选项来指定不同的备份文件前缀。

--backup-dir 将备份文件(如~filename)存放在在目录下。

-suffix=SUFFIX 定义备份文件前缀

-u, --update 仅仅进行更新,也就是跳过所有已经存在于DST,并且文件时间晚于要备份的文件。(不覆盖更新的文件)

-l, --links 保留软链结

-L, --copy-links 想对待常规文件一样处理软链结

--copy-unsafe-links 仅仅拷贝指向SRC路径目录树以外的链结

--safe-links 忽略指向SRC路径目录树以外的链结

-H, --hard-links 保留硬链结

-p, --perms 保持文件权限

-o, --owner 保持文件属主信息

-g, --group 保持文件属组信息

-D, --devices 保持设备文件信息

-t, --times 保持文件时间信息

-S, --sparse 对稀疏文件进行特殊处理以节省DST的空间

-n, --dry-run现实哪些文件将被传输

-W, --whole-file 拷贝文件,不进行增量检测

-x, --one-file-system 不要跨越文件系统边界

-B, --block-size=SIZE 检验算法使用的块尺寸,默认是700字节

-e, --rsh=COMMAND 指定使用rsh、ssh方式进行数据同步

--rsync-path=PATH 指定远程服务器上的rsync命令所在路径信息

-C, --cvs-exclude 使用和CVS一样的方法自动忽略文件,用来排除那些不希望传输的文件

--existing 仅仅更新那些已经存在于DST的文件,而不备份那些新创建的文件

--delete 删除那些DST中SRC没有的文件

--delete-excluded 同样删除接收端那些被该选项指定排除的文件

--delete-after 传输结束以后再删除

--ignore-errors 及时出现IO错误也进行删除

--max-delete=NUM 最多删除NUM个文件

--partial 保留那些因故没有完全传输的文件,以是加快随后的再次传输

--force 强制删除目录,即使不为空

--numeric-ids 不将数字的用户和组ID匹配为用户名和组名

--timeout=TIME IP超时时间,单位为秒

-I, --ignore-times 不跳过那些有同样的时间和长度的文件

--size-only 当决定是否要备份文件时,仅仅察看文件大小而不考虑文件时间

--modify-window=NUM 决定文件是否时间相同时使用的时间戳窗口,默认为0

-T --temp-dir=DIR 在DIR中创建临时文件

--compare-dest=DIR 同样比较DIR中的文件来决定是否需要备份

-P 等同于 --partial

--progress 显示备份过程

-z, --compress 对备份的文件在传输时进行压缩处理

--exclude=PATTERN 指定排除不需要传输的文件模式

--include=PATTERN 指定不排除而需要传输的文件模式

--exclude-from=FILE 排除FILE中指定模式的文件

--include-from=FILE 不排除FILE指定模式匹配的文件

--version 打印版本信息

等等...

下面举例说明rsync的六种不同工作模式:

1)拷贝本地文件。当SRC和DES路径信息都不包含有单个冒号":"分隔符时就启动这种工作模式。
如:rsync -a  ./test.c  /backup

2)使用一个远程shell程序(如rsh、ssh)来实现将本地机器的内容拷贝到远程机器。当DES路径地址包含单个冒号":"分隔符时启动该模式。

如:rsync -avz  test.c  user@172.16.0.11:/home/user/src

3)使用一个远程shell程序(如rsh、ssh)来实现将远程机器的内容拷贝到本地机器。当SRC地址路径包含单个冒号":"分隔符时启动该模式。

如:rsync -avz user@172.16.0.11:/home/user/src  ./src

4)从远程rsync服务器中拷贝文件到本地机。当SRC路径信息包含"::"分隔符时启动该模式。

如:rsync -av user@172.16.0.11::www  /databack

5)从本地机器拷贝文件到远程rsync服务器中。当DES路径信息包含"::"分隔符时启动该模式。

如:rsync -av /databack user@172.16.0.11::www

6)列远程机的文件列表。这类似于rsync传输,不过只要在命令中省略掉本地机信息即可。

如:rsync -v rsync://172.16.78.192  /www

常见问题举例:

ssh端口更改后rsync的用法

rsync有两种常用的认证方式,一种为rsync-daemon方式,另外一种则是ssh。

ssh方式比较缺乏灵活性 一般为首选,但当远端服务器的ssh默认端口被修改后,rsync时找不到一个合适的方法来输入对方ssh服务端口号。

比如现在向机器 172.16.0.172 传送文件,但此时172.16.0.172的ssh端口已经不是 默认的22 端口。

键入命令 rsync test.c ustc@172.16.0.172:/home/ustc  出现如下的错误:

我们注意到rsync中的命令 参数  -e, --rsh=COMMAND 指定使用rsh、ssh方式进行数据同步。

参数的作用是可以使用户自由选择欲使用的shell程序来连接远端服务器,当然也可以设置成使用默认的ssh来连接,但是这样我们就可以加入ssh的参数了。

现在命令可以这样写了: rsync  -e  'ssh -p 3333'  test.c  ustc@172.16.0.172:/home/ustc

可见这是 文件传送修改ssh端口后的机器上成功,上面语句中使用了单引号,目的是为了使引号内的参数为引号内的命令所用。没有引号的话系统就会

识别-p是给rsync的一个参数了。

更多例子。。。

参考:

http://blog.csdn.net/jackdai/article/details/460460

 

 

##场景
服务器 A 192.168.1.1
服务器 B 192.168.1.2
要将 A 服务器的 /data/logs 目录同步到 B 服务器的 /home/logs 下

##执行环境
操作系统: centos 6.2

##配置
我们将使用 rsync 的 daemon 方式来完成任务
登录到 A 服务器,执行 vim /etc/rsyncd.conf
添加

uid = root
gid = root
max connections = 4
pid file = /var/run/rsyncd.pid
lock file = /var/run/rsync.lock
log file = /var/log/rsyncd.log

[logs]
path = /data/logs
ignore errors
read only = true
list = true
auth users = backup
secrets file = /etc/rsyncd.pwd

保存文件,执行vim /etc/rsyncd.pwd ,添加

backup:dahouduan.com

保存退出,执行 chmod 600 /etc/rsyncd.pwd
启动 rsync 服务 执行 rsync --daemon
登录 B 服务器 ,执行 vim /etc/rsyncd.pwd ,添加

dahouduan.com

保存退出,执行 chmod 600 /etc/rsyncd.pwd
好了,配置已经完成了,现在 A 服务器为服务端 B 服务器为客户端,现在就可以在 B 服务器上执行同步操作了

配置说明

uid = root #设置执行rsync的本地用户
gid = root #设置执行rsync的本地组
max connections = 4 #最大同时连接数
pid file = /var/run/rsyncd.pid #指定rsync服务进程的pid file
lock file = /var/run/rsync.lock #指定rsync服务端锁定文件log file = /var/log/rsyncd.log #指定rsync的log输出路径

[logs] #模块设定,可设置多个模块
path = /data/logs #同步文件的真实路径
ignore errors
read only = true #是否只读
list = true
auth users = backup #身份验证用户。这不是系统用户,而是rsync服务自定的
secrets file = /etc/rsyncd.pwd #当前模块的密码文件

开始同步

登录 B 服务器,执行

rsync -avzP --password-file=/etc/rsyncd.pwd backup@192.168.1.1::logs  /home/logs

so easy!

注意

1.如果 /home/下 logs 目录不存在将会创建,如果已经存在了, 会将 A 机器上的 /data/logs 目录下的内容同步到 B 机器上的 /home/logs/ 下
2.假如 A 机器上有一个文件 /home/logs/1.txt , 在第二次执行同步时没有修改,则不会同步
3.假如 B 机器上有一个文件 /home/logs/2.txt , A 上没有,同步时不会被删除
4.如果 B 机器上有一个文件 /home/logs/1.txt 被修改了,同步时会被 A 上对应的文件覆盖

扩展

如果要同步别的目录,只需要修改 A 服务器上的 /etc/rsyncd.conf 将 logs 部分修改或者复制一份,改成你想同步的目录就可以了,

One more thing

下面是 rsync 的语法说明:
rsync [-avrlptgoD] [-e ssh] [user@host:/dir] [/local/path]
-v :观察模式,可以列出更多的信息;
-q :与 -v 相反,安静模式,输出的信息比较少;
-r :递归复制!可以针对『目录』来处理!很重要!
-u :仅更新 (update),不会覆盖目标的新档案;
-l :复制连结文件的属性,而非连结的目标源文件内容;
-p :复制时,连同属性 (permission) 也保存不变!
-g :保存源文件的拥有群组;
-o :保存源文件的拥有人;
-D :保存源文件的装置属性 (device)
-t :保存源文件的时间参数;
-I :忽略更新时间 (mtime) 的属性,档案比对上会比较快速;
-z :加上压缩的参数!
-e :使用的信道协议,例如使用 ssh 通道,则 -e ssh
-a :相当于 -rlptgoD ,所以这个 -a 是最常用的参数了!

Tagged as: , Comments Off
25Nov/16

Mac原生系统对ntfs格式写操作支持

Posted by Nick Xu

弹出移动硬盘
执行 hdiutil eject /Volumes/Toshiba\ Portable\ Hard\ Drive/,如下输出
"disk1" unmounted.
"disk1" ejected.

创建一个目录,稍后将mount到这个目录
sodu mkdir /Volumes/MYHD

将移动硬盘以NTFS格式mount到上面的目录
sudo mount_ntfs -o rw,nobrowse /dev/disk1s1 /Volumes/MYHD/
执行完上面命令后,你可以看到你的移动硬盘灯又两起来了,没有任何输出,表示成功。

此时,你的移动硬盘可写了。 不过你不能在Finder里面操作,因为上面加了nobrowse选项。但是这个选项是必须的,否则你无法写。

Tagged as: , , Comments Off
15Nov/16

KVM虚拟机Linux系统增加硬盘

Posted by Nick Xu

Linux虚拟机在使用过程中,硬盘空间不够使用。由于前期没有做LVM,所以只能手动添加新的硬盘。

给虚拟机添加硬盘有两种方法:

1、通过virsh attach-disk命令添加一块硬盘到系统中,即时生效,但系统重启后新硬盘会消失。

2、通过修改虚拟机配置文件进行添加,永久生效。

现在我来一一介绍方法一和方法二。

方法一、通过virsh attach-disk命令添加硬盘

首先看看在未添加新硬盘系统的分区情况。

fdisk –l

df –h

clip_image001

从上图我们可以看到目前系统中只有一块硬盘vda,而且被分成3个分区,其中vda1为系统启动分区。

下面开始添加硬盘:

先使用 qemu-img添加一块新的硬盘

qemu-img create -f raw /vhost/testdisk.img 20G

clip_image002

现在开始使用virsh attach-disk命令把新硬盘添加到虚拟机上。

virsh attach-disk ilanni01 /vhost/testdisk.img vdb

clip_image003

该命令的意思是把/vhost/testdisk.img硬盘添加到虚拟机ilanni01中,并且该硬盘在虚拟机系统中显示的硬盘名称为vdb。

现在在系统中查看是否已经挂载该硬盘,使用fdisk命令,如下图:

clip_image004

以上操作是在虚拟机运行是,进行操作的。

现在我们把虚拟机关闭然后,再添加看看。

virsh destroy ilanni01

virsh list –all

clip_image005

再次使用virsh attach-disk添加新的硬盘vdc,如下命令:

virsh attach-disk ilanni01 /vhost/test1.img vdc

clip_image006

通过上图我们可以发现,通过virsh attach-disk添加硬盘时,只能是虚拟机运行时才能添加,而且是即时生效的。

现在我们重新启动虚拟机看看,如下图:

fdisk –l

clip_image007

通过上图,我们可以看到通过virsh attach-disk命令添加的硬盘在重启系统后,添加的新硬盘失效。

那么现在我们来看第二种方法通过修改配置文件来添加新硬盘。

要通过修改配置文件来添加硬盘,我们首先要关闭虚拟机,否则无法正常添加。

关闭虚拟机,然后使用virsh edit命令修改虚拟机的主配置文件。

虚拟机的所有配置文件都存放在/etc/libvirt/qemu,如下图:

clip_image008

编辑虚拟机配置文件,如下图:

clip_image009

配置文件中,我们找到有关硬盘的代码:

<disk type=’file’ device=’disk’>

<driver name=’qemu’ type=’qcow2′ cache=’none’/>

<source file=’/vhost/ilanni01.img’/>

<target dev=’vda’ bus=’virtio’/>

<address type=’pci’ domain=’0x0000′ bus=’0x00′ slot=’0x04′ function=’0x0’/>

</disk>

现在我们在</disk>这之后,添加如下的代码

<disk type=’file’ device=’disk’>

<driver name=’qemu’ type=’qcow2′ cache=’none’/>

<source file=’/vhost/testdisk.img’/>

<target dev=’vdb’ bus=’virtio’/>

</disk>

注意其中type表示硬盘的格式

file表示硬盘所在的路径

dev表示硬盘在系统中显示的硬盘名称

bus表示硬盘的接线类型,如果是windows系统一般是ide。

clip_image010

clip_image011

添加完毕后,我们来启动虚拟机看看实际的效果。

clip_image012

clip_image013

可以看到硬盘已经被添加进来了。

第一种方法和第二种方法的区别,以上两种方法都能添加硬盘。

但是如果是使用第一种方法添加的硬盘,使用virsh edit ilanni01编辑时,是无法看到第一种方法添加的硬盘的,同时在系统重启添加的硬盘会消失。也就是说使用第一种方法添加的硬盘是在ilanni01.xml这个配置文件中看不到的。

除此之外,如果是卸载硬盘,通过第一种方法添加的一定要在虚拟机运行时卸载。否则会报错,但是还会把该磁盘卸载掉。而且在此之前对硬盘的操作、分区,等都还存在。

卸载硬盘我们可以使用virsh detach-disk命令,如下图:

virsh detach-disk ilanni01 –target vdb

clip_image014

使用virsh detach-disk ilanni01 –target vdb 也可以卸载通过virsh edit ilanni01添加的硬盘。但是此时配置文件ilanni01.xml中还是有此信息的。使用 virsh attach-disk ilanni01 /vhost/testdisk.img vdb命令可以再增加,系统重启后还是存在的。

综上所述,在我们添加硬盘时,建议还是使用第二种方法。

Tagged as: Comments Off
9Oct/16

MySQL Index详解

Posted by Nick Xu

FROM:http://blog.csdn.net/tianmo2010/article/details/7930482

MySQL Index

一、SHOW INDEX会返回以下字段

1、Table 表的名称。

2、 Non_unique 如果索引不能包括重复词,则为0,如果可以则为1。

3、 Key_name 索引的名称

4、 Seq_in_index 索引中的列序列号,从1开始。

5、 Column_name 列名称。

6、 Collation 列以什么方式存储在索引中。在MySQL中,有值‘A’(升序)或NULL(无分类)。

7、Cardinality 索引中唯一值的数目的估计值。通过运行ANALYZE TABLE或myisamchk -a可以更新。基数根据被存储为整数的统计数据来计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL使用该索引的机会就越大。

8、Sub_part 如果列只是被部分地编入索引,则为被编入索引的字符的数目。如果整列被编入索引,则为NULL。

9、 Packed 指示关键字如何被压缩。如果没有被压缩,则为NULL。

10、 Null 如果列含有NULL,则含有YES。如果没有,则该列含有NO。

11、 Index_type 用过的索引方法(BTREE, FULLTEXT, HASH, RTREE)。

12、 Comment 多种评注,您可以使用db_name.tbl_name作为tbl_name FROM db_name语法的另一种形式。这两个语句是等价的:

mysql>SHOW INDEX FROM mytable FROM mydb;

mysql>SHOW INDEX FROM mydb.mytable;

二、使用 CREATE INDEX 创建索引

如果要为已存在的表创建索引,就需要使用 CREATE INDEX 命令或 ALTER TABLE 来创建索引。

CREATEINDEX idxtitle ON tablename (title)

这条命令将创建与 CREATE TABLE 命令相同的索引。

三、使用 ALTER TABLE 创建索引

ALTER TABLE tablename ADD INDEX idxtitle (title)

四、查看和删除索引

我们可以使用以下命令来查看已存在的索引:

SHOW INDEX FROM tablename

DROP INDEX indexname ON tablename

DROP INDEX 将删除 tablename 表上的 indexname 索引,indexname 就是我们创建表时指定的索引名。

########################################

createtable c(id char(20) not null primary key,`index` char(10));

问题1.如果我忘记把id设为主键现在该怎么办?输入什么命令?

ALTER TABLE record

ADD PRIMARY KEY (id);

例如:ALTER TABLE `abc` ADD PRIMARY KEY(`a`);

问题2.如果我想把id设为主键,同时想把name改为not null,且改为varchar(10),能不能用一句命令完成问题2?

ALTER TABLE record

ADD PRIMARY KEY (id),

CHANGEname varchar(10) not null;

########################################

索引 mysql index

索引是一种数据结构,可以是B-tree, R-tree, 或者 hash 结构。其中R-tree 常用于查询比较接近的数据;B-trees适合用于查找某范围内的数据,可以很快的从当前数据找到下条数据;hash结构则适用于随机访问的场合,查找每条数据的时间几乎相同。显然,若要查找某个时间段的数据,用B-tree结构要比hash结构快好多。

优化查询的有效方法是为经常查询的字段建立索引,如无索引查询数据时,会遍历整张表(多么恐怖啊);若有了索引查找会容易很多。当进行 UPDATE, DELETE, 以及 INSERT 操作时,mysql会自动更新索引信息。

1.创建和删除索引( Creating and dropping indexes )

创建:

[xhtml] view plaincopy

  1. mysql> USE sakila;
  2. Database changed
  3. mysql> CREATE INDEX idx_actor_first_name ON actor (first_name);
  4. 或者
  5. mysql> ALTER TABLE actor ADD INDEX idx_actor_first_name (first_name);

PS:当用 create index 创建索引时,必须指定索引的名字,否则mysql会报错;
用 ALTER TABLE 创建索引时,可以不指定索引名字,若不指定mysql会自动生成索引名字

建立索引时,若不想用存储引擎的默认索引类型,可以指定索引的类型:

  1. mysql> ALTER TABLE temp_index
  2.  ADD INDEX (first_name),
  3.  ADD INDEX lname (last_name) USING BTREE

删除:

  1. DROP INDEX indexname ON tblname
  2. mysql> DROP INDEX idx_actor_fname ON actor;
  3. mysql> ALTER TABLE actor DROP INDEX idx_actor_fname;

2.索引类型

BTREE    适合连续读取数据
RTREE    适合根据一条数据找附近的数据
HASH      适合随机读取数据
FULLTEXT
SPATIAL

查看某个表中存在的索引类型

  1. mysql> SELECT INDEX_NAME,INDEX_TYPE
  2. -> FROM INFORMATION_SCHEMA.STATISTICS
  3. -> WHERE TABLE_NAME=’temp_index’;
  4. +------------+------------+
  5. | INDEX_NAME | INDEX_TYPE |
  6. +------------+------------+
  7. | first_name | HASH       |
  8. | lname      | BTREE      |
  9. +------------+------------+

3.索引冗余

如果两个或者多个索引包含了相同的索引信息,那么就存在索引冗余。

不同类型的索引有不同的索引冗余判断:
(1) SPATIAL 索引
SPATIAL 只能是一个简单索引,不能说复合索引;存在冗余的情况是同一个字段有两个索引。
(2) FULLTEXT 索引
若一个FULLTEXT索引是另一个索引的子集(不考虑字段顺序),则存在冗余。
例如: 表中包含如下两个索引
■ (field1)
■ (field1, field2)
(3) HASH 索引
若一个索引在不考虑字段顺序的情况下,索引字段相同,则存在冗余。
例如:表中包含如下两个索引
■ (field1, field2, field3)
■ (field1, field3, field2)
(4) BTREE 索引
若一个索引是另一个索引的子集(考虑字段顺序),则存在冗余。
例如:表中包含如下两个索引
■ (field2)
■ (field2, field1)

PS:若两个或多个索引有相同的索引字段和字段顺序,但是有不同的索引类型,这样的索引是不冗余的。因为每种索引类型有自己的索引值。

######################################

深入MySQL数据库的索引

摘要:本文介绍索引的类型,已经如何创建索引做了介绍,其中涉及三个比较重要的SQL语句――ALTER TABLE、CREATE/DROP INDEX和CREATE TABLE,注意它们的用法。

索引是加速表内容访问的主要手段,特别对涉及多个表的连接的查询更是如此。这是数据库优化中的一个重要内容,我们要了解为什么需要索引,索引如何工作以及怎样利用它们来优化查询。本节中,我们将介绍索引的特点,以及创建和删除索引的语法。

索引的特点

所有的MySQL列类型能被索引。在相关的列上的使用索引是改进SELECT操作性能的最好方法。

一个表最多可有16个索引。最大索引长度是256个字节,尽管这可以在编译MySQL时被改变。

对于CHAR和 VARCHAR列,你可以索引列的前缀。这更快并且比索引整个列需要较少的磁盘空间。对于BLOB和TEXT列,你必须索引列的前缀,你不能索引列的全部。

MySQL能在多个列上创建索引。一个索引可以由最多15个列组成。(在CHAR和VARCHAR列上,你也可以使用列的前缀作为一个索引的部分)。

虽然随着 MySQL 的进一步开发创建索引的约束将会越来越少,但现在还是存在一些约束的。下面的表根据索引的特性,给出了 ISAM 表和 MyISAM 表之间的差别:

表2-1 通道信息特征字对照表索引的特点 ISAM 表 MyISAM 表

NULL 值

BLOB 和 TEXT 列

每个表中的索引数

每个索引中的列数

最大索引行尺寸

不允许

不能索引

16

16

256 字节 允许

只能索引列的前缀

32

16

500 字节

从此表中可以看到,对于 ISAM 表来说,其索引列必须定义为 NOT NULL,并且不能对 BLOB 和 TEXT 列进行索引。MyISAM 表类型去掉了这些限制,而且减缓了其他的一些限制。两种表类型的索引特性的差异表明,根据所使用的 MySQL 版本的不同,有可能对某些列不能进行索引。例如,如果使用3.23 版以前的版本,则不能对包含 NULL 值的列进行索引。

索引有如下的几种情况:

INDEX索引:通常意义的索引,某些情况下KEY是它的一个同义词。索引的列可以包括重复的值。

UNIQUE索引:唯一索引,保证了列不包含重复的值,对于多列唯一索引,它保证值的组合不重复。

PRIMARY KEY索引:也UNIQUE索引非常类似。事实上,PRIMARYKEY索引仅是一个具有PRIMARY名称的UNIQUE索引。这表示一个表只能包含一个PRIMARY KEY。

用Alter Table语句创建与删除索引

为了给现有的表增加一个索引,可使用 ALTER TABLE 或CREATE INDEX 语句。ALTER TABLE 最常用,因为可用它来创建普通索引、UNIQUE 索引或 PRIMARY KEY 索引,如:

ALTER TABLE tbl_name ADD INDEX index_name  (column_list)

ALTER TABLE tbl_name ADD UNIQUE index_name  (column_list)

ALTER TABLE tbl_name ADD PRIMARY KEY index_name  (column_list)

其中 tbl_name 是要增加索引的表名,而 column_list 指出对哪些列进行索引。一个(col1,col2,...)形式的列表创造一个多列索引。索引值有给定列的值串联而成。如果索引由不止一列组成,各列名之间用逗号分隔。索引名 index_name 是可选的,因此可以不写它,MySQL 将根据第一个索引列赋给它一个名称。ALTER TABLE 允许在单个语句中指定多个表的更改,因此可以在同时创建多个索引。

同样,也可以用ALTER TABLE语句删除列的索引:

ALTER TABLE tbl_name DROP INDEX index_name

ALTER TABLE tbl_name DROP PRIMARY KEY

注意上面第一条语句可以用来删除各种类型的索引,而第三条语句只在删除 PRIMARY KEY 索引时使用;在此情形中,不需要索引名,因为一个表只可能具有一个这样的索引。如果没有明确地创建作为 PRIMARY KEY 的索引,但该表具有一个或多个 UNIQUE 索引,则 MySQL 将删除这些 UNIQUE 索引中的第一个。

如果从表中删除了列,则索引可能会受到影响。如果所删除的列为索引的组成部分,则该列也会从索引中删除。如果组成索引的所有列都被删除,则整个索引将被删除。

例如,对于上面所使用的student为例,你可能想为之创建这样的索引,以加速表的检索速度:

mysql> ALTER TABLE student

-> ADD PRIMARY KEY(id),

-> ADD INDEXmark(english,Chinese,history);

这个例子,既包括PRIMARY索引,也包括多列索引。记住,使用 PRIMARY索引的列,必须是一个具有NOT NULL属性的列,如果你愿意查看创建的索引的情况,可以使用SHOW INDEX语句:

mysql> SHOW INDEX FROM student;

其结果为:

+---------+------------+----------+--------------+-------------+-

| Table  | Non_unique | Key_name | Seq_in_index | Column_name |

+---------+------------+----------+--------------+-------------+-

| student |          0 | PRIMARY  |           1 | id          |

| student |          1 | mark     |            1 | english     |

| student |          1 | mark     |            2 | chinese     |

| student |          1 | mark     |            3 | history     |

+---------+------------+----------+--------------+-------------+-

由于列数太多,上表并没有包括所有的输出,读者可以试着自己查看。

再使用ALTER TABLE语句删除索引,删除索引需要知道索引的名字,你可以通过SHOW INDEX语句得到:

mysql> ALTER TABLE student DROP PRIMARYKEY,

-> DROP INDEX mark;

再产看表中的索引,其语句和输出为:

mysql> SHOW INDEX FROM student;

Empty set (0.01 sec)

用CREATE\DROP INDEX创建索引

还可以用CREATE INDEX语句来创建索引.CREATE INDEX 是在 MySQL 3.23版中引入的,但如果使用3.23 版以前的版本,可利用 ALTER TABLE 语句创建索引(MySQL 通常在内部将 CREATE INDEX 映射到 ALTER TABLE)。该语句创建索引的语法如下:

CREATE UNIQUE INDEX index_name ON tbl_name(column_list)

CREATE INDEX index_name ON tbl_name(column_list) tbl_name、index_name 和 column_list 具有与 ALTER TABLE 语句中相同的含义。这里索引名不可选。很明显,CREATE INDEX 可对表增加普通索引或 UNIQUE 索引,不能用 CREATE INDEX 语句创建 PRIMARY KEY 索引。

可利用 DROP INDEX语句来删除索引。类似于 CREATE INDEX 语句,DROP INDEX 通常在内部作为一条 ALTER TABLE 语句处理,并且DROP INDEX是在 MySQL 3.22 中引入的。

删除索引语句的语法如下:

DROP INDEX index_name ON tbl_name

还是上一节的例子,由于CREATE INDEX不能创建PRIMARY索引,所以这里我们只创建一个多列索引:

mysql> CREATE INDEX mark ONstudent(english,chinese,history);

同样的检查student表,可知:

mysql> SHOW INDEX FROM student;

+---------+------------+----------+--------------+-------------+

| Table  | Non_unique | Key_name | Seq_in_index | Column_name |

+---------+------------+----------+--------------+-------------+

| student |          1 | mark     |           1 | english     |

| student |          1 | mark     |            2 | chinese     |

| student |          1 | mark     |            3 | history     |

+---------+------------+----------+--------------+-------------+

然后使用下面的语句删除索引:

mysql> DROP INDEX mark ON student;

在创建表时指定索引

要想在发布 CREATE TABLE 语句时为新表创建索引,所使用的语法类似于 ALTER TABLE 语句的语法,但是应该在您定义表列的语句部分指定索引创建子句,如下所示:

  1. CREATE TABLE tbl_name
  2. (
  3. INDEX index_name (column_list),
  4. KEY index_name (column_list),
  5. UNIQUE index_name (column_list),
  6. PRIMARY KEY index_name (column_list),
  7. )

与ALTER TABLE 一样,索引名对于 INDEX 和 UNIQUE 都是可选的,如果未给出,MySQL 将为其选一个。另外,这里KEY时INDEX的一个别名,具有相同的意义。

有一种特殊情形:可在列定义之后增加 PRIMARY KEY 创建一个单列的PRIMARY KEY 索引,如下所示:

  1. CREATE TABLE tbl_name
  2. (
  3.   iINT NOT NULL PRIMARY KEY
  4. )

该语句等价于以下的语句:

  1. CREATE TABLE tbl_name
  2. (
  3.   iINT NOT NULL,
  4.  PRIMARY KEY (i)
  5. )

前面所有表创建样例都对索引列指定了 NOT NULL。如果是 ISAM 表,这是必须的,因为不能对可能包含 NULL 值的列进行索引。如果是 MyISAM 表,索引列可以为 NULL,只要该索引不是 PRIMARY KEY 索引即可。

在CREATE TBALE语句中可以某个串列的前缀进行索引(列值的最左边 n 个字符)。

如果对某个串列的前缀进行索引,应用 column_list 说明符表示该列的语法为 col_name(n) 而不用col_name。例如,下面第一条语句创建了一个具有两个 CHAR 列的表和一个由这两列组成的索引。第二条语句类似,但只对每个列的前缀进行索引:

  1. CREATE TABLE tbl_name
  2. (
  3. name CHAR(30),
  4. address CHAR(60),
  5. INDEX (name,address)
  6. )
  1. CREATE TABLE tbl_name
  2. (
  3. name CHAR(30),
  4. address CHAR(60),
  5. INDEX (name(10),address(20))
  6. )

你可以检查所创建表的索引:

mysql> SHOW INDEX FROM tbl_name;

+----------+------------+----------+--------------+-------------+-

| Table   | Non_unique | Key_name | Seq_in_index | Column_name |

+----------+------------+----------+--------------+-------------+-

| tbl_name |          1 | name     |            1 | name        |

| tbl_name |          1 | name     |            2 | address     |

+----------+------------+----------+--------------+-------------+-

在某些情况下,可能会发现必须对列的前缀进行索引。例如,索引行的长度有一个最大上限,因此,如果索引列的长度超过了这个上限,那么就可能需要利用前缀进行索引。在 MyISAM 表索引中,对 BLOB 或 TEXT 列也需要前缀索引。

对一个列的前缀进行索引限制了以后对该列的更改;不能在不删除该索引并使用较短前缀的情况下,将该列缩短为一个长度小于索引所用前缀的长度的列。

总结

本节对索引的类型,已经如何创建索引做了介绍,其中涉及三个比较重要的SQL语句――ALTER TABLE、CREATE/DROP INDEX和CREATE TABLE,注意它们的用法。

索引最重要的功能是,通过使用索引加速表的检索,有关这方面的知识,将在第十章数据库优化中介绍。

思考题

1、建立一个如下所述的表:

data:FLOAT列,使用随机函数填充数据

birth:DATETIME列,填充当前时间。

然后,请录入几条数据。最后计算data列的平均值、总和、极值,并且按照data列降序排序检索值。

2、分别使用标准SQL模式和扩展正规表达式模式匹配,匹配上面创建的表,假设你创建表的当前日期为2001-01-01,用模式匹配检索出birth列包含该日期的值。(实际上,上面的表中记录都是同一日期录入的,因此实际将返回全部记录。)

3、为前几章使用的数据表创建索引:

student:为id段创建一个PRIMARY索引,为english、chinese和history创建一个多列索引。

pet:为name和owner段创建一个多类索引。

4、删除为pet表创建的索引。

##################################################

MySQL Index的使用

以下是理论知识备忘:

一、什么是索引?
索引用来快速地寻找那些具有特定值的记录,所有MySQL索引都以B-树的形式保存。如果没有索引,执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录,直至找到符合要求的记录。表里面的记录数量越多,这个操作的代价就越高。如果作为搜索条件的列上已经创建了索引,MySQL无需扫描任何记录即可迅速得到目标记录所在的位置。如果表有1000个记录,通过索引查找记录至少要比顺序扫描记录快100倍。

假设我们创建了一个名为people的表:

CREATE TABLE people ( peopleid SMALLINT NOT NULL, name CHAR(50) NOT NULL );

然后,我们完全随机把1000个不同name值插入到people表。下图显示了people表所在数据文件的一小部分:

可以看到,在数据文件中name列没有任何明确的次序。如果我们创建了name列的索引,MySQL将在索引中排序name列:

对于索引中的每一项,MySQL在内部为它保存一个数据文件中实际记录所在位置的“指针”。因此,如果我们要查找name等于“Mike”记录的 peopleid(SQL命令为“SELECT peopleid FROM people WHERE name='Mike';”),MySQL能够在name的索引中查找“Mike”值,然后直接转到数据文件中相应的行,准确地返回该行的 peopleid(999)。在这个过程中,MySQL只需处理一个行就可以返回结果。如果没有“name”列的索引,MySQL要扫描数据文件中的所有记录,即1000个记录!显然,需要MySQL处理的记录数量越少,则它完成任务的速度就越快。

二、索引的类型
MySQL提供多种索引类型供选择:

普通索引
这是最基本的索引类型,而且它没有唯一性之类的限制。普通索引可以通过以下几种方式创建:
创建索引,例如CREATE INDEX <索引的名字> ON tablename (列的列表);
修改表,例如ALTER TABLE tablename ADD INDEX [索引的名字] (列的列表);
创建表的时候指定索引,例如CREATE TABLE tablename ( [...], INDEX [索引的名字] (列的列表) );

唯一性索引
这种索引和前面的“普通索引”基本相同,但有一个区别:索引列的所有值都只能出现一次,即必须唯一。唯一性索引可以用以下几种方式创建:
创建索引,例如CREATE UNIQUE INDEX <索引的名字> ON tablename (列的列表);
修改表,例如ALTER TABLE tablename ADD UNIQUE [索引的名字] (列的列表);
创建表的时候指定索引,例如CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (列的列表) );

主键
主键是一种唯一性索引,但它必须指定为“PRIMARY KEY”。如果你曾经用过AUTO_INCREMENT类型的列,你可能已经熟悉主键之类的概念了。主键一般在创建表的时候指定,例如“CREATE TABLE tablename ( [...], PRIMARY KEY (列的列表) ); ”。但是,我们也可以通过修改表的方式加入主键,例如“ALTER TABLE tablename ADD PRIMARY KEY (列的列表); ”。每个表只能有一个主键。

全文索引
MySQL从3.23.23版开始支持全文索引和全文检索。在MySQL中,全文索引的索引类型为FULLTEXT。全文索引可以在VARCHAR或者TEXT类型的列上创建。它可以通过CREATE TABLE命令创建,也可以通过ALTER TABLE或CREATE INDEX命令创建。对于大规模的数据集,通过ALTER TABLE(或者CREATE INDEX)命令创建全文索引要比把记录插入带有全文索引的空表更快。本文下面的讨论不再涉及全文索引,要了解更多信息,请参见MySQL documentation。

三、单列索引与多列索引
索引可以是单列索引,也可以是多列索引。下面我们通过具体的例子来说明这两种索引的区别。假设有这样一个people表:

CREATE TABLE people ( peopleid SMALLINT NOT NULL AUTO_INCREMENT, firstname CHAR(50) NOT NULL, lastname CHAR(50) NOT NULL, age SMALLINT NOT NULL, townid SMALLINT NOT NULL, PRIMARY KEY (peopleid) );

下面是我们插入到这个people表的数据:

这个数据片段中有四个名字为“Mikes”的人(其中两个姓Sullivans,两个姓McConnells),有两个年龄为17岁的人,还有一个名字与众不同的Joe Smith。

这个表的主要用途是根据指定的用户姓、名以及年龄返回相应的peopleid。例如,我们可能需要查找姓名为Mike Sullivan、年龄17岁用户的peopleid(SQL命令为SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan' AND age=17;)。由于我们不想让MySQL每次执行查询就去扫描整个表,这里需要考虑运用索引。

首先,我们可以考虑在单个列上创建索引,比如firstname、lastname或者age列。如果我们创建firstname列的索引(ALTER TABLE people ADD INDEX firstname (firstname);),MySQL将通过这个索引迅速把搜索范围限制到那些firstname='Mike'的记录,然后再在这个“中间结果集”上进行其他条件的搜索:它首先排除那些lastname不等于“Sullivan”的记录,然后排除那些age不等于17的记录。当记录满足所有搜索条件之后,MySQL就返回最终的搜索结果。

由于建立了firstname列的索引,与执行表的完全扫描相比,MySQL的效率提高了很多,但我们要求MySQL扫描的记录数量仍旧远远超过了实际所需要的。虽然我们可以删除firstname列上的索引,再创建lastname或者 age列的索引,但总地看来,不论在哪个列上创建索引搜索效率仍旧相似。

为了提高搜索效率,我们需要考虑运用多列索引。如果为firstname、lastname和age这三个列创建一个多列索引,MySQL只需一次检索就能够找出正确的结果!下面是创建这个多列索引的SQL命令:

ALTER TABLE people ADD INDEX fname_lname_age (firstname,lastname,age);

由于索引文件以B-树格式保存,MySQL能够立即转到合适的firstname,然后再转到合适的lastname,最后转到合适的age。在没有扫描数据文件任何一个记录的情况下,MySQL就正确地找出了搜索的目标记录!

那么,如果在firstname、lastname、age这三个列上分别创建单列索引,效果是否和创建一个firstname、lastname、 age的多列索引一样呢?答案是否定的,两者完全不同。当我们执行查询的时候,MySQL只能使用一个索引。如果你有三个单列的索引,MySQL会试图选择一个限制最严格的索引。但是,即使是限制最严格的单列索引,它的限制能力也肯定远远低于firstname、lastname、age这三个列上的多列索引。

四、最左前缀
多列索引还有另外一个优点,它通过称为最左前缀(Leftmost Prefixing)的概念体现出来。继续考虑前面的例子,现在我们有一个firstname、lastname、age列上的多列索引,我们称这个索引为fname_lname_age。当搜索条件是以下各种列的组合时,MySQL将使用fname_lname_age索引:

firstname,lastname,age
firstname,lastname
firstname
从另一方面理解,它相当于我们创建了(firstname,lastname,age)、(firstname,lastname)以及(firstname)这些列组合上的索引。下面这些查询都能够使用这个fname_lname_age索引:

SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan' AND age='17'; SELECT peopleid FROM people WHERE firstname='Mike' AND lastname='Sullivan'; SELECT peopleid FROM people WHERE firstname='Mike'; The following queries cannot use the index at all: SELECT peopleid FROM people WHERE lastname='Sullivan'; SELECT peopleid FROM people WHERE age='17'; SELECT peopleid FROM people WHERE lastname='Sullivan' AND age='17';

五、选择索引列
在性能优化过程中,选择在哪些列上创建索引是最重要的步骤之一。可以考虑使用索引的主要有两种类型的列:在WHERE子句中出现的列,在join子句中出现的列。请看下面这个查询:

SELECT age ## 不使用索引
FROM people WHERE firstname='Mike' ## 考虑使用索引
AND lastname='Sullivan' ## 考虑使用索引

这个查询与前面的查询略有不同,但仍属于简单查询。由于age是在SELECT部分被引用,MySQL不会用它来限制列选择操作。因此,对于这个查询来说,创建age列的索引没有什么必要。下面是一个更复杂的例子:

SELECT people.age, ##不使用索引
town.name ##不使用索引
FROM people LEFT JOIN town ON
people.townid=town.townid ##考虑使用索引
WHERE firstname='Mike' ##考虑使用索引
AND lastname='Sullivan' ##考虑使用索引

与前面的例子一样,由于firstname和lastname出现在WHERE子句中,因此这两个列仍旧有创建索引的必要。除此之外,由于town表的townid列出现在join子句中,因此我们需要考虑创建该列的索引。

那么,我们是否可以简单地认为应该索引WHERE子句和join子句中出现的每一个列呢?差不多如此,但并不完全。我们还必须考虑到对列进行比较的操作符类型。MySQL只有对以下操作符才使用索引:<,<=,=,>,>=,BETWEEN,IN,以及某些时候的LIKE。可以在LIKE操作中使用索引的情形是指另一个操作数不是以通配符(%或者_)开头的情形。例如,“SELECT peopleid FROM peopleWHERE firstname LIKE 'Mich%';”这个查询将使用索引,但“SELECT peopleid FROM people WHERE firstname LIKE '%ike';”这个查询不会使用索引。

六、分析索引效率

现在我们已经知道了一些如何选择索引列的知识,但还无法判断哪一个最有效。MySQL提供了一个内建的SQL命令帮助

一、 MySQL建表,字段需设置为非空,需设置字段默认值。

二、 MySQL建表,字段需NULL时,需设置字段默认值,默认值不为NULL。

三、 MySQL建表,如果字段等价于外键,应在该字段加索引。

四、 MySQL建表,不同表之间的相同属性值的字段,列类型,类型长度,是否非空,是否默认值,需保持一致,否则无法正确使用索引进行关联对比。

五、 MySQL使用时,一条SQL语句只能使用一个表的一个索引。所有的字段类型都可以索引,多列索引的属性最多15个。

六、 如果可以在多个索引中进行选择,MySQL通常使用找到最少行的索引,索引唯一值最高的索引。

七、 建立索引index(part1,part2,part3),相当于建立了 index(part1),index(part1,part2)和index(part1,part2,part3)三个索引。

八、 MySQL针对like语法必须如下格式才使用索引:

SELECT * FROM t1 WHERE key_col LIKE 'ab%' ;

九、 SELECT COUNT(*) 语法在没有where条件的语句中执行效率没有SELECT COUNT(col_name)快,但是在有where条件的语句中执行效率要快。

十、 在where条件中多个and的条件中,必须都是一个多列索引的key_part属性而且必须包含key_part1。各自单一索引的话,只使用遍历最少行的那个索引。

十一、 在where条件中多个or的条件中,每一个条件,都必须是一个有效索引。

十二、 ORDER BY 后面的条件必须是同一索引的属性,排序顺序必须一致(比如都是升序或都是降序)。

十三、 所有GROUP BY列引用同一索引的属性,并且索引必须是按顺序保存其关键字的。

十四、 JOIN 索引,所有匹配ON和where的字段应建立合适的索引。

十五、 对智能的扫描全表使用FORCE INDEX告知MySQL,使用索引效率更高。

十六、 定期ANALYZE TABLE tbl_name为扫描的表更新关键字分布 。

十七、 定期使用慢日志检查语句,执行explain,分析可能改进的索引。

十八、 条件允许的话,设置较大的key_buffer_size和query_cache_size的值(全局参数),和sort_buffer_size的值(session变量,建议不要超过4M)。

20Sep/16

Ubuntu增加新硬盘并扩展LVM

Posted by Nick Xu

使用虚拟机安装Ubuntu LTS 14.04,刚开始只分配了20G的硬盘,采用LVM的方式进行管理。安装了几个数据库应用后发觉空间剩余不多,之能再添加了一个40G的硬盘上去,还好用LVM,扩展不是太麻烦。

1. 查看硬盘是否增加

2. 格式化新硬盘(根据自身情况分区)

3. 增加新的PV

4. 扩展VG

查看VG的名称

扩展VG

验证操作

5. 将新空间分配到LV

查看要增加的LV名称

增加空间

验证操作

 

 

 

 

 

 

LVM一种支持在线增大和减小的分区技术
一、PV物理卷
  由分区架构而成,为卷组提供空间。
二、VG卷组
  由一个或多个物理卷组成,为LV提供空间。
三、LV逻辑卷
  从卷组中获取空间,形成一个新的可用的LVM分区。
四、制作逻辑卷。
1、创建PV(在创建PV之前需要创建一个可用的分区,并且ID为8e)
[root@station19 media]# fdisk /dev/hda 对第一块IDE硬盘进行操作。这取决于你的环境。
The number of cylinders for this disk is set to 14593.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
   (e.g., DOS FDISK, OS/2 FDISK)
Command (m for help): n 新建一个分区
First cylinder (5421-14593, default 5421):
Using default value 5421
Last cylinder or +size or +sizeM or +sizeK (5421-14593, default 14593): +500M 给他500M的空间。
Command (m for help): p 查看一下当前硬盘分区的情况。
Disk /dev/hda: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
   Device Boot      Start         End      Blocks   Id  System
/dev/hda1   *           1          13      104391   83  Linux
/dev/hda2              14        3837    30716280   83  Linux
/dev/hda3            3838        5112    10241437+  83  Linux
/dev/hda4            5113       14593    76156132+   5  Extended
/dev/hda5            5113        5243     1052226   82  Linux swap / Solaris
/dev/hda6            5244        5308      522081   8e  Linux LVM
/dev/hda7            5309        5370      497983+  83  Linux
/dev/hda8            5371        5420      401593+  8e  Linux LVM
/dev/hda9            5421        5482      497983+  83  Linux
 (这是新建的那快分区)
Command (m for help): t 修改分区的表示符
Partition number (1-9): 9 选择对第9个分区进行操作
Hex code (type L to list codes): 8e 将标识符改为8e(只有将标识符改为8e才能支持LVM)
Changed system type of partition 9 to 8e (Linux LVM)
Command (m for help): p 再次查看一下
Disk /dev/hda: 120.0 GB, 120034123776 bytes
255 heads, 63 sectors/track, 14593 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
   Device Boot      Start         End      Blocks   Id  System
/dev/hda1   *           1          13      104391   83  Linux
/dev/hda2              14        3837    30716280   83  Linux
/dev/hda3            3838        5112    10241437+  83  Linux
/dev/hda4            5113       14593    76156132+   5  Extended
/dev/hda5            5113        5243     1052226   82  Linux swap / Solaris
/dev/hda6            5244        5308      522081   8e  Linux LVM
/dev/hda7            5309        5370      497983+  83  Linux
/dev/hda8            5371        5420      401593+  8e  Linux LVM
/dev/hda9            5421        5482      497983+  8e  Linux LVM
  (当前第9快分区的类型变成了8e,LVM)
Command (m for help): w 保存退出
[root@station19 media]# partprobe 重新加载分区,不加载或重启的话当前系统无法识别这个新的分区)
[root@station19 media]# pvcreate /dev/hda9  (将hda9这个分区制作成物理卷)
  Physical volume "/dev/hda9" successfully created
[root@station19 media]# pvdisplay  查看PV的内容
  --- Physical volume ---
  PV Name               /dev/hda9
  VG Name              
  PV Size               486.31 MB / not usable 2.31 MB
  Allocatable           yes
  PE Size (KByte)       4096
  Total PE              121
  Free PE               121
  Allocated PE          0
  PV UUID               0pE20O-EWqI-JtTY-gmeX-VJck-GUb0-Mxvx5v
       (从这些信息可以看出,/dev/hda9这个物理卷不属于任何VG,它的磁盘空间为486M)
2、创建VG 
[root@station19 media]# vgcreate vg /dev/hda9 
  Volume group "vg" successfully created
 将hda9这个物理卷加入到vg这个组里(vg为自己定义的名字)
 [root@station19 media]# vgdisplay
  --- Volume group ---
  VG Name               vg
  System ID             
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               484.00 MB
  PE Size               4.00 MB
  Total PE              121
  Alloc PE / Size       0 / 0   
  Free  PE / Size       121 / 484.00 MB
  VG UUID               6yOerB-EExr-sY0E-KFwO-fg0D-9Zol-RypiT5
  现在查看一下,vg这个卷组就拥有了484M的空间也就是/dev/hda9这个逻辑卷的空间
3、创建LV
[root@station19 media]# lvcreate -L 300M -n lv vg
  Logical volume "lv" created
 创建一个LV,并给他指定拥有300M的空间,vg为指定它属于哪个卷组,也就是由哪个卷组为它提供这300M的空间。
[root@station19 media]# lvdisplay
  --- Logical volume ---
  LV Name                /dev/vg/lv
  VG Name                vg
  LV UUID                HIc32H-DR98-Ymd1-Flhy-1Z2u-iU1Q-e2znLB
  LV Write Access        read/write
  LV Status              available
  # open                 0
  LV Size                300.00 MB
  Current LE             75
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:1
   现在查看一下LV信息,现在这个lv属于vg这个卷组并拥有300M的空间
5、格式化文件系统
[root@station19 media]# mkfs.ext3 /dev/vg/lv 将lv这个逻辑卷格式化为ext3文件系统
mke2fs 1.39 (29-May-2006)
Filesystem label=
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
76912 inodes, 307200 blocks
15360 blocks (5.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=67633152
38 block groups
8192 blocks per group, 8192 fragments per group
2024 inodes per group
Superblock backups stored on blocks:
        8193, 24577, 40961, 57345, 73729, 204801, 221185
Writing inode tables: done                            
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done
This filesystem will be automatically checked every 39 mounts or
180 days, whichever comes first.  Use tune2fs -c or -i to override.  
6、挂载
[root@station19 media]# mount /dev/vg/lv /lv 将/dev/vg/lv这个分区挂在到/下的lv下
[root@station19 media]# df -H /lv/   
文件系统               容量   已用  可用 已用% 挂载点
/dev/mapper/vg-lv      305M    11M   279M   4% /lv
查看一下/lv这个分区的大小,300M
 到现在为止,我们已经成功的创建了一个逻辑卷,但别忘了。逻辑卷最大的功能是增大和减小,下面我们来对逻辑卷进行增大和减小。
7、增大逻辑卷
[root@station19 media]# lvextend -L 500M /dev/vg/lv
  Extending logical volume lv to 500.00 MB
  Insufficient free space: 50 extents needed, but only 46 available
 [root@station19 media]# lvdisplay
  --- Logical volume ---
  LV Name                /dev/vg/lv
  VG Name                vg
  LV UUID                HIc32H-DR98-Ymd1-Flhy-1Z2u-iU1Q-e2znLB
  LV Write Access        read/write
  LV Status              available
  # open                 1
  LV Size                300.00 MB
  Current LE             75
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:1
这是一个失败的例子,因为lv所属的vg只有484M,所以当我将lv扩增到500M的时候会失败,因为vg无法为lv提供500M的空间。查看一下,lv仍然只有300M。
[root@station19 media]# lvextend -L 480M /dev/vg/lv
  Extending logical volume lv to 480.00 MB
  Logical volume lv successfully resized
[root@station19 media]# lvdisplay
  --- Logical volume ---
  LV Name                /dev/vg/lv
  VG Name                vg
  LV UUID                HIc32H-DR98-Ymd1-Flhy-1Z2u-iU1Q-e2znLB
  LV Write Access        read/write
  LV Status              available
  # open                 1
  LV Size                480.00 MB
  Current LE             120
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:1
现在我将lv扩增到480M,480M是vg所允许的空间大小,查看一下现在成功了。Lv被成功的扩增到了480M。
8、增大文件系统
[root@station19 media]# df -H /lv/
文件系统               容量   已用  可用 已用% 挂载点
/dev/mapper/vg-lv      305M    11M   279M   4% /lv
查看一下文件系统大小,lv这个文件系统仍是300M,因为我们之前扩展的只是它的分区大小,文件大小并没有增大,所以我们仍然只能使用300M的空间
[root@station19 media]# resize2fs /dev/vg/lv 480M
resize2fs 1.39 (29-May-2006)
Filesystem at /dev/vg/lv is mounted on /lv; on-line resizing required
Performing an on-line resize of /dev/vg/lv to 491520 (1k) blocks.
The filesystem on /dev/vg/lv is now 491520 blocks long.
[root@station19 media]# df -H /lv
文件系统               容量   已用  可用 已用% 挂载点
/dev/mapper/vg-lv      488M    11M   452M   3% /lv
现在用resize这个工具将/dev/vg/lv这个文件系统扩展到488M,查看一下成功了。
 *注:文件系统是建立在分区之上的,分区为我们提供空间,而我们真正能直接使用的是文件系统,例如windows下我们使用的ntfs文件系统一样。而在linux下使用的是ext3格式的文件系统。所以文件系统只能比分区小,不能比分区大。
9、缩小文件系统和分区
(1)减小文件系统时需要现卸载,因为resize这个工具不支持在线减小。
[root@station19 media]# umount /lv  卸载
[root@station19 media]# e2fsck -f /dev/vg/lv  
e2fsck 1.39 (29-May-2006)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/vg/lv: 11/121440 files (9.1% non-contiguous), 25872/491520 blocks
在减小文件系统之前需要先检查一下分区的完整性。
[root@station19 media]# resize2fs /dev/vg/lv 100M 将文件系统减小到100M
resize2fs 1.39 (29-May-2006)
Resizing the filesystem on /dev/vg/lv to 102400 (1k) blocks.
The filesystem on /dev/vg/lv is now 102400 blocks long.
 (2)缩小分区
[root@station19 media]# lvreduce -L 100M /dev/vg/lv
  WARNING: Reducing active logical volume to 100.00 MB
  THIS MAY DESTROY YOUR DATA (filesystem etc.)
Do you really want to reduce lv? [y/n]: y
  Reducing logical volume lv to 100.00 MB
  Logical volume lv successfully resized
将分区缩小到100M
[root@station19 media]# mount /dev/vg/lv /lv/
[root@station19 media]# df -H /lv/
文件系统               容量   已用  可用 已用% 挂载点
/dev/mapper/vg-lv      102M    11M    88M  11% /lv
[root@station19 media]# lvdisplay
  --- Logical volume ---
  LV Name                /dev/vg/lv
  VG Name                vg
  LV UUID                HIc32H-DR98-Ymd1-Flhy-1Z2u-iU1Q-e2znLB
  LV Write Access        read/write
  LV Status              available
  # open                 1
  LV Size                100.00 MB
  Current LE             25
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:1
挂载、查看,成功!文件系统和分区都为100M
10、增大与减小VG
这个很简单,VG是由多个物理卷构成的,只要将物理卷加入VG就可以实现增容,移出就能实现减小。
[root@station19 media]# pvcreate /dev/hda10 将一块新的lvm格式的分区做成物理卷
 Physical volume "/dev/hda10" successfully created
[root@station19 media]# vgextend vg /dev/hda10 将hda10这个分区加入到vg这个组
   Volume group "vg" successfully extended
[root@station19 media]# vgdisplay
  --- Volume group ---
  VG Name               vg
  System ID             
  Format                lvm2
  Metadata Areas        2
  Metadata Sequence No  5
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               1
  Max PV                0
  Cur PV                2
  Act PV                2
  VG Size               968.00 MB
  PE Size               4.00 MB
  Total PE              242
  Alloc PE / Size       25 / 100.00 MB
  Free  PE / Size       217 / 868.00 MB
  VG UUID               6yOerB-EExr-sY0E-KFwO-fg0D-9Zol-RypiT5
现在查看一下,VG这个卷组拥有了将近1G的空间。
减小、
root@station19 media]# vgreduce vg /dev/hda10
  Removed "/dev/hda10" from volume group "vg"
[root@station19 media]# vgdisplay
  --- Volume group ---
  VG Name               vg
  System ID             
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  6
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                1
  Open LV               1
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               484.00 MB
  PE Size               4.00 MB
  Total PE              121
  Alloc PE / Size       25 / 100.00 MB
  Free  PE / Size       96 / 384.00 MB
  VG UUID               6yOerB-EExr-sY0E-KFwO-fg0D-9Zol-RypiT5
将hda10这个物理卷从VG中移出,再查看,VG又被减小了。
Tagged as: , Comments Off
8Jul/16

MongoDB 备份(mongodump)与恢复(mongorerstore)

Posted by Nick Xu

MongoDB数据备份

在Mongodb中我们使用mongodump命令来备份MongoDB数据。该命令可以导出所有数据到指定目录中。

mongodump命令可以通过参数指定导出的数据量级转存的服务器。

语法

mongodump命令脚本语法如下:

>mongodump -h dbhost -d dbname -o dbdirectory
  • -h:MongDB所在服务器地址,例如:127.0.0.1,当然也可以指定端口号:127.0.0.1:27017
  • -d:需要备份的数据库实例,例如:test
  • -o:备份的数据存放位置,例如:c:\data\dump,当然该目录需要提前建立,在备份完成后,系统自动在dump目录下建立一个test目录,这个目录里面存放该数据库实例的备份数据。

实例

在本地使用 27017 启动你的mongod服务。打开命令提示符窗口,进入MongoDB安装目录的bin目录输入命令mongodump:

>mongodump

执行以上命令后,客户端会连接到ip为 127.0.0.1 端口号为 27017 的MongoDB服务上,并备份所有数据到 bin/dump/ 目录中。命令输出结果如下:

MongoDB数据备份

mongodump 命令可选参数列表如下所示:

语法 描述 实例
mongodump --host HOST_NAME --port PORT_NUMBER 该命令将备份所有MongoDB数据 mongodump --host w3cschool.cc --port 27017
mongodump --dbpath DB_PATH --out BACKUP_DIRECTORY mongodump --dbpath /data/db/ --out /data/backup/
mongodump --collection COLLECTION --db DB_NAME 该命令将备份指定数据库的集合。 mongodump --collection mycol --db test

MongoDB数据恢复

mongodb使用 mongorerstore 命令来恢复备份的数据。

语法

mongorestore命令脚本语法如下:

>mongorestore -h dbhost -d dbname --directoryperdb dbdirectory
  • -h:MongoDB所在服务器地址
  • -d:需要恢复的数据库实例,例如:test,当然这个名称也可以和备份时候的不一样,比如test2
  • --directoryperdb:备份数据所在位置,例如:c:\data\dump\test,这里为什么要多加一个test,而不是备份时候的dump,读者自己查看提示吧!
  • --drop:恢复的时候,先删除当前数据,然后恢复备份的数据。就是说,恢复后,备份后添加修改的数据都会被删除,慎用哦!

接下来我们执行以下命令:

>mongorestore

执行以上命令输出结果如下:

MongoDB数据恢复

Tagged as: Comments Off
6Jun/16

mini osd 手动接isp引脚刷bootloader

Posted by Nick Xu

发现mini osd很容易出问题, 第一次刷了对应f3飞控的osd后用了几次就没有osd信息了, 只有图像, 后来又刷了一次, 结果还是用几次后又没了, 而且这次还无法用USB2TTL线刷系统, 听说只能用ISP线来刷单片机, 结果发现这MINI OSD根本没有接上ISP的引脚, 又不知道哪个才是ISP引脚, 找了N久, 在即将要放弃时, 终于找到了ISP引脚图(其实最重要的只是这张图, 其它都是次要)

 

MINI OSD ISP 引脚标注图, 触点很小, 接线时小心, 别短路了.

BOOTLOADER FLASH

下图是我的接线, 这是已经刷完BOOTLOADER后测试刷OSD系统了

IMG20160603223727

然后就是刷BOOTLOADER了, 当然你得先有ISP刷写器,我是USBasp刷写器, 装progisp1.72, 懒得打字了, 直接看图吧, 从论坛上找过来的

522F9946-4E0F-4922-991D-28FA57CDB229

第四步, 固件位置在 arduino-1.0.1\hardware\arduino\bootloaders\atmega\ATmegaBOOT_168_atmega328.hex ,根据自己的arduino安装目录找吧

刷完BOOTLOADER就回到 arduino 刷OSD系统吧.

貌似手动刷了BOOTLOADER后变稳定了, 不会出现用几次就无法显示osd信息的情况, 估计是出厂时预刷有问题或者是出厂BOOTLOADER有问题. 还有一种可能是我的USB2TTL前两次刷的时候是跳线到3.3v而不是5v, 虽然接线还是接到5v的位置, 不过目前已无法考究具体是哪个原因导致的了.

 

 

Filed under: 其它, 单片机 Comments Off
site
site
test