mysql 512m-4g内存 配置文件优化记录

>512m-my.ini

[mysqld]
basedir=C:/APMServ5.2.6/MySQL5.1
datadir=C:/APMServ5.2.6/MySQL5.1/data
port=3306
key_buffer=64M
max_allowed_packet=1M
table_cache=256
thread_cache=16
join_buffer_size=4M
sort_buffer=4M
record_buffer=4M
max_connections=500
wait_timeout=120
interactive_timeout=120
max_connect_errors=6000
long_query_time=1
max_heap_table_size=32M
tmp_table_size=16M
thread_concurrency=8
myisam_sort_buffer_size=16M

1g-my.ini

[mysqld]
basedir=C:/APMServ5.2.6/MySQL5.1
datadir=C:/APMServ5.2.6/MySQL5.1/data
port=3306
key_buffer=256M
max_allowed_packet=2M
table_cache=512
thread_cache=32
join_buffer_size=16M
sort_buffer=16M
record_buffer=16M
max_connections=500
wait_timeout=120
interactive_timeout=120
max_connect_errors=30000
long_query_time=1
max_heap_table_size=128M
tmp_table_size=64M
thread_concurrency=8
myisam_sort_buffer_size=64M

2g-my.ini

[mysqld]
basedir=C:/APMServ5.2.6/MySQL5.1
datadir=C:/APMServ5.2.6/MySQL5.1/data
port=3306
key_buffer=384M
max_allowed_packet=4M
table_cache=1024
thread_cache=64
join_buffer_size=32M
sort_buffer=32M
record_buffer=32M
max_connections=500
wait_timeout=120
interactive_timeout=120
max_connect_errors=30000
long_query_time=1
max_heap_table_size=256M
tmp_table_size=128M
thread_concurrency=8
myisam_sort_buffer_size=128M

4g-my.ini

[mysqld]
basedir=C:/APMServ5.2.6/MySQL5.1
datadir=C:/APMServ5.2.6/MySQL5.1/data
port=3306
key_buffer=512M
max_allowed_packet=8M
table_cache=2048
thread_cache=128
join_buffer_size=64M
sort_buffer=64M
record_buffer=64M
max_connections=500
wait_timeout=120
interactive_timeout=120
max_connect_errors=30000
long_query_time=1
max_heap_table_size=256M
tmp_table_size=128M
thread_concurrency=8
myisam_sort_buffer_size=128M

发表在 新闻头条 | 标签为 | mysql 512m-4g内存 配置文件优化记录已关闭评论

8G内存下MySQL的优化详细方案

对于任何一个数据库管理系统来说,内存的分配使用绝对可以算的上是其核心之一了,所以很多希望更为深入了解某数据库管理系统的人,都会希望一窥究竟,我也不例外。

这里给出方案

按照下面的设置试试看:

key_buffer = 3840M
max_allowed_packet = 16M
table_cache = 1024
sort_buffer_size = 32M
read_buffer_size = 32M
read_rnd_buffer_size = 32M
myisam_sort_buffer_size = 256M
thread_cache_size = 32
query_cache_size = 256M
# Try number of CPU’s*2 for thread_concurrency
thread_concurrency = 8

其中key_buffer_size 上限是4G,不能再多了
但是实际的为了使MySql的性能最优化,内存的分配是需要进行调试的。建议你参考一下文章进行设置:

从内存的使用方式MySQL 数据库的内存使用主要分为以下两类

线程独享内存
全局共享内存

线程独享内存

在 MySQL 中,线程独享内存主要用于各客户端连接线程存储各种操作的独享数据,如线程栈信息,分组排序操作,数据读写缓冲,结果集暂存等等,而且大多数可以通过相关参数来控制内存的使用量。

线程栈信息使用内存(thread_stack):主要用来存放每一个线程自身的标识信息,如线程id,线程运行时基本信息等等,我们可以通过 thread_stack 参数来设置为每一个线程栈分配多大的内存。

排序使用内存(sort_buffer_size):MySQL用此内存区域进行排序操作(filesort),完成客户端的排序请求。当我们设置的排序区缓存大小无法满足排序实际所需内存的时候,MySQL会将数据写入磁盘文件来完成排序。由于磁盘和内存的读写性能完全不在一个数量级,所以sort_buffer_size参数对排序操作的性能影响绝对不可小视。

Join操作使用内存(join_buffer_size):应用程序经常会出现一些两表(或多表)Join的操作需求,MySQL在完成某些 Join 需求的时候(all/indexjoin),为了减少参与Join的“被驱动表”的读取次数以提高性能,需要使用到 Join Buffer 来协助完成 Join操作。当 Join Buffer 太小,MySQL 不会将该 Buffer 存入磁盘文件,而是先将Join Buffer中的结果集与需要 Join的表进行 Join 操作,然后清空 Join Buffer 中的数据,继续将剩余的结果集写入此 Buffer中,如此往复。这势必会造成被驱动表需要被多次读取,成倍增加 IO 访问,降低效率。

顺序读取数据缓冲区使用内存(read_buffer_size):这部分内存主要用于当需要顺序读取数据的时候,如无发使用索引的情况下的全表扫描,全索引扫描等。在这种时候,MySQL按照数据的存储顺序依次读取数据块,每次读取的数据快首先会暂存在read_buffer_size中,当 buffer空间被写满或者全部数据读取结束后,再将buffer中的数据返回给上层调用者,以提高效率。

随机读取数据缓冲区使用内存(read_rnd_buffer_size):和顺序读取相对应,当MySQL进行非顺序读取(随机读取)数据块的时候,会利用这个缓冲区暂存读取的数据。如根据索引信息读取表数据,根据排序后的结果集与表进行Join等等。总的来说,就是当数据块的读取需要满足一定的顺序的情况下,MySQL 就需要产生随机读取,进而使用到 read_rnd_buffer_size参数所设置的内存缓冲区。

连接信息及返回客户端前结果集暂存使用内存(net_buffer_size):这部分用来存放客户端连接线程的连接信息和返回客户端的结果集。当 MySQL 开始产生可以返回的结果集,会在通过网络返回给客户端请求线程之前,会先暂存在通过net_buffer_size所设置的缓冲区中,等满足一定大小的时候才开始向客户端发送,以提高网络传输效率。不过,net_buffer_size参数所设置的仅仅只是该缓存区的初始化大小,MySQL 会根据实际需要自行申请更多的内存以满足需求,但最大不会超过max_allowed_packet 参数大小。

批量插入暂存使用内存(bulk_insert_buffer_size):当我们使用如 insert …values(…),(…),(…)… 的方式进行批量插入的时候,MySQL会先将提交的数据放如一个缓存空间中,当该缓存空间被写满或者提交完所有数据之后,MySQL才会一次性将该缓存空间中的数据写入数据库并清空缓存。此外,当我们进行 LOAD DATA INFILE 操作来将文本文件中的数据 Load进数据库的时候,同样会使用到此缓冲区。

临时表使用内存(tmp_table_size):当我们进行一些特殊操作如需要使用临时表才能完成的Order By,Group By 等等,MySQL 可能需要使用到临时表。当我们的临时表较小(小于 tmp_table_size参数所设置的大小)的时候,MySQL 会将临时表创建成内存临时表,只有当 tmp_table_size所设置的大小无法装下整个临时表的时候,MySQL 才会将该表创建成 MyISAM 存储引擎的表存放在磁盘上。不过,当另一个系统参数max_heap_table_size 的大小还小于 tmp_table_size 的时候,MySQL 将使用max_heap_table_size 参数所设置大小作为最大的内存临时表大小,而忽略 tmp_table_size 所设置的值。而且tmp_table_size 参数从 MySQL 5.1.2 才开始有,之前一直使用 max_heap_table_size。

上面所列举的 MySQL 线程独享内存仅仅只是所有线程独享内存中的部分,并不是全部,选择的原则是可能对 MySQL 的性能产生较大的影响,且可以通过系统参数进行调节。

由于以上内存都是线程独享,极端情况下的内存总体使用量将是所有连接线程的总倍数。所以各位朋友在设置过程中一定要谨慎,切不可为了提升性能就盲目的增大各参数值,避免因为内存不够而产生 Out Of Memory 异常或者是严重的 Swap 交换反而降低整体性能。

全局共享内存

全局共享内主要是 MySQLInstance(mysqld进程)以及底层存储引擎用来暂存各种全局运算及可共享的暂存信息,如存储查询缓存的 QueryCache,缓存连接线程的 Thread Cache,缓存表文件句柄信息的 Table Cache,缓存二进制日志的 BinLogBuffer, 缓存 MyISAM 存储引擎索引键的 Key Buffer以及存储 InnoDB 数据和索引的 InnoDB BufferPool 等等。下面针对 MySQL 主要的共享内存进行一个简单的分析。

查询缓存(Query Cache):查询缓存是 MySQL 比较独特的一个缓存区域,用来缓存特定Query 的结果集(Result Set)信息,且共享给所有客户端。通过对 Query 语句进行特定的 Hash 计算之后与结果集对应存放在Query Cache 中,以提高完全相同的 Query 语句的相应速度。当我们打开 MySQL 的 Query Cache 之后,MySQL接收到每一个 SELECT 类型的 Query 之后都会首先通过固定的 Hash 算法得到该 Query 的 Hash 值,然后到 QueryCache 中查找是否有对应的 Query Cache。如果有,则直接将 Cache的结果集返回给客户端。如果没有,再进行后续操作,得到对应的结果集之后将该结果集缓存到 Query Cache中,再返回给客户端。当任何一个表的数据发生任何变化之后,与该表相关的所有 Query Cache 全部会失效,所以 Query Cache对变更比较频繁的表并不是非常适用,但对那些变更较少的表是非常合适的,可以极大程度的提高查询效率,如那些静态资源表,配置表等等。为了尽可能高效的利用 Query Cache,MySQL 针对 Query Cache 设计了多个 query_cache_type 值和两个 QueryHint:SQL_CACHE 和 SQL_NO_CACHE。当 query_cache_type 设置为0(或者 OFF)的时候不使用Query Cache,当设置为1(或者 ON)的时候,当且仅当 Query 中使用了 SQL_NO_CACHE 的时候 MySQL 会忽略Query Cache,当 query_cache_type 设置为2(或者DEMAND)的时候,当且仅当Query 中使用了SQL_CACHE 提示之后,MySQL 才会针对该 Query 使用 Query Cache。可以通过 query_cache_size来设置可以使用的最大内存空间。

连接线程缓存(Thread Cache):连接线程是 MySQL为了提高创建连接线程的效率,将部分空闲的连接线程保持在一个缓存区以备新进连接请求的时候使用,这尤其对那些使用短连接的应用程序来说可以极大的提高创建连接的效率。当我们通过 thread_cache_size设置了连接线程缓存池可以缓存的连接线程的大小之后,可以通过(Connections – Threads_created) /Connections * 100% 计算出连接线程缓存的命中率。注意,这里设置的是可以缓存的连接线程的数目,而不是内存空间的大小。

表缓存(Table Cache):表缓存区主要用来缓存表文件的文件句柄信息,在MySQL5.1.3之前的版本通过 table_cache 参数设置,但从MySQL5.1.3开始改为 table_open_cache来设置其大小。当我们的客户端程序提交 Query 给 MySQL 的时候,MySQL 需要对 Query所涉及到的每一个表都取得一个表文件句柄信息,如果没有 Table Cache,那么 MySQL就不得不频繁的进行打开关闭文件操作,无疑会对系统性能产生一定的影响,Table Cache 正是为了解决这一问题而产生的。在有了 TableCache 之后,MySQL 每次需要获取某个表文件的句柄信息的时候,首先会到 Table Cache中查找是否存在空闲状态的表文件句柄。如果有,则取出直接使用,没有的话就只能进行打开文件操作获得文件句柄信息。在使用完之后,MySQL会将该文件句柄信息再放回 Table Cache池中,以供其他线程使用。注意,这里设置的是可以缓存的表文件句柄信息的数目,而不是内存空间的大小。

表定义信息缓存(Table definition Cache):表定义信息缓存是从MySQL5.1.3 版本才开始引入的一个新的缓存区,用来存放表定义信息。当我们的 MySQL中使用了较多的表的时候,此缓存无疑会提高对表定义信息的访问效率。MySQL 提供了 table_definition_cache参数给我们设置可以缓存的表的数量。在 MySQL5.1.25 之前的版本中,默认值为128,从 MySQL5.1.25版本开始,则将默认值调整为 256 了,最大设置值为524288。注意,这里设置的是可以缓存的表定义信息的数目,而不是内存空间的大小。

二进制日志缓冲区(Binlog Buffer):二进制日志缓冲区主要用来缓存由于各种数据变更操做所产生的Binary Log 信息。为了提高系统的性能,MySQL 并不是每次都是将二进制日志直接写入 Log File,而是先将信息写入Binlog Buffer 中,当满足某些特定的条件(如 sync_binlog参数设置)之后再一次写入 Log File 中。我们可以通过binlog_cache_size 来设置其可以使用的内存大小,同时通过 max_binlog_cache_size限制其最大大小(当单个事务过大的时候 MySQL 会申请更多的内存)。当所需内存大于 max_binlog_cache_size参数设置的时候,MySQL 会报错:“Multi-statement transaction required more than‘max_binlog_cache_size’ bytes of storage”。

MyISAM索引缓存(Key Buffer):MyISAM 索引缓存将 MyISAM 表的索引信息缓存在内存中,以提高其访问性能。这个缓存可以说是影响 MyISAM 存储引擎性能的最重要因素之一了,通过 key_buffere_size 设置可以使用的最大内存空间。

InnoDB 日志缓冲区(InnoDB Log Buffer):这是 InnoDB存储引擎的事务日志所使用的缓冲区。类似于 Binlog Buffer,InnoDB 在写事务日志的时候,为了提高性能,也是先将信息写入Innofb Log Buffer 中,当满足 innodb_flush_log_trx_commit参数所设置的相应条件(或者日志缓冲区写满)之后,才会将日志写到文件(或者同步到磁盘)中。可以通过 innodb_log_buffer_size参数设置其可以使用的最大内存空间。
注:innodb_flush_log_trx_commit 参数对 InnoDB Log 的写入性能有非常关键的影响。该参数可以设置为0,1,2,解释如下:

0:log buffer中的数据将以每秒一次的频率写入到log file中,且同时会进行文件系统到磁盘的同步操作,但是每个事务的commit并不会触发任何log buffer 到log file的刷新或者文件系统到磁盘的刷新操作;
1:在每次事务提交的时候将log buffer 中的数据都会写入到log file,同时也会触发文件系统到磁盘的同步;
2:事务提交会触发log buffer 到log file的刷新,但并不会触发磁盘文件系统到磁盘的同步。此外,每秒会有一次文件系统到磁盘同步操作。
此外,MySQL文档中还提到,这几种设置中的每秒同步一次的机制,可能并不会完全确保非常准确的每秒就一定会发生同步,还取决于进程调度的问题。实际上,InnoDB 能否真正满足此参数所设置值代表的意义正常 Recovery 还是受到了不同 OS下文件系统以及磁盘本身的限制,可能有些时候在并没有真正完成磁盘同步的情况下也会告诉 mysqld 已经完成了磁盘同步。

InnoDB 数据和索引缓存(InnoDB Buffer Pool):InnoDB BufferPool 对 InnoDB 存储引擎的作用类似于 Key Buffer Cache 对 MyISAM 存储引擎的影响,主要的不同在于InnoDB Buffer Pool 不仅仅缓存索引数据,还会缓存表的数据,而且完全按照数据文件中的数据快结构信息来缓存,这一点和Oracle SGA 中的 database buffer cache 非常类似。所以,InnoDB Buffer Pool 对 InnoDB存储引擎的性能影响之大就可想而知了。可以通过 (Innodb_buffer_pool_read_requests -Innodb_buffer_pool_reads) / Innodb_buffer_pool_read_requests * 100%计算得到 InnoDB Buffer Pool 的命中率。

InnoDB 字典信息缓存(InnoDB Additional Memory Pool):InnoDB字典信息缓存主要用来存放 InnoDB 存储引擎的字典信息以及一些 internal 的共享数据结构信息。所以其大小也与系统中所使用的InnoDB 存储引擎表的数量有较大关系。不过,如果我们通过 innodb_additional_mem_pool_size参数所设置的内存大小不够,InnoDB 会自动申请更多的内存,并在 MySQL 的 Error Log 中记录警告信息。

这里所列举的各种共享内存,是我个人认为对 MySQL 性能有较大影响的集中主要的共享内存。实际上,除了这些共享内存之外,MySQL 还存在很多其他的共享内存信息,如当同时请求连接过多的时候用来存放连接请求信息的back_log队列等。
以上内容可能存在分析不妥之处,欢迎各位朋友拍砖,一起交流。

发表在 新闻头条 | 标签为 | 8G内存下MySQL的优化详细方案已关闭评论

Mysql参数优化

Mysql参数优化对于新手来讲,是比较难懂的东西,其实这个参数优化,是个很复杂的东西,对于不同的网站,及其在线量,访问量,帖子数量,网络情况,以及机器硬件配置都有关系,优化不可能一次性 完成,需要不断的观察以及调试,才有可能得到最佳效果。

  下面先说我的服务器的硬件以及论坛情况,

  CPU: 2颗四核Intel Xeon 2.00GHz

  内存: 4GB DDR

  硬盘: SCSI 146GB

  论坛:在线会员 一般在 5000 人左右 – 最高记录是 13264.

  下面,我们根据以上硬件配置结合一份已经做过一次优化的my.cnf进行分析说明:有些参数可能还得根据论坛的变化情况以及程序员的程序进行再调整。

  [mysqld]

  port = 3306

  serverid = 1

  socket = /tmp/mysql.sock

  skip-locking # 避免MySQL的外部锁定,减少出错几率增强稳定性。 skip-name-resolve

  禁止MySQL对外部连接进行DNS解析,使用这一选项可以消除MySQL进行DNS 解析的时间。但需要注意,如果开启该选项,则所有远程主机连接授权都要使用IP地址方式,否则MySQL将无法正常处理连接请求!

  back_log = 500

  要求 MySQL 能有的连接数量。当主要MySQL线程在一个很短时间内得到非常多的连接请求,这就起作用,然后主线程花些时间(尽管很短)检查连接并且启动一个新线程。

  back_log值指出在MySQL暂时停止回答新请求之前的短时间内多少个请求可以被存在堆栈中。只有如果期望在一个短时间内有很多连接,你需要增 加它,换句话说,这值对到来的TCP/IP连接的侦听队列的大小。你的操作系统在这个队列大小上有它自己的限制。试图设定 back_log高于你的操作系统的限制将是无效的。当你观察你的主机进程列表,发现大量 264084 | unauthenticated user | xxx.xxx.xxx.xxx | NULL | Connect | NULL | login | NULL 的待连接进程时,就要加大 back_log 的值了。默认数值是50,我把它改为500。

  key_buffer_size = 384M

  # key_buffer_size指定用于索引的缓冲区大小,增加它可得到更好处理的索引(对所有读和多重写),到你能负担得起那样多。如果你使它太大,系 统将开始换页并且真的变慢了。对于内存在4GB左右的服务器该参数可设置为384M或512M。通过检查状态 值Key_read_requests和Key_reads,可以知道key_buffer_size设置是否合理。比例key_reads / key_read_requests应该尽可能的低,至少是1:100,1:1000更好(上述状态值可以使用SHOW STATUS LIKE ‘key_read%’获得)。注意:该参数值设置的过大反而会是服务器整体效率降低!

  max_allowed_packet = 32M

  增加该变量的值十分安全,这是因为仅当需要时才会分配额外内存。例如,仅当你发出长查询或mysqld必须返回大的结果行时mysqld才会分配更多 内存。该变量之所以取较小默认值是一种预防措施,以捕获客户端和服务器之间的错误信息包,并确保不会因偶然使用大的信息包而导致内存溢出。

  table_cache = 512

  table_cache指定表高速缓存的大小。每当MySQL访问一个表时,如果在表缓冲区中还有空间,该表就被打开并放入其中,这样可以更快地访问 表内容。通过检查峰值时间的状态值Open_tables和Opened_tables,可以决定是否需要增加table_cache的值。如果你发现 open_tables等于table_cache,并且opened_tables在不断增长,那么你就需要增加table_cache的值了(上述状 态值可以使用SHOW STATUS LIKE ‘Open%tables’获得)。注意,不能盲目地把table_cache设置成很大的值。如果设置得太高,可能会造成文件描述符不足,从而造成性能不稳定或者连接失败。

sort_buffer_size = 4M

  查询排序时所能使用的缓冲区大小。注意:该参数对应的分配内存是每连接独占!如果有100个连接,那么实际分配的总共排序缓冲区大小为100 × 4 = 400MB。所以,对于内存在4GB左右的服务器推荐设置为4-8M。

  read_buffer_size = 4M

  读查询操作所能使用的缓冲区大小。和sort_buffer_size一样,该参数对应的分配内存也是每连接独享!

  join_buffer_size = 8M

  联合查询操作所能使用的缓冲区大小,和sort_buffer_size一样,该参数对应的分配内存也是每连接独享!

  myisam_sort_buffer_size = 64M

  MyISAM表发生变化时重新排序所需的缓冲

  query_cache_size = 64M

  指定MySQL查询缓冲区的大小。可以通过在MySQL控制台执行以下命令观察:

  # > SHOW VARIABLES LIKE ‘%query_cache%’; # > SHOW STATUS LIKE ‘Qcache%’; # 如果Qcache_lowmem_prunes的值非常大,则表明经常出现缓冲不够的情况;

  如果Qcache_hits的值非常大,则表明查询缓冲使用非常频繁,如果该值较小反而会影响效率,那么可以考虑不用查询缓 冲;Qcache_free_blocks,如果该值非常大,则表明缓冲区中碎片很多。

  thread_cache_size = 64

  可以复用的保存在中的线程的数量。如果有,新的线程从缓存中取得,当断开连接的时候如果有空间,客户的线置在缓存中。如果有很多新的线程,为了提高性 能可以这个变量值。通过比较 Connections 和 Threads_created 状态的变量,可以看到这个变量的作用

  tmp_table_size = 256M

  max_connections = 1000

  指定MySQL允许的最大连接进程数。如果在访问论坛时经常出现Too Many Connections的错误提示,则需要增大该参数值。

  max_connect_errors = 10000000

  对于同一主机,如果有超出该参数值个数的中断错误连接,则该主机将被禁止连接。如需对该主机进行解禁,执行:FLUSH HOST;。

  wait_timeout = 10

  指定一个请求的最大连接时间,对于4GB左右内存的服务器可以设置为5-10。

  thread_concurrency = 8

  该参数取值为服务器逻辑CPU数量×2,在本例中,服务器有2颗物理CPU,而每颗物理CPU又支持H.T超线程,所以实际取值为4 × 2 = 8

  skip-networking

  开启该选项可以彻底关闭MySQL的TCP/IP连接方式,如果WEB服务器是以远程连接的方式访问MySQL数据库服务器则不要开启该选项!否则将无法正常连接!

  long_query_time = 10

  log-slow-queries =

  log-queries-not-using-indexes

  开启慢查询日志( slow query log )

  慢查询日志对于跟踪有问题的查询非常有用。它记录所有查过long_query_time的查询,如果需要,还可以记录不使用索引的记录。下面是一个 慢查询日志的例子:

  开启慢查询日志,需要设置参数log_slow_queries、long_query_times、log-queries-not-using- indexes。

  log_slow_queries指定日志文件,如果不提供文件名,MySQL将自己产生缺省文件名。long_query_times指定慢查询的 阈值,缺省是10秒。log-queries-not-using-indexes是4.1.0以后引入的参数,它指示记录不使用索引的查询。设置 long_query_time=10

 另外附上使用show status命令查看mysql状态相关的值及其含义:

  使用show status命令

  含义如下:

  aborted_clients 客户端非法中断连接次数

  aborted_connects 连接mysql失败次数

  com_xxx xxx命令执行次数,有很多条

  connections 连接mysql的数量

  Created_tmp_disk_tables 在磁盘上创建的临时表

  Created_tmp_tables 在内存里创建的临时表

  Created_tmp_files 临时文件数

  Key_read_requests The number of requests to read a key block from the cache

  Key_reads The number of physical reads of a key block from disk

  Max_used_connections 同时使用的连接数

  Open_tables 开放的表

  Open_files 开放的文件

  Opened_tables 打开的表

  Questions 提交到server的查询数

  Sort_merge_passes 如果这个值很大,应该增加my.cnf中的sort_buffer值

  Uptime 服务器已经工作的秒数

  提升性能的建议:

  1.如果opened_tables太大,应该把my.cnf中的table_cache变大

  2.如果Key_reads太大,则应该把my.cnf中key_buffer_size变大.可以用 Key_reads/Key_read_requests计算出cache失败率

  3.如果Handler_read_rnd太大,则你写的SQL语句里很多查询都是要扫描整个表,而没有发挥索引的键的作用

  4.如果Threads_created太大,就要增加my.cnf中thread_cache_size的值.可以用 Threads_created/Connections计算cache命中率

  5.如果Created_tmp_disk_tables太大,就要增加my.cnf中tmp_table_size的值,用基于内存的临时表代替基 于磁盘的

发表在 新闻头条 | 标签为 | Mysql参数优化已关闭评论

mysql常用优化参数

修改全站搜索
修改my.ini(my.cnf) ,在 [mysqld] 后面加入一行“ft_min_word_len=1”,然后 重启Mysql,再登录网站后台(模块管理->全站搜索)重建全文索引。
记录慢查询sql语句,修改my.ini(my.cnf),添加如下代码:
#log-slow-queries
long_query_time = 1 #是指 执行超过多久的 sql 会被 log 下来
log-slow-queries = E:/wamp /logs/slow.log #设置把日志写在那里,可以为空,系统会给一个缺省的文件
#log-slow-queries = /var /youpath/slow.log linux下 host_name-slow.log
log-queries-not-using-indexes
mysql缓存的设置
mysql>show variables like ‘%query_cache%’; mysql 本身是有对sql语句缓存的机制的,合理设置我们的mysql缓存可以降低数据库的io资源。
#query_cache_type= 查 询缓存的方式(默认是 ON)
query_cache_size 如果你希望禁用查询缓存,设置 query_cache_size=0。禁用了查 询缓存,将没有明显的开销
query_cache_limit 不缓存大于这个值的结果。(缺省为 1M)
查询缓存的统计信息
mysql> SHOW STATUS LIKE ‘qcache%’;
Qcache_free_blocks 缓存中相邻内存块的个数。数目大说明可能有碎片。FLUSH QUERY CACHE 会对 缓存中的碎片进行整理,从而得到一个空闲块。
Qcache_free_memory 缓存中的空闲内存。
Qcache_hits 每次查询在缓存中命中时就增大。
Qcache_inserts 每次插入一个查询时就增大。命中次数除以插入次数就是不中比率;用 1 减去这个值就是命中率。在上 面这个例子中,大约有 87% 的查询都在缓存中命中。
Qcache_lowmem_prunes 缓存出现内存不足并且必须要进行清理以便为更多查询提供空间的次数。这个数字最好长时间 来看;如果这个数字在不断增长,就表示可能碎片非常严重,或者内存很少。(上面的 free_blocks 和 free_memory 可以告诉您属于 哪种情况)。
Qcache_not_cached 不适合进行缓存的查询的数量,通常是由于这些查询不是 SELECT 语句。
Qcache_queries_in_cache 当前缓存的查询(和响应)的数量。
Qcache_total_blocks 缓存中块的数量。通常,间隔几秒显示这些变量就可以看出区别,这可以帮助确定缓存是否正在 有效地使用。运行 FLUSH STATUS 可以重置一些计数器,如果服务器已经运行了一段时间,这会非常有帮助。
my.ini(my.conf)配置
key_buffer_size = 256M
# key_buffer_size指定用于索引的缓冲区大小,增加它可得到更好的索引处理性能。 对于内存在4GB左右的 服务器该参数可设置为256M或384M。注意:该参数值设置的过大反而会是服务器整体效率降低
max_allowed_packet = 4M
thread_stack = 256K
table_cache = 128K
sort_buffer_size = 6M
查询排序时所能使用的缓冲区大小。注意:该参数对应的分配内存是每连接独占!如果有100个连接,那么实际分配的总共排序缓冲区大小 为100 × 6 = 600MB。所以,对于内存在4GB左右的服务器推荐设置为6-8M。
read_buffer_size = 4M
读查询操作所能使用的缓冲区大小。和sort_buffer_size一样,该参数对应的分配内存也是每个连接独享!
join_buffer_size = 8M
联合查询操作所能使用的缓冲区大小,和sort_buffer_size一样,该参数对应的分配内存也是每个连接独享!
myisam_sort_buffer_size = 64M
table_cache = 512
thread_cache_size = 64
query_cache_size = 64M
指定MySQL查询缓冲区的大小。可以通过在MySQL控制台执行以下命令观察:
# > SHOW VARIABLES LIKE ‘%query_cache%’;
# > SHOW STATUS LIKE ‘Qcache%’;
# 如果Qcache_lowmem_prunes的值非常大,则表明经常出现缓冲不够的情况;
#如果Qcache_hits的值非常大,则表明查询缓冲使用非常频繁,如果该值较小反而会影响效率,那么可以考虑不用查询缓冲;
Qcache_free_blocks,如 果该值非常大,则表明缓冲区中碎片很多
tmp_table_size = 256M
max_connections = 768
指定MySQL允许的最大连接进程数。如果在访问论坛时经常出现Too Many Connections的错误提示,则需要增大该 参数值。
max_connect_errors = 10000000
wait_timeout = 10
指定一个请求的最大连接时间,对于4GB左右内存的服务器可以设置为5-10。
thread_concurrency = 8
该参数取值为服务器逻辑CPU数量×2,如果服务器有2颗物理CPU,而每颗物理CPU又支持H.T超线程,所以实际取值为 4 × 2 = 8
skip-networking
开启该选项可以彻底关闭MySQL的TCP/IP连接方式,如果WEB服务器是以远程连接的方式访问MySQL数据库服务器则不要开 启该选项!否则将无法正常连接!

发表在 新闻头条 | 标签为 , | mysql常用优化参数已关闭评论

MySQL高速缓存启动方法及参数详解query_cache_size=32M query_cache_type=1

MySQL query cache从4.1版本开始提供了,不过值今天本人才对其进行研究。默认配置下,MySQL的该功能是没有启动的,可能你通过show variables like ‘%query_cache%’;会发现其变量have_query_cache的值是yes,MYSQL初学者很容易以为这个参数为YES就代表开启了 查询缓存,实际上是不对的,该参数表示当前版本的MYSQL是否支持Query Cache,实际上是否开启查询缓存是看另外一个参数的值:query_cache_size ,该值为0,表示禁用query cache,而默认配置正是配置为0。

配置方法:

在MYSQL的配置文件my.ini或my.cnf中找到如下内容:

# Query cache is used to cache SELECT results and later return them

# without actual executing the same query once again. Having the query

# cache enabled may result in significant speed improvements, if your

# have a lot of identical queries and rarely changing tables. See the

# “Qcache_lowmem_prunes” status variable to check if the current value

# is high enough for your load.

# Note: In case your tables change very often or if your queries are

# textually different every time, the query cache may result in a

# slowdown instead of a performance improvement.

query_cache_size=0

以 上信息是默认配置,其注释意思是说,MYSQL的查询缓存用于缓存select查询结果,并在下次接收到同样的查询请求时,不再执行实际查询处理而直接返 回结果,有这样的查询缓存能提高查询的速度,使查询性能得到优化,前提条件是你有大量的相同或相似的查询,而很少改变表里的数据,否则没有必要使用此功 能。可以通过Qcache_lowmem_prunes变量的值来检查是否当前的值满足你目前系统的负载。注意:如果你查询的表更新比较频繁,而且很少有 相同的查询,最好不要使用查询缓存。

具体配置方法:

1. 将query_cache_size设置为具体的大小,具体大小是多少取决于查询的实际情况,但最好设置为1024的倍数,参考值32M。

2. 增加一行:query_cache_type=1

query_cache_type参数用于控制缓存的类型,注意这个值不能随便设置,必须设置为数字,可选项目以及说明如下:
MySQL高速缓存启动方法及参数详解 – 默石游五洲 – 默石游五洲

如果设置为0,那么可以说,你的缓存根本就没有用,相当于禁用了。但是这种情况下query_cache_size设置的大小系统是否要为其分配呢,这个问题有待于测试?

如果设置为1,将会缓存所有的结果,除非你的select语句使用SQL_NO_CACHE禁用了查询缓存。

如果设置为2,则只缓存在select语句中通过SQL_CACHE指定需要缓存的查询。

OK,配置完后的部分文件如下:

query_cache_size=128M

query_cache_type=1

保存文件,重新启动MYSQL服务,然后通过如下查询来验证是否真正开启了:

mysql> show variables like ‘%query_cache%’;

+——————————+———–+

| Variable_name | Value |

+——————————+———–+

| have_query_cache | YES |

| query_cache_limit | 1048576 |

| query_cache_min_res_unit | 4096 |

| query_cache_size | 134217728 |

| query_cache_type | ON |

| query_cache_wlock_invalidate | OFF |

+——————————+———–+

6 rows in set (0.00 sec)

主要看query_cache_size和query_cache_type的值是否跟我们设的一致:

这里query_cache_size的值是134217728,我们设置的是128M,实际是一样的,只是单位不同,可以自己换算下:134217728 = 128*1024*1024。

query_cache_type设置为1,显示为ON,这个前面已经说过了。

总之,看到上边的显示表示设置正确,但是在实际的查询中是否能够缓存查询,还需要手动测试下,我们可以通过show status like ‘%Qcache%’;语句来测试,现在我们开启了查询缓存功能,在执行查询前,我们先看看相关参数的值:

mysql> show status like ‘%Qcache%’;

+————————-+———–+

| Variable_name | Value |

+————————-+———–+

| Qcache_free_blocks | 1 |

| Qcache_free_memory | 134208800 |

| Qcache_hits | 0 |

| Qcache_inserts | 0 |

| Qcache_lowmem_prunes | 0 |

| Qcache_not_cached | 2 |

| Qcache_queries_in_cache | 0 |

| Qcache_total_blocks | 1 |

+————————-+———–+

8 rows in set (0.00 sec)

这里顺便解释下这个几个参数的作用:

Qcache_free_blocks:表示查询缓存中目前还有多少剩余的blocks,如果该值显示较大,则说明查询缓存中的内存碎片过多了,可能在一定的时间进行整理。

Qcache_free_memory:查询缓存的内存大小,通过这个参数可以很清晰的知道当前系统的查询内存是否够用,是多了,还是不够用,DBA可以根据实际情况做出调整。

Qcache_hits:表示有多少次命中缓存。我们主要可以通过该值来验证我们的查询缓存的效果。数字越大,缓存效果越理想。

Qcache_inserts: 表示多少次未命中然后插入,意思是新来的SQL请求在缓存中未找到,不得不执行查询处理,执行查询处理后把结果insert到查询缓存中。这样的情况的次 数,次数越多,表示查询缓存应用到的比较少,效果也就不理想。当然系统刚启动后,查询缓存是空的,这很正常。

Qcache_lowmem_prunes:该参数记录有多少条查询因为内存不足而被移除出查询缓存。通过这个值,用户可以适当的调整缓存大小。

Qcache_not_cached: 表示因为query_cache_type的设置而没有被缓存的查询数量。

Qcache_queries_in_cache:当前缓存中缓存的查询数量。

Qcache_total_blocks:当前缓存的block数量。

下边我们测试下:

比如执行如下查询语句

mysql> select * from user where id = 2;

+—-+——-+

| id | name |

+—-+——-+

| 2 | test2 |

+—-+——-+

1 row in set (0.02 sec)

然后执行show status like ‘%Qcache%’,看看有什么变化:

mysql> show status like ‘%Qcache%’;

+————————-+———–+

| Variable_name | Value |

+————————-+———–+

| Qcache_free_blocks | 1 |

| Qcache_free_memory | 134207264 |

| Qcache_hits | 0 |

| Qcache_inserts | 1 |

| Qcache_lowmem_prunes | 0 |

| Qcache_not_cached | 3 |

| Qcache_queries_in_cache | 1 |

| Qcache_total_blocks | 4 |

+————————-+———–+

8 rows in set (0.00 sec)

对比前面的参数值,我们发现Qcache_inserts变化了。Qcache_hits没有变,下边我们在执行同样的查询
select * from user where id = 2,按照前面的理论分析:Qcache_hits应该等于1,而Qcache_inserts应该值不变(其他参数的值变化暂时不关注,读者可以自行测试),再次执行:

show status like ‘%Qcache%’,看看有什么变化:

mysql> show status like ‘%Qcache%’;

+————————-+———–+

| Variable_name | Value |

+————————-+———–+

| Qcache_free_blocks | 1 |

| Qcache_free_memory | 134207264 |

| Qcache_hits | 1 |

| Qcache_inserts | 1 |

| Qcache_lowmem_prunes | 0 |

| Qcache_not_cached | 4 |

| Qcache_queries_in_cache | 1 |

| Qcache_total_blocks | 4 |

+————————-+———–+

8 rows in set (0.00 sec)

OK,果然跟我们分析的完全一致。

发表在 新闻头条 | 标签为 , , | MySQL高速缓存启动方法及参数详解query_cache_size=32M query_cache_type=1已关闭评论

MySQL 性能优化的最佳20多条经验分享

今天,数据库的操作越来越成为整个应用的性能瓶颈了,这点对于Web应用尤其明显。关于数据库的性能,这并不只是DBA才需要担心的事,而这更是我们程序员需要去关注的事情。
当我们去设计数据库表结构,对操作数据库时(尤其是查表时的SQL语句),我们都需要注意数据操作的性能。这里,我们不会讲过多的SQL语句的优化,而只是针对MySQL这一Web应用最多的数据库。希望下面的这些优化技巧对你有用。
1. 为查询缓存优化你的查询

大多数的MySQL服务器都开启了查询缓存。这是提高性最有效的方法之一,而且这是被MySQL的数据库引擎处理的。当有很多相同的查询被执行了多次的时候,这些查询结果会被放到一个缓存中,这样,后续的相同的查询就不用操作表而直接访问缓存结果了。

这里最主要的问题是,对于程序员来说,这个事情是很容易被忽略的。因为,我们某些查询语句会让MySQL不使用缓存。请看下面的示例:
复制代码 代码如下:

// 查询缓存不开启
$r = mysql_query(“SELECT username FROM user WHERE signup_date >= CURDATE()”);

// 开启查询缓存
$today = date(“Y-m-d”);
$r = mysql_query(“SELECT username FROM user WHERE signup_date >= ‘$today'”);

上面两条SQL语句的差别就是 CURDATE() ,MySQL的查询缓存对这个函数不起作用。所以,像 NOW() 和 RAND() 或是其它的诸如此类的SQL函数都不会开启查询缓存,因为这些函数的返回是会不定的易变的。所以,你所需要的就是用一个变量来代替MySQL的函数,从而开启缓存。

2. EXPLAIN 你的 SELECT 查询

使用 EXPLAIN 关键字可以让你知道MySQL是如何处理你的SQL语句的。这可以帮你分析你的查询语句或是表结构的性能瓶颈。

EXPLAIN 的查询结果还会告诉你你的索引主键被如何利用的,你的数据表是如何被搜索和排序的……等等,等等。

挑一个你的SELECT语句(推荐挑选那个最复杂的,有多表联接的),把关键字EXPLAIN加到前面。你可以使用phpmyadmin来做这个事。然后,你会看到一张表格。下面的这个示例中,我们忘记加上了group_id索引,并且有表联接:

当我们为 group_id 字段加上索引后:

我们可以看到,前一个结果显示搜索了 7883 行,而后一个只是搜索了两个表的 9 和 16 行。查看rows列可以让我们找到潜在的性能问题。

3. 当只要一行数据时使用 LIMIT 1

当你查询表的有些时候,你已经知道结果只会有一条结果,但因为你可能需要去fetch游标,或是你也许会去检查返回的记录数。

在这种情况下,加上 LIMIT 1 可以增加性能。这样一样,MySQL数据库引擎会在找到一条数据后停止搜索,而不是继续往后查少下一条符合记录的数据。

下面的示例,只是为了找一下是否有“中国”的用户,很明显,后面的会比前面的更有效率。(请注意,第一条中是Select *,第二条是Select 1)
复制代码 代码如下:

// 没有效率的:
$r = mysql_query(“SELECT * FROM user WHERE country = ‘China'”);
if (mysql_num_rows($r) > 0) {
// …
}

// 有效率的:
$r = mysql_query(“SELECT 1 FROM user WHERE country = ‘China’ LIMIT 1”);
if (mysql_num_rows($r) > 0) {
// …
}

4. 为搜索字段建索引

索引并不一定就是给主键或是唯一的字段。如果在你的表中,有某个字段你总要会经常用来做搜索,那么,请为其建立索引吧。

从上图你可以看到那个搜索字串 “last_name LIKE ‘a%’”,一个是建了索引,一个是没有索引,性能差了4倍左右。

另外,你应该也需要知道什么样的搜索是不能使用正常的索引的。例如,当你需要在一篇大的文章中搜索一个词时,如: “WHERE post_content LIKE ‘%apple%’”,索引可能是没有意义的。你可能需要使用MySQL全文索引 或是自己做一个索引(比如说:搜索关键词或是Tag什么的)

5. 在Join表的时候使用相当类型的例,并将其索引

如果你的应用程序有很多 JOIN 查询,你应该确认两个表中Join的字段是被建过索引的。这样,MySQL内部会启动为你优化Join的SQL语句的机制。

而且,这些被用来Join的字段,应该是相同的类型的。例如:如果你要把 DECIMAL 字段和一个 INT 字段Join在一起,MySQL就无法使用它们的索引。对于那些STRING类型,还需要有相同的字符集才行。(两个表的字符集有可能不一样)
复制代码 代码如下:

// 在state中查找company
$r = mysql_query(“SELECT company_name FROM users
LEFT JOIN companies ON (users.state = companies.state)
WHERE users.id = $user_id”);

// 两个 state 字段应该是被建过索引的,而且应该是相当的类型,相同的字符集。

6. 千万不要 ORDER BY RAND()

想打乱返回的数据行?随机挑一个数据?真不知道谁发明了这种用法,但很多新手很喜欢这样用。但你确不了解这样做有多么可怕的性能问题。

如果你真的想把返回的数据行打乱了,你有N种方法可以达到这个目的。这样使用只让你的数据库的性能呈指数级的下降。这里的问题是:MySQL会不得不去执行RAND()函数(很耗CPU时间),而且这是为了每一行记录去记行,然后再对其排序。就算是你用了Limit 1也无济于事(因为要排序)

下面的示例是随机挑一条记录
复制代码 代码如下:

// 千万不要这样做:
$r = mysql_query(“SELECT username FROM user ORDER BY RAND() LIMIT 1”);

// 这要会更好:
$r = mysql_query(“SELECT count(*) FROM user”);
$d = mysql_fetch_row($r);
$rand = mt_rand(0,$d[0] – 1);

$r = mysql_query(“SELECT username FROM user LIMIT $rand, 1”);

7. 避免 SELECT *

从数据库里读出越多的数据,那么查询就会变得越慢。并且,如果你的数据库服务器和WEB服务器是两台独立的服务器的话,这还会增加网络传输的负载。

所以,你应该养成一个需要什么就取什么的好的习惯。
复制代码 代码如下:

// 不推荐
$r = mysql_query(“SELECT * FROM user WHERE user_id = 1”);
$d = mysql_fetch_assoc($r);
echo “Welcome {$d[‘username’]}”;

// 推荐
$r = mysql_query(“SELECT username FROM user WHERE user_id = 1”);
$d = mysql_fetch_assoc($r);
echo “Welcome {$d[‘username’]}”;

8. 永远为每张表设置一个ID

我们应该为数据库里的每张表都设置一个ID做为其主键,而且最好的是一个INT型的(推荐使用UNSIGNED),并设置上自动增加的 AUTO_INCREMENT标志。

就算是你 users 表有一个主键叫 “email”的字段,你也别让它成为主键。使用 VARCHAR 类型来当主键会使用得性能下降。另外,在你的程序中,你应该使用表的ID来构造你的数据结构。

而且,在MySQL数据引擎下,还有一些操作需要使用主键,在这些情况下,主键的性能和设置变得非常重要,比如,集群,分区……

在这里,只有一个情况是例外,那就是“关联表”的“外键”,也就是说,这个表的主键,通过若干个别的表的主键构成。我们把这个情况叫做“外键”。比如:有一个“学生表”有学生的ID,有一个“课程表”有课程ID,那么,“成绩表”就是“关联表”了,其关联了学生表和课程表,在成绩表中,学生ID和课程ID叫“外键”其共同组成主键。
9. 使用 ENUM 而不是 VARCHAR

ENUM 类型是非常快和紧凑的。在实际上,其保存的是 TINYINT,但其外表上显示为字符串。这样一来,用这个字段来做一些选项列表变得相当的完美。

如果你有一个字段,比如“性别”,“国家”,“民族”,“状态”或“部门”,你知道这些字段的取值是有限而且固定的,那么,你应该使用 ENUM 而不是 VARCHAR。

MySQL也有一个“建议”(见第十条)告诉你怎么去重新组织你的表结构。当你有一个 VARCHAR 字段时,这个建议会告诉你把其改成 ENUM 类型。使用 PROCEDURE ANALYSE() 你可以得到相关的建议。
10. 从 PROCEDURE ANALYSE() 取得建议

PROCEDURE ANALYSE() 会让 MySQL 帮你去分析你的字段和其实际的数据,并会给你一些有用的建议。只有表中有实际的数据,这些建议才会变得有用,因为要做一些大的决定是需要有数据作为基础的。

例如,如果你创建了一个 INT 字段作为你的主键,然而并没有太多的数据,那么,PROCEDURE ANALYSE()会建议你把这个字段的类型改成 MEDIUMINT 。或是你使用了一个 VARCHAR 字段,因为数据不多,你可能会得到一个让你把它改成 ENUM 的建议。这些建议,都是可能因为数据不够多,所以决策做得就不够准。

在phpmyadmin里,你可以在查看表时,点击 “Propose table structure” 来查看这些建议

一定要注意,这些只是建议,只有当你的表里的数据越来越多时,这些建议才会变得准确。一定要记住,你才是最终做决定的人。
11. 尽可能的使用 NOT NULL

除非你有一个很特别的原因去使用 NULL 值,你应该总是让你的字段保持 NOT NULL。这看起来好像有点争议,请往下看。

首先,问问你自己“Empty”和“NULL”有多大的区别(如果是INT,那就是0和NULL)?如果你觉得它们之间没有什么区别,那么你就不要使用NULL。(你知道吗?在 Oracle 里,NULL 和 Empty 的字符串是一样的!)

不要以为 NULL 不需要空间,其需要额外的空间,并且,在你进行比较的时候,你的程序会更复杂。 当然,这里并不是说你就不能使用NULL了,现实情况是很复杂的,依然会有些情况下,你需要使用NULL值。

下面摘自MySQL自己的文档:

“NULL columns require additional space in the row to record whether their values are NULL. For MyISAM tables, each NULL column takes one bit extra, rounded up to the nearest byte.”

12. Prepared Statements

Prepared Statements很像存储过程,是一种运行在后台的SQL语句集合,我们可以从使用 prepared statements 获得很多好处,无论是性能问题还是安全问题。

Prepared Statements 可以检查一些你绑定好的变量,这样可以保护你的程序不会受到“SQL注入式”攻击。当然,你也可以手动地检查你的这些变量,然而,手动的检查容易出问题,而且很经常会被程序员忘了。当我们使用一些framework或是ORM的时候,这样的问题会好一些。

在性能方面,当一个相同的查询被使用多次的时候,这会为你带来可观的性能优势。你可以给这些Prepared Statements定义一些参数,而MySQL只会解析一次。

虽然最新版本的MySQL在传输Prepared Statements是使用二进制形势,所以这会使得网络传输非常有效率。

当然,也有一些情况下,我们需要避免使用Prepared Statements,因为其不支持查询缓存。但据说版本5.1后支持了。

在PHP中要使用prepared statements,你可以查看其使用手册:mysqli 扩展 或是使用数据库抽象层,如: PDO.
复制代码 代码如下:

// 创建 prepared statement
if ($stmt = $mysqli->prepare(“SELECT username FROM user WHERE state=?”)) {

// 绑定参数
$stmt->bind_param(“s”, $state);

// 执行
$stmt->execute();

// 绑定结果
$stmt->bind_result($username);

// 移动游标
$stmt->fetch();

printf(“%s is from %s\n”, $username, $state);

$stmt->close();
}

13. 无缓冲的查询

正常的情况下,当你在当你在你的脚本中执行一个SQL语句的时候,你的程序会停在那里直到没这个SQL语句返回,然后你的程序再往下继续执行。你可以使用无缓冲查询来改变这个行为。

关于这个事情,在PHP的文档中有一个非常不错的说明: mysql_unbuffered_query() 函数:

“mysql_unbuffered_query() sends the SQL query query to MySQL without automatically fetching and buffering the result rows as mysql_query() does. This saves a considerable amount of memory with SQL queries that produce large result sets, and you can start working on the result set immediately after the first row has been retrieved as you don’t have to wait until the complete SQL query has been performed.”

上面那句话翻译过来是说,mysql_unbuffered_query() 发送一个SQL语句到MySQL而并不像mysql_query()一样去自动fethch和缓存结果。这会相当节约很多可观的内存,尤其是那些会产生大量结果的查询语句,并且,你不需要等到所有的结果都返回,只需要第一行数据返回的时候,你就可以开始马上开始工作于查询结果了。

然而,这会有一些限制。因为你要么把所有行都读走,或是你要在进行下一次的查询前调用 mysql_free_result() 清除结果。而且, mysql_num_rows() 或 mysql_data_seek() 将无法使用。所以,是否使用无缓冲的查询你需要仔细考虑。
14. 把IP地址存成 UNSIGNED INT

很多程序员都会创建一个 VARCHAR(15) 字段来存放字符串形式的IP而不是整形的IP。如果你用整形来存放,只需要4个字节,并且你可以有定长的字段。而且,这会为你带来查询上的优势,尤其是当你需要使用这样的WHERE条件:IP between ip1 and ip2。

我们必需要使用UNSIGNED INT,因为 IP地址会使用整个32位的无符号整形。

而你的查询,你可以使用 INET_ATON() 来把一个字符串IP转成一个整形,并使用 INET_NTOA() 把一个整形转成一个字符串IP。在PHP中,也有这样的函数 ip2long() 和 long2ip()。
1 $r = “UPDATE users SET ip = INET_ATON(‘{$_SERVER[‘REMOTE_ADDR’]}’) WHERE user_id = $user_id”;
15. 固定长度的表会更快

如果表中的所有字段都是“固定长度”的,整个表会被认为是 “static” 或 “fixed-length”。 例如,表中没有如下类型的字段: VARCHAR,TEXT,BLOB。只要你包括了其中一个这些字段,那么这个表就不是“固定长度静态表”了,这样,MySQL 引擎会用另一种方法来处理。

固定长度的表会提高性能,因为MySQL搜寻得会更快一些,因为这些固定的长度是很容易计算下一个数据的偏移量的,所以读取的自然也会很快。而如果字段不是定长的,那么,每一次要找下一条的话,需要程序找到主键。

并且,固定长度的表也更容易被缓存和重建。不过,唯一的副作用是,固定长度的字段会浪费一些空间,因为定长的字段无论你用不用,他都是要分配那么多的空间。

使用“垂直分割”技术(见下一条),你可以分割你的表成为两个一个是定长的,一个则是不定长的。
16. 垂直分割

“垂直分割”是一种把数据库中的表按列变成几张表的方法,这样可以降低表的复杂度和字段的数目,从而达到优化的目的。(以前,在银行做过项目,见过一张表有100多个字段,很恐怖)

示例一:在Users表中有一个字段是家庭地址,这个字段是可选字段,相比起,而且你在数据库操作的时候除了个人信息外,你并不需要经常读取或是改写这个字段。那么,为什么不把他放到另外一张表中呢? 这样会让你的表有更好的性能,大家想想是不是,大量的时候,我对于用户表来说,只有用户ID,用户名,口令,用户角色等会被经常使用。小一点的表总是会有好的性能。

示例二: 你有一个叫 “last_login” 的字段,它会在每次用户登录时被更新。但是,每次更新时会导致该表的查询缓存被清空。所以,你可以把这个字段放到另一个表中,这样就不会影响你对用户 ID,用户名,用户角色的不停地读取了,因为查询缓存会帮你增加很多性能。

另外,你需要注意的是,这些被分出去的字段所形成的表,你不会经常性地去Join他们,不然的话,这样的性能会比不分割时还要差,而且,会是极数级的下降。
17. 拆分大的 DELETE 或 INSERT 语句

如果你需要在一个在线的网站上去执行一个大的 DELETE 或 INSERT 查询,你需要非常小心,要避免你的操作让你的整个网站停止相应。因为这两个操作是会锁表的,表一锁住了,别的操作都进不来了。

Apache 会有很多的子进程或线程。所以,其工作起来相当有效率,而我们的服务器也不希望有太多的子进程,线程和数据库链接,这是极大的占服务器资源的事情,尤其是内存。

如果你把你的表锁上一段时间,比如30秒钟,那么对于一个有很高访问量的站点来说,这30秒所积累的访问进程/线程,数据库链接,打开的文件数,可能不仅仅会让你泊WEB服务Crash,还可能会让你的整台服务器马上掛了。

所以,如果你有一个大的处理,你定你一定把其拆分,使用 LIMIT 条件是一个好的方法。下面是一个示例:
复制代码 代码如下:

while (1) {
//每次只做1000条
mysql_query(“DELETE FROM logs WHERE log_date <= '2009-11-01' LIMIT 1000"); if (mysql_affected_rows() == 0) { // 没得可删了,退出! break; } // 每次都要休息一会儿 usleep(50000); } 18. 越小的列会越快 对于大多数的数据库引擎来说,硬盘操作可能是最重大的瓶颈。所以,把你的数据变得紧凑会对这种情况非常有帮助,因为这减少了对硬盘的访问。 参看 MySQL 的文档 Storage Requirements 查看所有的数据类型。 如果一个表只会有几列罢了(比如说字典表,配置表),那么,我们就没有理由使用 INT 来做主键,使用 MEDIUMINT, SMALLINT 或是更小的 TINYINT 会更经济一些。如果你不需要记录时间,使用 DATE 要比 DATETIME 好得多。 当然,你也需要留够足够的扩展空间,不然,你日后来干这个事,你会死的很难看,参看Slashdot的例子(2009年11月06 日),一个简单的ALTER TABLE语句花了3个多小时,因为里面有一千六百万条数据。 19. 选择正确的存储引擎 在 MySQL 中有两个存储引擎 MyISAM 和 InnoDB,每个引擎都有利有弊。酷壳以前文章《MySQL: InnoDB 还是 MyISAM?》讨论和这个事情。 MyISAM 适合于一些需要大量查询的应用,但其对于有大量写操作并不是很好。甚至你只是需要update一个字段,整个表都会被锁起来,而别的进程,就算是读进程都无法操作直到读操作完成。另外,MyISAM 对于 SELECT COUNT(*) 这类的计算是超快无比的。 InnoDB 的趋势会是一个非常复杂的存储引擎,对于一些小的应用,它会比 MyISAM 还慢。他是它支持“行锁” ,于是在写操作比较多的时候,会更优秀。并且,他还支持更多的高级应用,比如:事务。 下面是MySQL的手册 * target=”_blank”MyISAM Storage Engine * InnoDB Storage Engine 20. 使用一个对象关系映射器(Object Relational Mapper) 使用 ORM (Object Relational Mapper),你能够获得可靠的性能增涨。一个ORM可以做的所有事情,也能被手动的编写出来。但是,这需要一个高级专家。 ORM 的最重要的是“Lazy Loading”,也就是说,只有在需要的去取值的时候才会去真正的去做。但你也需要小心这种机制的副作用,因为这很有可能会因为要去创建很多很多小的查询反而会降低性能。 ORM 还可以把你的SQL语句打包成一个事务,这会比单独执行他们快得多得多。 目前,个人最喜欢的PHP的ORM是:Doctrine。 21. 小心“永久链接” “永久链接”的目的是用来减少重新创建MySQL链接的次数。当一个链接被创建了,它会永远处在连接的状态,就算是数据库操作已经结束了。而且,自从我们的Apache开始重用它的子进程后——也就是说,下一次的HTTP请求会重用Apache的子进程,并重用相同的 MySQL 链接。 * PHP手册:mysql_pconnect() 在理论上来说,这听起来非常的不错。但是从个人经验(也是大多数人的)上来说,这个功能制造出来的麻烦事更多。因为,你只有有限的链接数,内存问题,文件句柄数,等等。 而且,Apache 运行在极端并行的环境中,会创建很多很多的了进程。这就是为什么这种“永久链接”的机制工作地不好的原因。在你决定要使用“永久链接”之前,你需要好好地考虑一下你的整个系统的架构。

发表在 新闻头条 | 标签为 , | MySQL 性能优化的最佳20多条经验分享已关闭评论

top命令的Load average 含义及性能参考基值

$ uptime
11:12:26 up 3:44, 4 users, load average: 0.38, 0.31, 0.19

系统平均负载被定义为在特定时间间隔内运行队列中的平均进程树。如果一个进程满足以下条件则其就会位于运行队列中:

它没有在等待I/O操作的结果
它没有主动进入等待状态(也就是没有调用’wait’)
没有被停止(例如:等待终止)

上面的输出,load average后面分别是1分钟、5分钟、15分钟的负载情况。数据是每隔5秒钟检查一次活跃的进程数,然后根据这个数值算出来的。如果这个数除以CPU 的数目,结果高于5的时候就表明系统在超负荷运转了。

Linux系统Load average负载详细解释  我们知道判断一个系统的负载可以使用top,uptime等命令去查看,它分别记录了一分钟、五分钟、以及十五分钟的系统平均负载
  例如我的某台服务器:
  $ uptime
  09:50:21 up 200 days, 15:07, 1 user, load average: 0.27, 0.33, 0.37
  大部分的人都认为这个数字越小越好,其实有很多关联的提示信息,今天看到这个好文,应该可以给大家说清楚很多问题,转一下:
  原文链接: http://blog.scoutapp.com/articles/2009/07/31/understanding-load-averages
  你可能对于 Linux 的负载均值(load averages)已有了充分的了解。负载均值在 uptime 或者 top 命令中可以看到,它们可能会显示成这个样子:
  load average: 0.09, 0.05, 0.01
  很多人会这样理解负载均值:三个数分别代表不同时间段的系统平均负载(一分钟、五 分钟、以及十五分钟),它们的数字当然是越小越好。数字越高,说明服务器的负载越 大,这也可能是服务器出现某种问题的信号。
  而事实不完全如此,是什么因素构成了负载均值的大小,以及如何区分它们目前的状况是 “好”还是“糟糕”?什么时候应该注意哪些不正常的数值?
  回答这些问题之前,首先需要了解下这些数值背后的些知识。我们先用最简单的例子说明, 一台只配备一块单核处理器的服务器。
  行车过桥
  一只单核的处理器可以形象得比喻成一条单车道。设想下,你现在需要收取这条道路的过桥 费 — 忙于处理那些将要过桥的车辆。你首先当然需要了解些信息,例如车辆的载重、以及 还有多少车辆正在等待过桥。如果前面没有车辆在等待,那么你可以告诉后面的司机通过。 如果车辆众多,那么需要告知他们可能需要稍等一会。
  因此,需要些特定的代号表示目前的车流情况,例如:
  0.00 表示目前桥面上没有任何的车流。 实际上这种情况与 0.00 和 1.00 之间是相同的,总而言之很通畅,过往的车辆可以丝毫不用等待的通过。
  1.00 表示刚好是在这座桥的承受范围内。 这种情况不算糟糕,只是车流会有些堵,不过这种情况可能会造成交通越来越慢。
  超过 1.00,那么说明这座桥已经超出负荷,交通严重的拥堵。 那么情况有多糟糕? 例如 2.00 的情况说明车流已经超出了桥所能承受的一倍,那么将有多余过桥一倍的车辆正在焦急的等待。3.00 的话情况就更不妙了,说明这座桥基本上已经快承受不了,还有超出桥负载两倍多的车辆正在等待。
  上面的情况和处理器的负载情况非常相似。一辆汽车的过桥时间就好比是处理器处理某线程 的实际时间。Unix 系统定义的进程运行时长为所有处理器内核的处理时间加上线程 在队列中等待的时间。
  和收过桥费的管理员一样,你当然希望你的汽车(操作)不会被焦急的等待。所以,理想状态 下,都希望负载平均值小于 1.00 。当然不排除部分峰值会超过 1.00,但长此以往保持这 个状态,就说明会有问题,这时候你应该会很焦急。
  “所以你说的理想负荷为 1.00 ?”
  嗯,这种情况其实并不完全正确。负荷 1.00 说明系统已经没有剩余的资源了。在实际情况中 ,有经验的系统管理员都会将这条线划在 0.70:
  “需要进行调查法则”: 如果长期你的系统负载在 0.70 上下,那么你需要在事情变得更糟糕之前,花些时间了解其原因。
  “现在就要修复法则”:1.00 。 如果你的服务器系统负载长期徘徊于 1.00,那么就应该马上解决这个问题。否则,你将半夜接到你上司的电话,这可不是件令人愉快的事情。
  “凌晨三点半锻炼身体法则”:5.00。 如果你的服务器负载超过了 5.00 这个数字,那么你将失去你的睡眠,还得在会议中说明这情况发生的原因,总之千万不要让它发生。

发表在 新闻头条 | 标签为 , , , | top命令的Load average 含义及性能参考基值已关闭评论

理解和配置 Linux 下的 Out of memory

最近有位 VPS 客户抱怨 MySQL 无缘无故挂掉,还有位客户抱怨 VPS 经常死机,登陆到终端看了一下,都是常见的 Out of memory 问题。这通常是因为某时刻应用程序大量请求内存导致系统内存不足造成的,这通常会触发 Linux 内核里的 Out of Memory (OOM) killer,OOM killer 会杀掉某个进程以腾出内存留给系统用,不致于让系统立刻崩溃。如果检查相关的日志文件(/var/log/messages)就会看到下面类似的 Out of memory: Kill process 信息:


Out of memory: Kill process 9682 (mysqld) score 9 or sacrifice child
Killed process 9682, UID 27, (mysqld) total-vm:47388kB, anon-rss:3744kB, file-rss:80kB
httpd invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
httpd cpuset=/ mems_allowed=0
Pid: 8911, comm: httpd Not tainted 2.6.32-279.1.1.el6.i686 #1

21556 total pagecache pages
21049 pages in swap cache
Swap cache stats: add 12819103, delete 12798054, find 3188096/4634617
Free swap = 0kB
Total swap = 524280kB
131071 pages RAM
0 pages HighMem
3673 pages reserved
67960 pages shared
124940 pages non-shared

Linux 内核根据应用程序的要求分配内存,通常来说应用程序分配了内存但是并没有实际全部使用,为了提高性能,这部分没用的内存可以留作它用,这部分内存是属于每个进程的,内核直接回收利用的话比较麻烦,所以内核采用一种过度分配内存(over-commit memory)的办法来间接利用这部分 “空闲” 的内存,提高整体内存的使用效率。一般来说这样做没有问题,但当大多数应用程序都消耗完自己的内存的时候麻烦就来了,因为这些应用程序的内存需求加起来超出了物理内存(包括 swap)的容量,内核(OOM killer)必须杀掉一些进程才能腾出空间保障系统正常运行。用银行的例子来讲可能更容易懂一些,部分人取钱的时候银行不怕,银行有足够的存款应付,当全国人民(或者绝大多数)都取钱而且每个人都想把自己钱取完的时候银行的麻烦就来了,银行实际上是没有这么多钱给大家取的。

内核检测到系统内存不足、挑选并杀掉某个进程的过程可以参考内核源代码 linux/mm/oom_kill.c,当系统内存不足的时候,out_of_memory() 被触发,然后调用 select_bad_process() 选择一个 “bad” 进程杀掉,如何判断和选择一个 “bad” 进程呢,总不能随机选吧?挑选的过程由 oom_badness() 决定,挑选的算法和想法都很简单很朴实:最 bad 的那个进程就是那个最占用内存的进程。

/**
* oom_badness – heuristic function to determine which candidate task to kill
* @p: task struct of which task we should calculate
* @totalpages: total present RAM allowed for page allocation
*
* The heuristic for determining which task to kill is made to be as simple and
* predictable as possible. The goal is to return the highest value for the
* task consuming the most memory to avoid subsequent oom failures.
*/
unsigned long oom_badness(struct task_struct *p, struct mem_cgroup *memcg,
const nodemask_t *nodemask, unsigned long totalpages)
{
long points;
long adj;

if (oom_unkillable_task(p, memcg, nodemask))
return 0;

p = find_lock_task_mm(p);
if (!p)
return 0;

adj = (long)p->signal->oom_score_adj;
if (adj == OOM_SCORE_ADJ_MIN) {
task_unlock(p);
return 0;
}

/*
* The baseline for the badness score is the proportion of RAM that each
* task’s rss, pagetable and swap space use.
*/
points = get_mm_rss(p->mm) + p->mm->nr_ptes +
get_mm_counter(p->mm, MM_SWAPENTS);
task_unlock(p);

/*
* Root processes get 3% bonus, just like the __vm_enough_memory()
* implementation used by LSMs.
*/
if (has_capability_noaudit(p, CAP_SYS_ADMIN))
adj -= 30;

/* Normalize to oom_score_adj units */
adj *= totalpages / 1000;
points += adj;

/*
* Never return 0 for an eligible task regardless of the root bonus and
* oom_score_adj (oom_score_adj can’t be OOM_SCORE_ADJ_MIN here).
*/
return points > 0 ? points : 1;
}

理解了这个算法我们就理解了为啥 MySQL 躺着也能中枪了,因为它的体积总是最大(一般来说它在系统上占用内存最多),所以如果 Out of Memeory (OOM) 的话总是不幸第一个被 kill 掉。解决这个问题最简单的办法就是增加内存,或者想办法优化 MySQL 使其占用更少的内存,除了优化 MySQL 外还可以优化系统(优化 Debian 5,优化 CentOS 5.x),让系统尽可能使用少的内存以便应用程序(如 MySQL) 能使用更多的内存,还有一个临时的办法就是调整内核参数,让 MySQL 进程不容易被 OOM killer 发现。
配置 OOM killer

我们可以通过一些内核参数来调整 OOM killer 的行为,避免系统在那里不停的杀进程。比如我们可以在触发 OOM 后立刻触发 kernel panic,kernel panic 10秒后自动重启系统。

# sysctl -w vm.panic_on_oom=1
vm.panic_on_oom = 1

# sysctl -w kernel.panic=10
kernel.panic = 10

# echo “vm.panic_on_oom=1” >> /etc/sysctl.conf
# echo “kernel.panic=10” >> /etc/sysctl.conf

从上面的 oom_kill.c 代码里可以看到 oom_badness() 给每个进程打分,根据 points 的高低来决定杀哪个进程,这个 points 可以根据 adj 调节,root 权限的进程通常被认为很重要,不应该被轻易杀掉,所以打分的时候可以得到 3% 的优惠(adj -= 30; 分数越低越不容易被杀掉)。我们可以在用户空间通过操作每个进程的 oom_adj 内核参数来决定哪些进程不这么容易被 OOM killer 选中杀掉。比如,如果不想 MySQL 进程被轻易杀掉的话可以找到 MySQL 运行的进程号后,调整 oom_score_adj 为 -15(注意 points 越小越不容易被杀):

# ps aux | grep mysqld
mysql 2196 1.6 2.1 623800 44876 ? Ssl 09:42 0:00 /usr/sbin/mysqld

# cat /proc/2196/oom_score_adj
0
# echo -15 > /proc/2196/oom_score_adj

当然,如果需要的话可以完全关闭 OOM killer(不推荐用在生产环境):

# sysctl -w vm.overcommit_memory=2

# echo “vm.overcommit_memory=2” >> /etc/sysctl.conf

发表在 新闻头条 | 标签为 , , , | 理解和配置 Linux 下的 Out of memory已关闭评论

linux命令ps -ef | grep httpd 是啥意思

PS是LINUX下最常用的也是非常强大的进程查看命令
//以下这条命令是检查java 进程是否存在.
ps -ef |grep java
下面对命令选项进行说明:
-e 显示所有进程.
-f 全格式.
ps e 列出程序时,显示每个程序所使用的环境变量.
ps f 用ASCII字符显示树状结构,表达程序间的相互关系
grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expression Print,表示全局正则表达式版本,它的使用权限是所有用户.
ps -ef | grep httpd :
检查httpd进程是否存在

发表在 新闻头条 | 标签为 , , , | linux命令ps -ef | grep httpd 是啥意思已关闭评论

Linux之ftp命令使用

一:前言

在达内参加暑期社会实践,达内公司免费教授了一星期的课,当时觉得老师用ftp命令用的很爽。所以回来学学了。

二:分类

有关FTP(客户端,服务器搭建这里不讲)有很多,大体分为命令行和GUI图形界面的软件。

1,图形界面的有

gftp

gnome下ftp客户端

crossftp

基于Java的稳定ftp客户端和同步工具。优良的中文/Unicode支持。

Kftpgrabber

KDE下ftp客户端,支持编码选择。对中文支持较好

filezilla

对中文支持好

krusader

也可以通过浏览器输入ftp://ip使用

如果有喜欢的可以通过apt-get 或者 aptitude 安装。

2,CLI(命令行)主要有ftp 和 lftp

(1)ftp

1. 连接ftp服务器

  格式:ftp [hostname| ip-address]

  a)在linux命令行下输入:ftp 10.18.34.115

  b)服务器询问你用户名和口令,分别输入yint和相应密码,待认证通过即可。

或者用下面的格式

 ftp – -i -n IP_ADDRESS

  user USERNAME PASSWORD

比如:

ftp -i -n 172.17.17.17

user PUB 123456

也可以自己写个脚本自动登录。

cyq@cyq-desktop:~/桌面/shell$ cat ftp.sh

#!/bin/sh

ftp -i -n 172.17.17.17

<< ! user PUB 123456 ! 这样就可以自动登录了。   2. 下载文件   下载文件通常用get和mget这两条命令。   a) get   格式:get [remote-file] [local-file]   将文件从远端主机中传送至本地主机中.   如要获取服务器上E:/rose/1.bmp,则   ftp> get /rose/1.bmp 1.bmp (回车)

  b) mget      

  格式:mget [remote-files]

  从远端主机接收一批文件至本地主机.

  如要获取服务器上E:/rose/下的所有文件,则

  ftp> cd /rose

  ftp> mget *.* (回车)

  注意:文件都下载到了linux主机的当前目录下。比如,在 /root/yint下运行的ftp命令,则文件都下载到了/root/yint下。

  3.上传文件

  a) put

  格式:put local-file [remote-file]

  将本地一个文件传送至远端主机中.

  如要把本地的1.bmp传送到远端主机E:/rose,并改名为333.bmp

  ftp> put 1.bmp /rose/333.bmp (回车)

  b) mput

  格式:mput local-files

  将本地主机中一批文件传送至远端主机.

  如要把本地当前目录下所有bmp文件上传到服务器E:/rose 下

  ftp> cd /rose (回车)

  ftp> mput *.bmp (回车)

  注意:上传文件都来自于主机的当前目录下。比如,在 /root/yint下运行的ftp命令,则只有在/root/yint下的文件linux才会上传到服务器E:/rose 下。

  4. 断开连接

  bye:中断与服务器的连接。

  ftp> bye (回车)

(2)lftp

在用lftp访问国内一些ftp服务器时,往往看到的中文是乱码,这是由于服务器和本地编码不一致造成的。

解决办法:

在主目录下新建一个文件~/.lftprc或者~/.lftp/rc

比如我在终端中输入:

gedit ~/.lftprc #在当前目录下建立.lftprc文件

然后在弹出的对话框中输入以下内容:

debug 3

set ftp:charset GBK

set file:charset UTF-8

#set ftp:passtive-mode no

#alias utf8 ” set ftp:charset UTF-8″

#alias gbk ” set ftp:charset GBK”

上面的这几行的意思是

设置本地和ftp服务器的编码方式

alias 是使用别名命令

如果对于经常使用不同编码的 ftp server 的朋友,或经常使用不同的选项的,可以设置一些别名,这样会方便很多。
比如:

我经常访问 gbk 编码的 ftp, 还有 utf8 编码的,那么我在 ~/.lftp 中这样写

代码:

alias gbk set ftp:charset gbk; set file:charset UTF-8
alias utf8 set ftp:charset UTF-8; set file:charset UTF-8

那么当我访问一个 utf8 站点的时候,如果发现乱码,只要在 lftp 的命令提示符号下面输入 utf8 就可以将编码调整正常。同理,如果访问 gbk 的发现乱码就输入 gbk, 马上正常。

下面讲解使用lftp

1、登录ftp

代码:

lftp 用户名:密码@ftp地址:传送端口(默认21)

例如: $ lftp test:123456@172.17.17.17

也可以先不带用户名登录,然后在接口界面下用login命令来用指定账号登录,密码不显示。

lftp user@site:port

例如:$ lftp test@172.17.17.17

口令:

然后就进入了。(这里输入的口令是密码,linux下密码不显示)

2、查看文件与改变目录

代码:

ls
cd 对应ftp目录

在lftp终端中,前面带一个l的命令例如lcd,指的是local,就是在本机的操作,而对应的没有这个l的,都是对ftp site的操作。还有就是要执行本地终端命令,也可以用前面带一个!的方式。这样,配合起来,终端,本地的操作都很放遍。
例如,查看ftp上所有的以mp3为扩展名的文件:

代码:

find . -name “*.mp3”

代码:

lftp test@172.17.17.17:/> lcd

lcd 成功, 本地目录=/home/cyq

lftp test@172.17.17.17:/>

3、下载
get当然是可以的,还可以

代码:

mget -c *.pdf

把所有的pdf文件以允许断点续传的方式下载。m代表multi

代码:

mirror aaa/

将aaa目录整个的下载下来,子目录也会自动复制

代码:

pget -c -n 10 file.dat

以最多10个线程以允许断点续传的方式下载file.dat
可以通过设置pget:default-n的值而使用默认值。

4、上传
同样的put,mput,都是对文件的操作,和下载类似。

代码:

mirror -R 本地目录名

将本地目录以迭代(包括子目录)的方式反向上传到ftp site。

5、模式设置。

代码:

set ftp:charset gbk

远程ftp site用gbk编码,对应的要设置为utf8,只要替换gbk为utf8即可。

代码:

set file:charset utf8

本地的charset设定为utf8,如果你是gbk,相应改掉。

代码:

set ftp:passive-mode 1

使用被动模式登录,有些site要求必须用被动模式或者主动模式才可以登录,这个开关就是设置这个的。0代表不用被动模式。

6、书签
其实命令行也可以有书签,在lftp终端提示符下:

代码:

bookmark add ustc

就可以把当前正在浏览的ftp site用ustc作为标签储存起来。以后在shell终端下,直接

代码:

lftp ustc

就可以自动填好用户名,密码,进入对应的目录了。

代码:

bookmark edit

会调用编辑器手动修改书签。当然,也可以看到,这个书签其实就是个简单的文本文件。密码,用户名都可以看到。

7、配置文件
/etc/lftp.conf
一般,我会添加这几行:

引用:

set ftp:charset gbk
set file:charset utf8
set pget:default-n 5

这样,就不用每次进入都要打命令了。其他的set 可以自己tab然后help 来看。

下面是常用命令

ls

显示远端文件列表(ils 显示本地文件列表)。# l 的意思就是local ils比较特殊

cd

切换远端目录(lcd 切换本地目录)。

get

下载远端文件。

mget

下载远端文件(可以用通配符也就是 *)。

pget

使用多个线程来下载远端文件, 预设为五个。

mirror

下载/上传(mirror -R)/同步 整个目录。

put

上传文件。

mput

上传多个文件(支持通配符)。

mv

移动远端文件(远端文件改名)。

rm

删除远端文件。

参数-r,递归删除文件夹

mrm

删除多个远端文件(支持通配符)。

mkdir

建立远端目录。

rmdir

删除远端目录。

pwd

显示目前远端所在目录(lpwd 显示本地目录)。

du

计算远端目录的大小

set net:limit-rate 10000,10000

限制上传下载各为10KB/s

set ftp:charset gbk

设置远程ftp site用gbk编码

!

执行本地 shell的命令(由于lftp 没有 lls, 故可用 !ls 来替代)

lcd

切换本地目录

lpwd

显示本地目录

alias

定义别名

bookmark

设定书签。

exit

退出ftp

发表在 新闻头条 | 标签为 , , | Linux之ftp命令使用已关闭评论