MySQL常用用户管理命令

1、添加用户

本机访问权限:

  1. mysql> GRANT ALL PRIVILEGES ON *.* TO ‘username’@’localhost’ IDENTIFIED BY ‘password’ WITH GRANT OPTION;

远程访问权限:

  1. mysql> GRANT ALL PRIVILEGES ON *.* TO ‘username’@’%’ IDENTIFIED BY ‘password’ WITH GRANT OPTION;

另外还有一种方法是直接Insert INTO user,注意这种方法之后需要 FLUSH PRIVILEGES 让服务器重读授权表。

  1. insert into user(host,user,password,ssl_cipher,x509_issuer,x509_subject) values(‘localhost’,’xff’,password(‘xff’),”,”,”);
  2. FLUSH PRIVILEGES;

note:1)必须要加上ssl_cipher,x509_issuer,x509_subject三列,以为其默认值不为空(数据库版本为:5.0.51b)
2)FLUSH PRIVILEGES重载授权表,使权限更改生效
3)mysql是通过User表,Db表,Host表,Tables_priv 表,Columns_priv 表这5张表实现用户权限控制,均可以通过直接对这些表的操作以达到对用户的管理

2、删除用户

  1. drop user admin@localhost;(@不加默认为“%”)

3、权限回收

  1. revoke delete on test.* from admin@’localhost’;

4、创建用户授权一起实现

  1. grant select,insert,update,delete on *.* to ‘admin2′@’%’ identified by ‘admin2′ with grant option;

note:在mysql中,如果@后面的登录范围不同,帐号可以一样

5、限制用户资源

  1. mysql> GRANT ALL ON customer.* TO ‘francis’@’localhost’
  2. -> IDENTIFIED BY ‘frank’
  3. -> WITH MAX_QUERIES_PER_HOUR 20
  4. -> MAX_UPDATES_PER_HOUR 10
  5. -> MAX_CONNECTIONS_PER_HOUR 5
  6. -> MAX_USER_CONNECTIONS 2;

6、用户密码设置

使用mysqladmin:

  1. shell> mysqladmin -u user_name -h host_name password "newpwd"

或在mysql里执行语句:

  1. mysql> SET PASSWORD FOR ‘username’@’%’ = PASSWORD(‘password’);

如果只是更改自己的密码,则:

  1. mysql> SET PASSWORD = PASSWORD(‘password’);

在全局级别使用GRANT USAGE语句(在*.*)来指定某个账户的密码:

  1. mysql> GRANT USAGE ON *.* TO ‘username’@’%’ IDENTIFIED BY ‘password’;

或直接修改MySQL库表:

  1. mysql> UPDATE user SET Password = PASSWORD(‘bagel’)  WHERE Host = ‘%’ AND User = ‘francis’;
  2. mysql> FLUSH PRIVILEGES;

修改root密码:

  1. update mysql.user set password=password(‘passw0rd’) where user=’root’;
  2. FLUSH PRIVILEGES;

7、关于加密

  1. mysql> select PASSWORD(‘password’);
  2. +——————————————-+
  3. | PASSWORD(‘password’)                      |
  4. +——————————————-+
  5. | *2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19 |
  6. +——————————————-+
  7. 1 row in set (0.00 sec)
  8.  
  9. mysql> select MD5(‘hello’);
  10. +———————————-+
  11. | MD5(‘hello’)                     |
  12. +———————————-+
  13. | 5d41402abc4b2a76b9719d911017c592 |
  14. +———————————-+
  15. 1 row in set (0.00 sec)
  16.  
  17. mysql> select SHA1(‘abc’);
  18.  
  19. -> ‘a9993e364706816aba3e25717850c26c9cd0d89d’

SHA1()是为字符串算出一个 SHA1 160比特检查和,如RFC 3174 (安全散列算法)中所述。

8、授权精确到列

  1. grant select (cur_url,pre_url) on test.abc to admin@localhost;

文章来源:http://www.ha97.com/4109.html

MySQL my.cnf参数配置优化详解

PS:本配置文件针对Dell R710,双至强E5620、16G内存的硬件配置。CentOS 5.6 64位系统,MySQL 5.5.x 稳定版。适用于日IP 50-100w,PV 100-300w的站点,主要使用InnoDB存储引擎。其他应用环境请根据实际情况来设置优化。

# 以下选项会被MySQL客户端应用读取。
# 注意只有MySQL附带的客户端应用程序保证可以读取这段内容。
# 如果你想你自己的MySQL应用程序获取这些值。
# 需要在MySQL客户端库初始化的时候指定这些选项。

#
[client]
#password = [your_password]
port = @MYSQL_TCP_PORT@
socket = @MYSQL_UNIX_ADDR@

# *** 应用定制选项 ***

#
# MySQL 服务端
#
[mysqld]

# 一般配置选项
port = @MYSQL_TCP_PORT@
socket = @MYSQL_UNIX_ADDR@

# back_log 是操作系统在监听队列中所能保持的连接数,
# 队列保存了在MySQL连接管理器线程处理之前的连接.
# 如果你有非常高的连接率并且出现”connection refused” 报错,
# 你就应该增加此处的值.
# 检查你的操作系统文档来获取这个变量的最大值.
# 如果将back_log设定到比你操作系统限制更高的值,将会没有效果
back_log = 300

# 不在TCP/IP端口上进行监听.
# 如果所有的进程都是在同一台服务器连接到本地的mysqld,
# 这样设置将是增强安全的方法
# 所有mysqld的连接都是通过Unix sockets 或者命名管道进行的.
# 注意在windows下如果没有打开命名管道选项而只是用此项
# (通过 “enable-named-pipe” 选项) 将会导致mysql服务没有任何作用!
#skip-networking

# MySQL 服务所允许的同时会话数的上限
# 其中一个连接将被SUPER权限保留作为管理员登录.
# 即便已经达到了连接数的上限.
max_connections = 3000
# 每个客户端连接最大的错误允许数量,如果达到了此限制.
# 这个客户端将会被MySQL服务阻止直到执行了”FLUSH HOSTS” 或者服务重启
# 非法的密码以及其他在链接时的错误会增加此值.
# 查看 “Aborted_connects” 状态来获取全局计数器.
max_connect_errors = 30

# 所有线程所打开表的数量.
# 增加此值就增加了mysqld所需要的文件描述符的数量
# 这样你需要确认在[mysqld_safe]中 “open-files-limit” 变量设置打开文件数量允许至少4096
table_cache = 4096

# 允许外部文件级别的锁. 打开文件锁会对性能造成负面影响
# 所以只有在你在同样的文件上运行多个数据库实例时才使用此选项(注意仍会有其他约束!)
# 或者你在文件层面上使用了其他一些软件依赖来锁定MyISAM表
#external-locking

# 服务所能处理的请求包的最大大小以及服务所能处理的最大的请求大小(当与大的BLOB字段一起工作时相当必要)
# 每个连接独立的大小.大小动态增加
max_allowed_packet = 32M

# 在一个事务中binlog为了记录SQL状态所持有的cache大小
# 如果你经常使用大的,多声明的事务,你可以增加此值来获取更大的性能.
# 所有从事务来的状态都将被缓冲在binlog缓冲中然后在提交后一次性写入到binlog中
# 如果事务比此值大, 会使用磁盘上的临时文件来替代.
# 此缓冲在每个连接的事务第一次更新状态时被创建
binlog_cache_size = 4M

# 独立的内存表所允许的最大容量.
# 此选项为了防止意外创建一个超大的内存表导致永尽所有的内存资源.
max_heap_table_size = 128M

# 排序缓冲被用来处理类似ORDER BY以及GROUP BY队列所引起的排序
# 如果排序后的数据无法放入排序缓冲,
# 一个用来替代的基于磁盘的合并分类会被使用
# 查看 “Sort_merge_passes” 状态变量.
# 在排序发生时由每个线程分配
sort_buffer_size = 16M

# 此缓冲被使用来优化全联合(full JOINs 不带索引的联合).
# 类似的联合在极大多数情况下有非常糟糕的性能表现,
# 但是将此值设大能够减轻性能影响.
# 通过 “Select_full_join” 状态变量查看全联合的数量
# 当全联合发生时,在每个线程中分配
join_buffer_size = 16M

# 我们在cache中保留多少线程用于重用
# 当一个客户端断开连接后,如果cache中的线程还少于thread_cache_size,
# 则客户端线程被放入cache中.
# 这可以在你需要大量新连接的时候极大的减少线程创建的开销
# (一般来说如果你有好的线程模型的话,这不会有明显的性能提升.)
thread_cache_size = 16

# 此允许应用程序给予线程系统一个提示在同一时间给予渴望被运行的线程的数量.
# 此值只对于支持 thread_concurrency() 函数的系统有意义( 例如Sun Solaris).
# 你可可以尝试使用 [CPU数量]*(2..4) 来作为thread_concurrency的值
thread_concurrency = 8

# 查询缓冲常被用来缓冲 SELECT 的结果并且在下一次同样查询的时候不再执行直接返回结果.
# 打开查询缓冲可以极大的提高服务器速度, 如果你有大量的相同的查询并且很少修改表.
# 查看 “Qcache_lowmem_prunes” 状态变量来检查是否当前值对于你的负载来说是否足够高.
# 注意: 在你表经常变化的情况下或者如果你的查询原文每次都不同,
# 查询缓冲也许引起性能下降而不是性能提升.
query_cache_size = 128M

# 只有小于此设定值的结果才会被缓冲
# 此设置用来保护查询缓冲,防止一个极大的结果集将其他所有的查询结果都覆盖.
query_cache_limit = 4M

# 被全文检索索引的最小的字长.
# 你也许希望减少它,如果你需要搜索更短字的时候.
# 注意在你修改此值之后,
# 你需要重建你的 FULLTEXT 索引
ft_min_word_len = 8

# 如果你的系统支持 memlock() 函数,你也许希望打开此选项用以让运行中的mysql在在内存高度紧张的时候,数据在内存中保持锁定并且防止可能被swapping out
# 此选项对于性能有益
#memlock

# 当创建新表时作为默认使用的表类型,
# 如果在创建表示没有特别执行表类型,将会使用此值
default_table_type = MYISAM

# 线程使用的堆大小. 此容量的内存在每次连接时被预留.
# MySQL 本身常不会需要超过64K的内存
# 如果你使用你自己的需要大量堆的UDF函数
# 或者你的操作系统对于某些操作需要更多的堆,
# 你也许需要将其设置的更高一点.
thread_stack = 512K

# 设定默认的事务隔离级别.可用的级别如下:
# READ-UNCOMMITTED, READ-COMMITTED, REPEATABLE-READ, SERIALIZABLE
transaction_isolation = REPEATABLE-READ

# 内部(内存中)临时表的最大大小
# 如果一个表增长到比此值更大,将会自动转换为基于磁盘的表.
# 此限制是针对单个表的,而不是总和.
tmp_table_size = 128M

# 打开二进制日志功能.
# 在复制(replication)配置中,作为MASTER主服务器必须打开此项
# 如果你需要从你最后的备份中做基于时间点的恢复,你也同样需要二进制日志.
log-bin=mysql-bin

# 如果你在使用链式从服务器结构的复制模式 (A->B->C),
# 你需要在服务器B上打开此项.
# 此选项打开在从线程上重做过的更新的日志,
# 并将其写入从服务器的二进制日志.
#log_slave_updates

# 打开全查询日志. 所有的由服务器接收到的查询 (甚至对于一个错误语法的查询)
# 都会被记录下来. 这对于调试非常有用, 在生产环境中常常关闭此项.
#log

# 将警告打印输出到错误log文件. 如果你对于MySQL有任何问题
# 你应该打开警告log并且仔细审查错误日志,查出可能的原因.
#log_warnings

# 记录慢速查询. 慢速查询是指消耗了比 “long_query_time” 定义的更多时间的查询.
# 如果 log_long_format 被打开,那些没有使用索引的查询也会被记录.
# 如果你经常增加新查询到已有的系统内的话. 一般来说这是一个好主意,
log_slow_queries

# 所有的使用了比这个时间(以秒为单位)更多的查询会被认为是慢速查询.
# 不要在这里使用”1″, 否则会导致所有的查询,甚至非常快的查询页被记录下来(由于MySQL 目前时间的精确度只能达到秒的级别).
long_query_time = 6

# 在慢速日志中记录更多的信息.
# 一般此项最好打开.
# 打开此项会记录使得那些没有使用索引的查询也被作为到慢速查询附加到慢速日志里
log_long_format

# 此目录被MySQL用来保存临时文件.例如,
# 它被用来处理基于磁盘的大型排序,和内部排序一样.
# 以及简单的临时表.
# 如果你不创建非常大的临时文件,将其放置到 swapfs/tmpfs 文件系统上也许比较好
# 另一种选择是你也可以将其放置在独立的磁盘上.
# 你可以使用”;”来放置多个路径
# 他们会按照roud-robin方法被轮询使用.
#tmpdir = /tmp

# *** 主从复制相关的设置

# 唯一的服务辨识号,数值位于 1 到 2^32-1之间.
# 此值在master和slave上都需要设置.
# 如果 “master-host” 没有被设置,则默认为1, 但是如果忽略此选项,MySQL不会作为master生效.
server-id = 1

# 复制的Slave (去掉master段的注释来使其生效)
#
# 为了配置此主机作为复制的slave服务器,你可以选择两种方法:
#
# 1) 使用 CHANGE MASTER TO 命令 (在我们的手册中有完整描述) –
# 语法如下:
#
# CHANGE MASTER TO MASTER_HOST=, MASTER_PORT=,
# MASTER_USER=, MASTER_PASSWORD= ;
#
# 你需要替换掉 , , 等被尖括号包围的字段以及使用master的端口号替换 (默认3306).
#
# 例子:
#
# CHANGE MASTER TO MASTER_HOST=’125.564.12.1′, MASTER_PORT=3306,
# MASTER_USER=’joe’, MASTER_PASSWORD=’secret’;
#
# 或者
#
# 2) 设置以下的变量. 不论如何, 在你选择这种方法的情况下, 然后第一次启动复制(甚至不成功的情况下,
# 例如如果你输入错密码在master-password字段并且slave无法连接),
# slave会创建一个 master.info 文件,并且之后任何对于包含在此文件内的参数的变化都会被忽略
# 并且由 master.info 文件内的内容覆盖, 除非你关闭slave服务, 删除 master.info 并且重启slave 服务.
# 由于这个原因,你也许不想碰一下的配置(注释掉的) 并且使用 CHANGE MASTER TO (查看上面) 来代替
#
# 所需要的唯一id号位于 2 和 2^32 – 1之间
# (并且和master不同)
# 如果master-host被设置了.则默认值是2
# 但是如果省略,则不会生效
#server-id = 2
#
# 复制结构中的master – 必须
#master-host =
#
# 当连接到master上时slave所用来认证的用户名 – 必须
#master-user =
#
# 当连接到master上时slave所用来认证的密码 – 必须
#master-password =
#
# master监听的端口.
# 可选 – 默认是3306
#master-port =

# 使得slave只读.只有用户拥有SUPER权限和在上面的slave线程能够修改数据.
# 你可以使用此项去保证没有应用程序会意外的修改slave而不是master上的数据
#read_only

#*** MyISAM 相关选项

# 关键词缓冲的大小, 一般用来缓冲MyISAM表的索引块.
# 不要将其设置大于你可用内存的30%,
# 因为一部分内存同样被OS用来缓冲行数据
# 甚至在你并不使用MyISAM 表的情况下, 你也需要仍旧设置起 8-64M 内存由于它同样会被内部临时磁盘表使用.
key_buffer_size = 128M

# 用来做MyISAM表全表扫描的缓冲大小.
# 当全表扫描需要时,在对应线程中分配.
read_buffer_size = 8M

# 当在排序之后,从一个已经排序好的序列中读取行时,行数据将从这个缓冲中读取来防止磁盘寻道.
# 如果你增高此值,可以提高很多ORDER BY的性能.
# 当需要时由每个线程分配
read_rnd_buffer_size = 64M

# MyISAM 使用特殊的类似树的cache来使得突发插入
# (这些插入是,INSERT … SELECT, INSERT … VALUES (…), (…), …, 以及 LOAD DATA
# INFILE) 更快. 此变量限制每个进程中缓冲树的字节数.
# 设置为 0 会关闭此优化.
# 为了最优化不要将此值设置大于 “key_buffer_size”.
# 当突发插入被检测到时此缓冲将被分配.
bulk_insert_buffer_size = 256M

# 此缓冲当MySQL需要在 REPAIR, OPTIMIZE, ALTER 以及 LOAD DATA INFILE 到一个空表中引起重建索引时被分配.
# 这在每个线程中被分配.所以在设置大值时需要小心.
myisam_sort_buffer_size = 256M

# MySQL重建索引时所允许的最大临时文件的大小 (当 REPAIR, ALTER TABLE 或者 LOAD DATA INFILE).
# 如果文件大小比此值更大,索引会通过键值缓冲创建(更慢)
myisam_max_sort_file_size = 10G

# 如果被用来更快的索引创建索引所使用临时文件大于制定的值,那就使用键值缓冲方法.
# 这主要用来强制在大表中长字串键去使用慢速的键值缓冲方法来创建索引.
myisam_max_extra_sort_file_size = 10G

# 如果一个表拥有超过一个索引, MyISAM 可以通过并行排序使用超过一个线程去修复他们.
# 这对于拥有多个CPU以及大量内存情况的用户,是一个很好的选择.
myisam_repair_threads = 1

# 自动检查和修复没有适当关闭的 MyISAM 表.
myisam_recover

# 默认关闭 Federated
skip-federated

# *** BDB 相关选项 ***

# 如果你运行的MySQL服务有BDB支持但是你不准备使用的时候使用此选项. 这会节省内存并且可能加速一些事.
skip-bdb

# *** INNODB 相关选项 ***

# 如果你的MySQL服务包含InnoDB支持但是并不打算使用的话,
# 使用此选项会节省内存以及磁盘空间,并且加速某些部分
#skip-innodb

# 附加的内存池被InnoDB用来保存 metadata 信息
# 如果InnoDB为此目的需要更多的内存,它会开始从OS这里申请内存.
# 由于这个操作在大多数现代操作系统上已经足够快, 你一般不需要修改此值.
# SHOW INNODB STATUS 命令会显示当先使用的数量.
innodb_additional_mem_pool_size = 64M

# InnoDB使用一个缓冲池来保存索引和原始数据, 不像 MyISAM.
# 这里你设置越大,你在存取表里面数据时所需要的磁盘I/O越少.
# 在一个独立使用的数据库服务器上,你可以设置这个变量到服务器物理内存大小的80%
# 不要设置过大,否则,由于物理内存的竞争可能导致操作系统的换页颠簸.
# 注意在32位系统上你每个进程可能被限制在 2-3.5G 用户层面内存限制,
# 所以不要设置的太高.
innodb_buffer_pool_size = 6G

# InnoDB 将数据保存在一个或者多个数据文件中成为表空间.
# 如果你只有单个逻辑驱动保存你的数据,一个单个的自增文件就足够好了.
# 其他情况下.每个设备一个文件一般都是个好的选择.
# 你也可以配置InnoDB来使用裸盘分区 – 请参考手册来获取更多相关内容
innodb_data_file_path = ibdata1:10M:autoextend

# 设置此选项如果你希望InnoDB表空间文件被保存在其他分区.
# 默认保存在MySQL的datadir中.
#innodb_data_home_dir =

# 用来同步IO操作的IO线程的数量. This value is
# 此值在Unix下被硬编码为4,但是在Windows磁盘I/O可能在一个大数值下表现的更好.
innodb_file_io_threads = 4

# 如果你发现InnoDB表空间损坏, 设置此值为一个非零值可能帮助你导出你的表.
# 从1开始并且增加此值知道你能够成功的导出表.
#innodb_force_recovery=1

# 在InnoDb核心内的允许线程数量.
# 最优值依赖于应用程序,硬件以及操作系统的调度方式.
# 过高的值可能导致线程的互斥颠簸.
innodb_thread_concurrency = 16

# 如果设置为1 ,InnoDB会在每次提交后刷新(fsync)事务日志到磁盘上,
# 这提供了完整的ACID行为.
# 如果你愿意对事务安全折衷, 并且你正在运行一个小的食物, 你可以设置此值到0或者2来减少由事务日志引起的磁盘I/O
# 0代表日志只大约每秒写入日志文件并且日志文件刷新到磁盘.
# 2代表日志写入日志文件在每次提交后,但是日志文件只有大约每秒才会刷新到磁盘上.
innodb_flush_log_at_trx_commit = 2
说明:如果是游戏服务器,建议此值设置为2;如果是对数据安全要求极高的应用,建议设置为1;设置为0性能最高,但如果发生故障,数据可能会有丢失的危险!默认值1的意思是每一次事务提交或事务外的指令都需要把日志写入(flush)硬盘,这是很费时的。特别是使用电池供电缓存(Battery backed up cache)时。设成2对于很多运用,特别是从MyISAM表转过来的是可以的,它的意思是不写入硬盘而是写入系统缓存。日志仍然会每秒flush到硬盘,所以你一般不会丢失超过1-2秒的更新。设成0会更快一点,但安全方面比较差,即使MySQL挂了也可能会丢失事务的数据。而值2只会在整个操作系统挂了时才可能丢数据。

# 加速InnoDB的关闭. 这会阻止InnoDB在关闭时做全清除以及插入缓冲合并.
# 这可能极大增加关机时间, 但是取而代之的是InnoDB可能在下次启动时做这些操作.
#innodb_fast_shutdown

# 用来缓冲日志数据的缓冲区的大小.
# 当此值快满时, InnoDB将必须刷新数据到磁盘上.
# 由于基本上每秒都会刷新一次,所以没有必要将此值设置的太大(甚至对于长事务而言)

innodb_log_buffer_size = 16M

# 在日志组中每个日志文件的大小.
# 你应该设置日志文件总合大小到你缓冲池大小的25%~100%
# 来避免在日志文件覆写上不必要的缓冲池刷新行为.
# 不论如何, 请注意一个大的日志文件大小会增加恢复进程所需要的时间.
innodb_log_file_size = 512M

# 在日志组中的文件总数.
# 通常来说2~3是比较好的.
innodb_log_files_in_group = 3

# InnoDB的日志文件所在位置. 默认是MySQL的datadir.
# 你可以将其指定到一个独立的硬盘上或者一个RAID1卷上来提高其性能
#innodb_log_group_home_dir

# 在InnoDB缓冲池中最大允许的脏页面的比例.
# 如果达到限额, InnoDB会开始刷新他们防止他们妨碍到干净数据页面.
# 这是一个软限制,不被保证绝对执行.
innodb_max_dirty_pages_pct = 90

# InnoDB用来刷新日志的方法.
# 表空间总是使用双重写入刷新方法
# 默认值是 “fdatasync”, 另一个是 “O_DSYNC”.
#innodb_flush_method=O_DSYNC

# 在被回滚前,一个InnoDB的事务应该等待一个锁被批准多久.
# InnoDB在其拥有的锁表中自动检测事务死锁并且回滚事务.
# 如果你使用 LOCK TABLES 指令, 或者在同样事务中使用除了InnoDB以外的其他事务安全的存储引擎
# 那么一个死锁可能发生而InnoDB无法注意到.
# 这种情况下这个timeout值对于解决这种问题就非常有帮助.
innodb_lock_wait_timeout = 120

[mysqldump]
# 不要在将内存中的整个结果写入磁盘之前缓存. 在导出非常巨大的表时需要此项
quick

max_allowed_packet = 32M

[mysql]
no-auto-rehash

# 仅仅允许使用键值的 UPDATEs 和 DELETEs .
#safe-updates

[isamchk]
key_buffer = 2048M
sort_buffer_size = 2048M
read_buffer = 32M
write_buffer = 32M

[myisamchk]
key_buffer = 2048M
sort_buffer_size = 2048M
read_buffer = 32M
write_buffer = 32M

[mysqlhotcopy]
interactive-timeout

[mysqld_safe]
# 增加每个进程的可打开文件数量.
# 警告: 确认你已经将全系统限制设定的足够高!
# 打开大量表需要将此值设大
open-files-limit = 8192
文章来源:http://www.ha97.com/4110.html

MySQL Innodb 存储引擎参数优化

介绍:
InnoDB给MySQL提供了具有提交,回滚和崩溃恢复能力的事务安全(ACID兼容)存储引擎。InnoDB锁定在行级并且也在SELECT语句提供一个Oracle风格一致的非锁定读。这些特色增加了多用户部署和性能。没有在InnoDB中扩大锁定的需要,因为在InnoDB中行级锁定适合非常小的空间。InnoDB也支持FOREIGN KEY强制。在SQL查询中,你可以自由地将InnoDB类型的表与其它MySQL的表的类型混合起来,甚至在同一个查询中也可以混合。
Innodb 的创始人:Heikki Tuuri
Heikki Tuuri在Innodb的Bug社区里也是很活跃的,如果遇到Bug也可以直接提到社区,得到作者的解答。

为什么要学习Innodb的调优:
目前来说:InnoDB是为Mysql处理巨大数据量时的最大性能设计。它的CPU效率可能是任何其它基于磁盘的关系数据库引擎所不能匹敌的。在数据量大的网站或是应用中Innodb是倍受青睐的。
另一方面,在数据库的复制操作中Innodb也是能保证master和slave数据一致有一定的作用。

参数调优内容:

  • 1. 内存利用方面
  • 2. 日值控制方面
  • 3. 文件IO分配,空间占用方面
  • 4. 其它相关参数

1.内存利用方面:

首先介绍一个Innodb最重要的参数:
innodb_buffer_pool_size
这个参数和MyISAM的key_buffer_size有相似之处,但也是有差别的。这个参数主要缓存innodb表的索引,数据,插入数据时的缓冲。为Innodb加速优化首要参数。
该参数分配内存的原则:这个参数默认分配只有8M,可以说是非常小的一个值。如果是一个专用DB服务器,那么他可以占到内存的70%-80%。这个参数不能动态更改,所以分配需多考虑。分配过大,会使Swap占用过多,致使Mysql的查询特慢。如果你的数据比较小,那么可分配是你的数据大小+10%左右做为这个参数的值。例如:数据大小为50M,那么给这个值分配innodb_buffer_pool_size=64M
设置方法:
innodb_buffer_pool_size=4G
这个参数分配值的使用情况可以根据show innodb statusG;中的
———————-
BUFFER POOL AND MEMORY
———————-
Total memory allocated 4668764894;
去确认使用情况。
第二个:
innodb_additional_mem_pool:
作用:用来存放Innodb的内部目录
这个值不用分配太大,系统可以自动调。不用设置太高。通常比较大数据设置16M够用了,如果表比较多,可以适当的增大。如果这个值自动增加,会在error log有中显示的。
分配原则:
show innodb statusG;去查看运行中的DB是什么状态(参考BUFFER POOL AND MEMORY段中),然后可以调整到适当的值。
———————-
BUFFER POOL AND MEMORY
———————-
Total memory allocated 4668764894; in additional pool allocated 16777216
参考:in additional pool allocated 16777216
根据你的参数情况,可以适当的调整。
设置方法:
innodb_additional_mem_pool=16M

2.关于日值方面:

innodb_log_file_size
作用:指定日值的大小
分配原则:几个日值成员大小加起来差不多和你的innodb_buffer_pool_size相等。上限为每个日值上限大小为4G.一般控制在几个LOG文件相加大小在2G以内为佳。具体情况还需要看你的事务大小,数据大小为依据。
说明:这个值分配的大小和数据库的写入速度,事务大小,异常重启后的恢复有很大的关系。
设置方法:
innodb_log_file_size=256M
innodb_log_files_in_group

作用:指定你有几个日值组。
分配原则: 一般我们可以用2-3个日值组。默认为两个。
设置方法:
innodb_log_files_in_group=3
innodb_log_buffer_size:

作用:事务在内存中的缓冲。
分配原则:控制在2-8M.这个值不用太多的。他里面的内存一般一秒钟写到磁盘一次。具体写入方式和你的事务提交方式有关。在Oracle等数据库了解这个,一般最大指定为3M比较合适。
参考:Innodb_os_log_written(show global status 可以拿到)
如果这个值增长过快,可以适当的增加innodb_log_buffer_size
另外如果你需要处理大理的TEXT,或是BLOB字段,可以考虑增加这个参数的值。
设置方法:
innodb_log_buffer_size=3M

innodb_flush_logs_at_trx_commit
作用:控制事务的提交方式
分配原则:这个参数只有3个值,0,1,2请确认一下自已能接受的级别。默认为1,主库请不要更改了。
性能更高的可以设置为0或是2,但会丢失一秒钟的事务。
说明:
这个参数的设置对Innodb的性能有很大的影响,所以在这里给多说明一下。
当这个值为1时:innodb 的事务LOG在每次提交后写入日值文件,并对日值做刷新到磁盘。这个可以做到不丢任何一个事务。
当这个值为2时:在每个提交,日志缓冲被写到文件,但不对日志文件做到磁盘操作的刷新,在对日志文件的刷新在值为2的情况也每秒发生一次。但需要注意的是,由于进程调用方面的问题,并不能保证每秒100%的发生。从而在性能上是最快的。但操作系统崩溃或掉电才会删除最后一秒的事务。
当这个值为0时:日志缓冲每秒一次地被写到日志文件,并且对日志文件做到磁盘操作的刷新,但是在一个事务提交不做任何操作。mysqld进程的崩溃会删除崩溃前最后一秒的事务。

从以上分析,当这个值不为1时,可以取得较好的性能,但遇到异常会有损失,所以需要根据自已的情况去衡量。
设置方法:
innodb_flush_logs_at_trx_commit=1

3.文件IO分配,空间占用方面

innodb_file_per_table
作用:使每个Innodb的表,有自已独立的表空间。如删除文件后可以回收那部分空间。
分配原则:只有使用不使用。但DB还需要有一个公共的表空间。
设置方法:
innodb_file_per_table=1

innodb_file_io_threads
作用:文件读写IO数,这个参数只在Windows上起作用。在LINUX上只会等于4
设置方法:
innodb_file_io_threads=4

innodb_open_files
作用:限制Innodb能打开的表的数据。
分配原则:如果库里的表特别多的情况,请增加这个。这个值默认是300。
设置方法:
innodb_open_files=800
请适当的增加table_cache

4. 其它相关参数

这里说明一个比较重要的参数:
innodb_flush_method
作用:Innodb和系统打交道的一个IO模型
分配原则:Windows不用设置。
Unix可以设置:fsync() or O_SYNC/O_DSYNC
如果系统可以禁止系统的Cache那就把他禁了。
Linux可以选择:O_DIRECT
直接写入磁盘,禁止系统Cache了
设置方法:
innodb_flush_method=O_DIRECT

innodb_max_dirty_pages_pct
作用:控制Innodb的脏页在缓冲中在那个百分比之下,值在范围1-100,默认为90.
这个参数的另一个用处:当Innodb的内存分配过大,致使Swap占用严重时,可以适当的减小调整这个值,使达到Swap空间释放出来。建义:这个值最大在90%,最小在15%。太大,缓存中每次更新需要致换数据页太多,太小,放的数据页太小,更新操作太慢。
设置方法:
innodb_max_dirty_pages_pct=90
动态更改需要有Super权限:
set global innodb_max_dirty_pages_pct=50;

总结:
这里只算是列出了Innodb部分的重要参数,不能认为是对MySQL的整体调优。MySQL的参数一般分为:全局参数,具体引擎的参数。
文章来源:http://imysql.cn/

MySQL MyISAM/InnoDB高并发优化经验

最近做的一个应用,功能要求非常简单,就是 key/value 形式的存储,简单的 INSERT/SELECT,没有任何复杂查询,唯一的问题是量非常大,如果目前投入使用,初期的单表 insert 频率约 20Hz(次/秒,我喜欢这个单位,让我想起国内交流电是 50Hz),但我估计以后会有 500Hz+ 的峰值。目前的工作成果,额定功率 200Hz(CPU 占用 10 – 20,load avg = 2),最大功率 500Hz(这时 load avg > 20,很明显,只能暂时挺挺,应该在出现这种负载前提前拆表了)

  1. INSERT DELAYED INTO

从 数据的插入开始说起。如果可以容忍结果几秒以后再生效的,可以用 INSERT DELAYED INTO,因为在我的这个结构中不需要对同一个 key 频繁的 INSERT/SELECT,因为 SELECT 我是用 Memcached 挡住了,除非 Memcached 挂了,或者数据实在老到过期了,才会去 SELECT。而且要注意,如果 PHP 不需要关心 MySQL 操作的返回结果,应该使用 unbuffered query,简单的说,在你提交 query 后,不用等待 MySQL 有返回信息就继续执行之后的 PHP 指令,具体用法是用 mysql_unbuffered_query 代替 mysql_query,如果用的 MySQLi 类,应该使用 mysqli->query($sQuery, MYSQLI_USE_RESULT);

如果 SHOW PROCESSLIST,可以看到用户名为 DELAYED 的进程,进程数量等于 INSERT DELAYED 的表的数量,因为表级锁的存在,每个表一条以上的 DELAYED 进程是没有意义的

关于这个功能的 my.cnf 配置有三条,我定为如下值

  1. delayed_insert_limit = 1000
  2. delayed_insert_timeout = 300
  3. delayed_queue_size = 5000

连接

有 人说,如果报错连接数过大,你把 max_connections 调大就 OK,如果只这么说而不讲原因,完全是句废话,你调成 1M 肯定不会再报 Too many connections(但应该会报内存溢出之类的),但如果是这样 MySQL 又何必给这个参数?

我看到的一个很有用的公式

  1. key_buffer_size + (read_buffer_size + sort_buffer_size) * max_connections

以前只有很模糊的概念,应该设的很大,但又不能太大,具体多大合适,知道这个就明确了。innoDB 的公式比这个复杂点,一并给出

  1. innodb_buffer_pool_size
  2. + key_buffer_size
  3. + max_connections * ( sort_buffer_size + read_buffer_size + binlog_cache_size )
  4. + max_connections * 2MB

还有一个看起来很有用的参数 back_log,给我一种连接池的感觉,而且它确实在起作用,我不知道如果设大了会占用多少内存,但估计不会很多。

key_buffer_size

很 多文章都告诉你越大越好,要为此分配一半左右的物理内存,这么干通常不会出问题,但肯定不是最优的,甚至可以说很无理头——分多少内存应该是根据需求决 定,而不是不管什么机器,都砍掉一半内存用作 key_buffer_size ——有的时候可能是不够,还有的时候可能是浪费。

其实最关 键的指标,还是看 SHOW GLOBAL STATUS 时的 Key_blocks_unused,只要还有剩余,就说明 key_buffer_size 没用满。有人说看 Key_reads 跟 Key_read_requests 的比值,至少要达到 1:100。这可以作为一个结果来衡量,但不够准确,因为在服务器刚启动的时候,大多数请求都要新建缓存,缓存命中比高不起来,需要运行稳定(几小时后) 再观察。我个人建议还是看 Key_blocks_unused

如果不花很长时间在运行中调试,给出一个简单的计算方法,把数据库填满,达到设计时的最大值,看看这时候索引占了多大空间,然后把所有表的索引大小加起来,就是 key_buffer_size 可能达到的最大值,当然,还要留些余地,乘个 2 或 3 之类的。

这是我做测试的时候的 phpMyAdmin 截图,可以看到 key_buffer_size 被浪费了太多。
MySQL
OPTIMIZE TABLE

优 化一下有好处,但会锁住表,是否值得做要权衡一下。拿我现在这个表做例子,有 text 字段,700万条记录,1.5G 大小,优化时间约两分钟,优化后性能提升了 50%,同时表的大小变为 1.4G,但随着表的频繁改写,约一天后又恢复到以前的速度,因此在我看来并不值得。

Query Cache

因为每有写操作 Query Cache 都会被清空,除了极特殊的情况(大量读,少量写,但即使这样也应该是多用 memcached 才对)完全没有必要使用这个,把 query_cache_size 设为 0 关闭这个功能吧。

InnoDB和MyISAM是在使用MySQL最常用的两个表类型,各有优缺点,视具体应用而定。基本 的差别为:MyISAM类型不支持事务处理等高级处理,而InnoDB类型支持。MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快, 但是不提供事务支持,而InnoDB提供事务支持已经外部键等高级数据库功能。

MyISAM:这个是默认类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法.与其他存储引擎比较,MyISAM具有检查和修复表格的大多数工具. MyISAM表格可以被压缩,而且它们支持全文搜索.它们不是事务安全的,而且也不支持外键。如果事物回滚将造成不完全回滚,不具有原子性。如果执行大量 的SELECT,MyISAM是更好的选择。

InnoDB:这种类型是事务安全的.它与BDB类型具有相同的特性,它们还支持外键.InnoDB表格速度很快.具有比BDB还丰富的特性,因此如果需 要一个事务安全的存储引擎,建议使用它.如果你的数据执行大量的INSERT或UPDATE,出于性能方面的考虑,应该使用InnoDB表,

对于支持事物的InnoDB类型的标,影响速度的主要原因是AUTOCOMMIT默认设置是打开的,而且程序没有显式调用BEGIN 开始事务,导致每插入一条都自动Commit,严重影响了速度。可以在执行sql前调用begin,多条sql形成一个事物(即使autocommit打 开也可以),将大大提高性能。

MyIASM是IASM表的新版本,有如下扩展:

  • 1、二进制层次的可移植性。
  • 2、NULL列索引。
  • 3、对变长行比ISAM表有更少的碎片。
  • 4、支持大文件。
  • 5、更好的索引压缩。
  • 6、更好的键码统计分布。
  • 7、更好和更快的auto_increment处理。

InnoDB 是 MySQL 上第一个提供外键约束的引擎,除了提供事务处理外,InnoDB 还支持行锁,提供和 Oracle 一样的一致性的不加锁读取,能增加并发读的用户数量并提高性能,不会增加锁的数量。

InnoDB 的设计目标是处理大容量数据时最大化性能,它的 CPU 利用率是其他所有基于磁盘的关系数据库引擎中最有效率的。

InnoDB 是一套放在 MySQL 后台的完整数据库系统,InnoDB 有它自己的缓冲池,能缓冲数据和索引,InnoDB 还把数据和索引存放在表空间里面,可能包含好几个文件,这和 MyISAM 表完全不同,在 MyISAM 中,表被存放在单独的文件中,InnoDB 表的大小只受限于操作系统文件的大小,一般为 2GB。

InnoDB所有的表都保存在同一个数据文件 ibdata1 中(也可能是多个文件,或者是独立的表空间文件),相对来说比较不好备份,免费的方案可以是拷贝数据文件、备份 binlog,或者用 mysqldump。

MyISAM 是MySQL缺省存贮引擎 .

每张MyISAM 表被存放在三个文件 。frm 文件存放表格定义。 数据文件是MYD (MYData) 。 索引文件是MYI (MYIndex) 引伸。

因为MyISAM相对简单所以在效率上要优于InnoDB..小型应用使用MyISAM是不错的选择。

MyISAM表是保存成文件的形式,在跨平台的数据转移中使用MyISAM存储会省去不少的麻烦。

以下是一些细节和具体实现的差别:

  • 1、InnoDB不支持FULLTEXT类型的索引。
  • 2、InnoDB 中不保存表的具体行数,也就是说,执行select count(*) from table时,InnoDB要扫描一遍整个表来计算有多少行,但是MyISAM只要简单的读出保存好的行数即可。注意的是,当count(*)语句包含 where条件时,两种表的操作是一样的。
  • 3、对于AUTO_INCREMENT类型的字段,InnoDB中必须包含只有该字段的索引,但是在MyISAM表中,可以和其他字段一起建立联合索引。
  • 4、DELETE FROM table时,InnoDB不会重新建立表,而是一行一行的删除。
  • 5、LOAD TABLE FROM MASTER操作对InnoDB是不起作用的,解决方法是首先把InnoDB表改成MyISAM表,导入数据后再改成InnoDB表,但是对于使用的额外的InnoDB特性(例如外键)的表不适用。
  • 6、InnoDB表的行锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表,例如update table set num=1 where name like “%aaa%”

综上所述,任何一种表都不是万能的,只有恰当的针对业务类型来疡合适的表类型,才能最大的发挥MySQL的性能优势。

两种类型最主要的差别就是 InnoDB 支持事务处理与外键和行级锁.而MyISAM不支持.所以Myisam往往就容易被人认为只适合在小项目中使用。

我作为使用mysql的用户角度出发,innodb和myisam都是比较喜欢的,但是从我目前运维的数据库平台要达到需求:99.9%的稳定性,方便的扩展性和高可用性来说的话,myisam绝对是我的首选。

原因如下:

  • 1.首先我目前平台上承载的大部分项目是读多写少的项目,而myisam的读性能是比innodb强不少的。
  • 2.myisam的索引和数据是分开的,并且索引是有压缩的,内存使用率就对应提高了不少。能加载更多索引,而innodb是索引和数据是紧密捆绑的,没有使用压缩从而会造成innodb比myisam体积庞大不校
  • 3.从平台角度来说,经常隔1,2个月就会发生应用开发人员不小心update一个表where写的范围不对,导致这个表没法正常用了,这个时候 myisam 的优越性就体现出来了,随便从当天拷贝的压缩包取出对应表的文件,随便放到一个数据库目录下,然后dump成sql再导回到主库,并把对应的binlog 补上。如果是innodb,恐怕不可能有这么快速度,别和我说让innodb定期用导出xxx.sql机制备份,因为我平台上最小的一个数据库实例的数据 量基本都是几十G大校
  • 4.从我接触的应用逻辑来说,select count(*) 和order by 是最频繁的,大概能占了整个sql总语句的60%以上的操作,而这种操作innodb其实也是会锁表的,很多人以为innodb是行级锁,那个只是 where对它主键是有效,非主键的都会锁全表的。
  • 5.还有就是经常有很多应用部门需要我给他们定期某些表的数据,myisam的话很方便,只要发给他们对应那表的frm.MYD,MYI的文件,让他们自 己在对应版本的数据库启动就行,而innodb就需要导出xxx.sql了,因为光给别人文件,受字典数据文件的影响,对方是无法使用的。
  • 6.如果和myisam比insert写操作的话,innodb还达不到myisam的写性能,如果是针对基于索引的update操作,虽然myisam可能会逊色innodb,但是那么高并发的写,从库能否追的上也是一个问题,还不如通过多实例分库分表架构来解决。
  • 7.如果是用Myisam的话,merge引擎可以大大加快应用部门的开发速度,他们只要对这个merge表做一些select count(*)操作,非常适合大项目总量约几亿的rows某一类型(如日志,调查统计)的业务表。

当然innodb也不是绝对不用,用事务的项目如模拟炒股项目,我就是用innodb的,活跃用户20多万时候,也是很轻松应付了,因此我个人也是很喜欢Innodb的,只是

如果从数据库平台应用出发,我还是会首选myisam.

PS:可能有人会说你myisam无法抗太多写操作,但是我可以通过架构来弥补,说个我现有用的数据库平台容量:主从数据总量在几百T以上,每天十多亿 pv的动态页面,还有几个大项目是通过数据接口方式调用未算进pv总数,(其中包括一个大项目因为初期memcached没部署,导致单台数据库每天处理 9千万的查询)。而我的整体数据库服务器平均负载都在0.5-1左右。

MyISAM和InnoDB优化:

key_buffer_size – 这对MyISAM表来说非常重要。如果只是使用MyISAM表,可以把它设置为可用内存的 30-40%。合理的值取决于索引大小、数据量以及负载 — 记住,MyISAM表会使用操作系统的缓存来缓存数据,因此需要留出部分内存给它们,很多情况下数据比索引大多了。尽管如此,需要总是检查是否所有的 key_buffer 都被利用了 — .MYI 文件只有 1GB,而 key_buffer 却设置为 4GB 的情况是非常少的。这么做太浪费了。如果你很少使用MyISAM表,那么也保留低于 16-32MB 的 key_buffer_size 以适应给予磁盘的临时表索引所需。

innodb_buffer_pool_size – 这对Innodb表来说非常重要。Innodb相比MyISAM表对缓冲更为敏感。MyISAM可以在默认的 key_buffer_size 设置下运行的可以,然而Innodb在默认的 innodb_buffer_pool_size 设置下却跟蜗牛似的。由于Innodb把数据和索引都缓存起来,无需留给操作系统太多的内存,因此如果只需要用Innodb的话则可以设置它高达 70-80% 的可用内存。一些应用于 key_buffer 的规则有 — 如果你的数据量不大,并且不会暴增,那么无需把 innodb_buffer_pool_size 设置的太大了。

innodb_additional_pool_size – 这个选项对性能影响并不太多,至少在有差不多足够内存可分配的操作系统上是这样。不过如果你仍然想设置为 20MB(或者更大),因此就需要看一下Innodb其他需要分配的内存有多少。

innodb_log_file_size 在高写入负载尤其是大数据集的情况下很重要。这个值越大则性能相对越高,但是要注意到可能会增加恢复时间。我经常设置为 64-512MB,跟据服务器大小而异。

innodb_log_buffer_size 默 认的设置在中等强度写入负载以及较短事务的情况下,服务器性能还可 以。如果存在更新操作峰值或者负载较大,就应该考虑加大它的值了。如果它的值设置太高了,可能会浪费内存 — 它每秒都会刷新一次,因此无需设置超过1秒所需的内存空间。通常 8-16MB 就足够了。越小的系统它的值越小。

innodb_flush_logs_at_trx_commit 是否为Innodb比MyISAM慢1000倍而头大?看来也许你忘了修改这个参数了。默认值是 1,这意味着每次提交的更新事务(或者每个事务之外的语句)都会刷新到磁盘中,而这相当耗费资源,尤其是没有电池备用缓存时。很多应用程序,尤其是从 MyISAM转变过来的那些,把它的值设置为 2 就可以了,也就是不把日志刷新到磁盘上,而只刷新到操作系统的缓存上。日志仍然会每秒刷新到磁盘中去,因此通常不会丢失每秒1-2次更新的消耗。如果设置 为 0 就快很多了,不过也相对不安全了 — MySQL服务器崩溃时就会丢失一些事务。设置为 2 指挥丢失刷新到操作系统缓存的那部分事务。

table_cache — 打开一个表的开销可能很大。例如MyISAM把MYI文件头标志该表正在使用中。你肯定不希望这种操作太频繁,所以通常要加大缓存数量,使得足以最大限度 地缓存打开的表。它需要用到操作系统的资源以及内存,对当前的硬件配置来说当然不是什么问题了。如果你有200多个表的话,那么设置为 1024 也许比较合适(每个线程都需要打开表),如果连接数比较大那么就加大它的值。我曾经见过设置为 100,000 的情况。

thread_cache — 线程的创建和销毁的开销可能很大,因为每个线程的连接/断开都需要。我通常至少设置为 16。如果应用程序中有大量的跳跃并发连接并且 Threads_Created 的值也比较大,那么我就会加大它的值。它的目的是在通常的操作中无需创建新线程。

query_cache — 如果你的应用程序有大量读,而且没有应用程序级别的缓存,那么这很有用。不要把它设置太大了,因为想要维护它也需要不少开销,这会导致MySQL变慢。通 常设置为 32-512Mb。设置完之后最好是跟踪一段时间,查看是否运行良好。在一定的负载压力下,如果缓存命中率太低了,就启用它。

sort_buffer_size –如果你只有一些简单的查询,那么就无需增加它的值了,尽管你有 64GB 的内存。搞不好也许会降低性能。
文章来源:https://soulogic.com/archives/347
http://www.ha97.com/4170.html

MySQL如何避免使用swap

Linux有很多很好的内存、IO调度机制,但是并不会适用于所有场景。对于DBA来说Linux比较让人头疼的一个地方是,它不会因为MySQL很重要就避免将分配给MySQL的地址空间映射到swap上。对于频繁进行读写操作的系统而言,数据看似在内存而实际上在磁盘是非常糟糕的,响应时间的增长很可能直接拖垮整个系统。这篇blog主要讲讲我们作为DBA,怎样尽量避免MySQL惨遭swap的毒手。

首先我们要了解点基础的东西,比如说为什么会产生swap。假设我们的物理内存是16G,swap是4G。如果MySQL本身已经占用了12G物理内存,而同时其他程序或者系统模块又需要6G内存,这时候操作系统就可能把MySQL所拥有的一部分地址空间映射到swap上去。

cp一个大文件,或用mysqldump导出一个很大的数据库的时候,文件系统往往会向Linux申请大量的内存作为cache,一不小心就会导致L使用swap。这个情景比较常见,以下是最简单的三个调整方法:
1、/proc/sys/vm/swappiness的内容改成0(临时),/etc/sysctl.conf上添加vm.swappiness=0(永久)
这个参数决定了Linux是倾向于使用swap,还是倾向于释放文件系统cache。在内存紧张的情况下,数值越低越倾向于释放文件系统cache。
当然,这个参数只能减少使用swap的概率,并不能避免Linux使用swap。
2、修改MySQL的配置参数innodb_flush_method,开启O_DIRECT模式。
这种情况下,InnoDB的buffer pool会直接绕过文件系统cache来访问磁盘,但是redo log依旧会使用文件系统cache。值得注意的是,Redo log是覆写模式的,即使使用了文件系统的cache,也不会占用太多。
3、添加MySQL的配置参数memlock
这个参数会强迫mysqld进程的地址空间一直被锁定在物理内存上,对于os来说是非常霸道的一个要求。必须要用root帐号来启动MySQL才能生效。

4、还有一个比较复杂的方法,指定MySQL使用大页内存(Large Page)。Linux上的大页内存是不会被换出物理内存的,和memlock有异曲同工之妙。具体的配置方法可以参考:http://harrison-fisk.blogspot.com/2009/01/enabling-innodb-large-pages-on-linux.html

以上介绍了MySQL如何避免使用swap的四个方法。这里需要补充一下原理和实现机制,对于Linux api不感兴趣的同学可以直接跳过。
一、操作系统设置swap的目的
程序运行的一个必要条件就是足够的内存,而内存往往是系统里面比较紧张的一种资源。为了满足更多程序的要求,操作系统虚拟了一部分内存地址,并将之映射到swap上。对于程序来说,它只知道操作系统给自己分配了内存地址,但并不清楚这些内存地址到底映射到物理内存还是swap。
物理内存和swap在功能上是一样的,只是因为物理存储元件的不同(内存和磁盘),性能上有很大的差别。操作系统会根据程序使用内存的特点进行换入和换出,尽可能地把物理内存留给最需要它的程序。但是这种调度是按照预先设定的某种规则的,并不能完全符合程序的需要。一些特殊的程序(比如MySQL)希望自己的数据永远寄存在物理内存里,以便提供更高的性能。于是操作系统就设置了几个api,以便为调用者提供“特殊服务”。

二、Linux提供的几个api
1、mlockall()和munlockall()
这一对函数,可以让调用者的地址空间常驻物理内存,也可以在需要的时候将此特权取消。mlockall()的flag位可以是MCL_CURRENT和MCL_FUTURE的任意组合,分别代表了“保持已分配的地址空间常驻物理内存”和“保持未来分配的地址空间常驻物理内存”。对于Linux来说,这对函数是非常霸道的,只有root用户才有权限调用。

2、shmget()和shmat()
这一对函数,可以向操作系统申请使用大页内存(Large Page)。大页内存的特点是预分配和永驻物理内存,因为使用了共享内存段的方式,page table有可能会比传统的小页分配方式更小。对于多进程共享内存的程序(比如ORACLE),大页内存能够节省很多page table开销;而对于MySQL来说,性能和资源开销都没有显著变化,好处就在于减少了内存地址被映射到swap上的可能。至于为什么是减少,而不是完全避免,之后再讲解。

3、O_DIRECT和posix_memalign()
以上两个方法都不会减少内存的使用量,调用者的本意是获取更高的系统特权,而不是节约系统资源。O_DIRECT是一种更加理想化的方式,通过避免double buffer,节省了文件系统cache的开销,最终减少swap的使用率。O_DIRECT是Linux IO调度相关的标志,在open函数里面调用。通过O_DIRECT标志打开的文件,读写都不会用到文件系统的cache。传统的数据库(ORACLE、MySQL)基本都有O_DIRECT相关的开关,在提高性能的同时,也减少了内存的使用。至于posix_memalign(),是用来申请对齐的内存地址的。只有用posix_memalign()申请的内存地址,才能用来读写O_DIRECT模式下的文件描述符。

4、madvise()和fadvise()
这对函数也是比较温和的,可以将调用者对数据访问模式的预期传递给Linux,以期得到更好的性能。
我们比较感兴趣的是MADV_DONTNEED和FADV_NOREUSE这两个flag。前者会建议Linux释放指定的内存区域,而后者会建议文件系统释放指定文件所占用的cache。

三、MySQL内存使用相关的一些代码
1、memlock
在MySQL的源码目录里面查询memlock,可以知道这个参数的作用是使MySQL调用mlockall()。在源码里面匹配可以得知NDB、MyISAM和mysqld都调用了mlockall()。NDB是可以独立于MySQL而存在的存储引擎,此处按下不表。mysqld调用mlockall()的方式有点出乎意料,在init_server_components()函数里传给mlockall()的flag是MCL_CURRENT,也就是说之后申请的内存一概不用锁住。再看看MyISAM的调用顺序是:mlockall() <- lock_memory() http://www.taobaodba.com/html/552_mysql_avoid_swap.html
http://www.taobaodba.com/html/554_mysql_avoid_swap_2.html

CentOS源码编译安装MySQL 5.5.15

安装编译工具

  1. yum install gcc gcc-c++
  2. yum install ncurses-devel

下载源码

  1. mkdir -p /tmp
  2. cd /tmp
  3. wget http://dev.mysql.com/get/Downloads/MySQL-5.5/mysql-5.5.15.tar.gz/from/http://mysql.he.net/
  4. wget http://www.cmake.org/files/v2.8/cmake-2.8.4.tar.gz
  5. wget http://ftp.gnu.org/gnu/bison/bison-2.5.tar.gz

安装cmake和bison

  1. cd /tmp
  2. tar zxvf cmake-2.8.4.tar.gz
  3. cd cmake-2.8.4
  4. ./bootstrap
  5. make
  6. make install
  1. cd /tmp
  2. tar zxvf bison-2.5.tar.gz
  3. cd bison-2.5
  4. ./configure
  5. make
  6. make install

编译安装MySQL

  1. /usr/sbin/groupadd mysql
  2. /usr/sbin/useradd -g mysql mysql
  3. cd /tmp
  4. tar xvf mysql-5.5.15.tar.gz
  5. cd mysql-5.5.15/
  6. cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql
  7. -DMYSQL_UNIX_ADDR=/tmp/mysql.sock
  8. -DDEFAULT_CHARSET=utf8
  9. -DDEFAULT_COLLATION=utf8_general_ci
  10. -DWITH_EXTRA_CHARSETS=all
  11. -DWITH_MYISAM_STORAGE_ENGINE=1
  12. -DWITH_INNOBASE_STORAGE_ENGINE=1
  13. -DWITH_MEMORY_STORAGE_ENGINE=1
  14. -DWITH_READLINE=1
  15. -DENABLED_LOCAL_INFILE=1
  16. -DMYSQL_DATADIR=/var/mysql/data
  17. -DMYSQL_USER=mysql
  18.  
  19. make
  20. make install

详细编译参数参考:http://dev.mysql.com/doc/refman/5.5/en/source-configuration-options.html

一些相关设置

  1. chmod +w /usr/local/mysql
  2. chown -R mysql:mysql /usr/local/mysql
  3. ln -s /usr/local/mysql/lib/libmysqlclient.so.16 /usr/lib/libmysqlclient.so.16
  4. mkdir -p /var/mysql/
  5. mkdir -p /var/mysql/data/
  6. mkdir -p /var/mysql/log/
  7. chown -R mysql:mysql /var/mysql/
  8. cd support-files/
  9. cp my-large.cnf /var/mysql/my.cnf
  10. cp mysql.server /etc/rc.d/init.d/mysqld
  11.  
  12. /usr/local/mysql/scripts/mysql_install_db
  13. –defaults-file=/var/mysql/my.cnf
  14. –basedir=/usr/local/mysql
  15. –datadir=/var/mysql/data
  16. –user=mysql
  17.  
  18. chmod +x /etc/init.d/mysqld
  1. vi /etc/init.d/mysqld(编辑此文件,查找并修改以下变量内容:)
  2. basedir=/usr/local/mysql
  3. datadir=/var/mysql/data

加入启动项:

  1. chkconfig –add mysqld
  2. chkconfig –level 345 mysqld on

启动服务:

  1. service mysqld start

设置密码:

  1. /usr/local/mysql/bin/mysqladmin password [new-password]

error while loading shared libraries: libmysqlclient.so.15: cannot open shared object file

今天编译安装LAMP,运行mysql命令时出现error while loading shared libraries: libmysqlclient.so.15: cannot open shared object file,在其它机子上安装又没问题,不明白这次有问题。下面是解决方法。
首先确定 libmysqlclient.so.15确实存在,出现这种错误可能是没有装载上。通过下列方法解决。
通过ldconfig注册即可
ldconfig /usr/local/mysql/lib/mysql/libmysqlclient.so.15

CentOS 5 RPM安装MySQL 5.5.14

下载所需RPM软件包

http://dev.mysql.com/downloads/mysql/5.5.html#downloads找到所需的RPM包。
所需的RPM包如下

  • Server
  • Client
  • Shared libraries
  • Headers and libraries

以CentOS 5 32位为例,我们需要下载如下RPM包及依赖。

  1. wget http://dev.mysql.com/get/Downloads/MySQL-5.5/MySQL-server-5.5.14-1.rhel5.i386.rpm/from/http://mysql.he.net/
  2. wget http://dev.mysql.com/get/Downloads/MySQL-5.5/MySQL-client-5.5.14-1.rhel5.i386.rpm/from/http://mysql.he.net/
  3. wget http://dev.mysql.com/get/Downloads/MySQL-5.5/MySQL-shared-5.5.14-1.rhel5.i386.rpm/from/http://mysql.he.net/
  4. wget http://dev.mysql.com/get/Downloads/MySQL-5.5/MySQL-devel-5.5.14-1.rhel5.i386.rpm/from/http://mysql.he.net/
  5. wget ftp://ftp.sunet.se/pub/Linux/distributions/redhat/redhat-archive/redhat/linux/9/en/os/i386/RedHat/RPMS/libaio-0.3.93-4.i386.rpm

安装软件

  1. rpm -ivh libaio-0.3.93-4.i386.rpm
  2. rpm -ivh MySQL-server-5.5.14-1.rhel5.i386.rpm
  3. rpm -ivh MySQL-client-5.5.14-1.rhel5.i386.rpm
  4. rpm -ivh MySQL-shared-5.5.14-1.rhel5.i386.rpm
  5. rpm -ivh MySQL-devel-5.5.14-1.rhel5.i386.rpm

启动MySQL服务器并设置密码

  1. service mysql start
  2. mysql_secure_installation

MySQL常用命令大全

下面是我们经常会用到且非常有用的MySQL命令。下面你看到#表示在Unix命令行下执行命令,看到mysql>表示当前已经登录MySQL服务器,是在mysql客户端执行mysql命令。
登录MySQL,如果连接远程数据库,需要用-h指定hostname。

  1. # [mysql dir]/bin/mysql -h hostname -u root -p

创建一个数据库。

  1. mysql> create database [databasename];

列出所有数据库。

  1. mysql> show databases;

切换到一个数据库。

  1. mysql> use [db name];

显示一个数据库的所有表。

  1. mysql> show tables;

查看数据表的字段格式。

  1. mysql> describe [table name];

删除一个数据库。

  1. mysql> drop database [database name];

删除一个数据表。

  1. mysql> drop table [table name];

显示一个数据表的所有数据。

  1. mysql> SELECT * FROM [table name];

返回指定数据表的各列信息。

  1. mysql> show columns from [table name];

使用值“whatever”过滤显示选定的某些行。

  1. mysql> SELECT * FROM [table name] WHERE [field name] = "whatever";

显示所有包含name为”Bob”和phone number为“3444444”的记录。

  1. mysql> SELECT * FROM [table name] WHERE name = "Bob" AND phone_number = ‘3444444’;

显示所有不包含name为”Bob”和phone number为“3444444”的记录,并以phone_number字段排序。

  1. mysql> SELECT * FROM [table name] WHERE name != "Bob" AND phone_number = ‘3444444’ order by phone_number;

显示所有的name以字母“bob”开头和phone number为“3444444”的记录。

  1. mysql> SELECT * FROM [table name] WHERE name like "Bob%" AND phone_number = ‘3444444’;

显示name以字母“bob”开头和phone number为“3444444”的第1至第5条记录。

  1. mysql> SELECT * FROM [table name] WHERE name like "Bob%" AND phone_number = ‘3444444’ limit 1,5;

使用正则表达式查找记录。使用“正则表达式二进制”强制区分大小写。此命令查找以a开头的任何记录。

  1. mysql> SELECT * FROM [table name] WHERE rec RLIKE "^a";

返回唯一不同的记录。

  1. mysql> SELECT DISTINCT [column name] FROM [table name];

以升序或降序显示选定的记录。

  1. mysql> SELECT [col1],[col2] FROM [table name] ORDER BY [col2] DESC;

返回行数。

  1. mysql> SELECT COUNT(*) FROM [table name];

统计指定列值的总和。

  1. mysql> SELECT SUM(*) FROM [table name];

联结表。

  1. mysql> select lookup.illustrationid, lookup.personid,person.birthday from lookup left join person on lookup.personid=person.personid=statement to join birthday in person table with primary illustration id;

新建一个用户。以root登录。切换到mysql数据库,创建用户,刷新权限。

  1. # mysql -u root -p
  2. mysql> use mysql;
  3. mysql> INSERT INTO user (Host,User,Password) VALUES(‘%’,’username’,PASSWORD(‘password’));
  4. mysql> flush privileges;

从unix命令行更改用户密码。

  1. # [mysql dir]/bin/mysqladmin -u username -h hostname.blah.org -p password ‘new-password’

从mysql命令行更改用户密码。以root登录,设置密码,更新权限。

  1. # /etc/init.d/mysql stop
  2. # mysqld_safe –skip-grant-tables &
  3. # mysql -u root
  4. mysql> use mysql;
  5. mysql> update user set password=PASSWORD("newrootpassword") where User=’root’;
  6. mysql> flush privileges;
  7. mysql> quit
  8. # /etc/init.d/mysql stop
  9. # /etc/init.d/mysql start

root密码为空时,设置root密码。

  1. # mysqladmin -u root password newpassword

更新root密码。

  1. # mysqladmin -u root -p oldpassword newpassword

允许用户“bob”从localhost以密码“passwd”连接服务器。以root登录,切换mysql数据库。设置权限,更新权限。

  1. # mysql -u root -p
  2. mysql> use mysql;
  3. mysql> grant usage on *.* to bob@localhost identified by ‘passwd’;
  4. mysql> flush privileges;

为数据库db设置权限。以root登录,切换到mysql数据库,授予权限,更新权限。

  1. # mysql -u root -p
  2. mysql> use mysql;
  3. mysql> INSERT INTO db (Host,Db,User,Select_priv,Insert_priv,Update_priv,Delete_priv,Create_priv,Drop_priv) VALUES (‘%’,’databasename’,’username’,’Y’,’Y’,’Y’,’Y’,’Y’,’N’);
  4. mysql> flush privileges;

或者

  1. mysql> grant all privileges on databasename.* to username@localhost;
  2. mysql> flush privileges;

更新已存在表的数据。

  1. mysql> UPDATE [table name] SET Select_priv = ‘Y’,Insert_priv = ‘Y’,Update_priv = ‘Y’ where [field name] = ‘user’;

删除表中[field name] = ‘whatever’的行。

  1. mysql> DELETE from [table name] where [field name] = ‘whatever’;

更新数据库的权限/特权。

  1. mysql> flush privileges;

删除列。

  1. mysql> alter table [table name] drop column [column name];

新增列到db。

  1. mysql> alter table [table name] add column [new column name] varchar (20);

更改列名。

  1. mysql> alter table [table name] change [old column name] [new column name] varchar (50);

增加唯一的列。

  1. mysql> alter table [table name] add unique ([column name]);

设置列值大点。

  1. mysql> alter table [table name] modify [column name] VARCHAR(3);

删除唯一列。

  1. mysql> alter table [table name] drop index [colmn name];

导入一个CSV文件到表。

  1. mysql> LOAD DATA INFILE ‘/tmp/filename.csv’ replace INTO TABLE [table name] FIELDS TERMINATED BY ‘,’ LINES TERMINATED BY ‘n’ (field1,field2,field3);

导出所有数据库到sql文件。

  1. # [mysql dir]/bin/mysqldump -u root -ppassword –opt >/tmp/alldatabases.sql

导出一个数据库。

  1. # [mysql dir]/bin/mysqldump -u username -ppassword –databases databasename >/tmp/databasename.sql

从一个数据库导出一个表。

  1. # [mysql dir]/bin/mysqldump -c -u username -ppassword databasename tablename > /tmp/databasename.tablename.sql

从sql文件还原数据库(数据表)。

  1. # [mysql dir]/bin/mysql -u username -ppassword databasename < /tmp/databasename.sql

创建数据表例1。

  1. mysql> CREATE TABLE [table name] (firstname VARCHAR(20), middleinitial VARCHAR(3), lastname VARCHAR(35),suffix VARCHAR(3),officeid VARCHAR(10),userid VARCHAR(15),username VARCHAR(8),email VARCHAR(35),phone VARCHAR(25), groups VARCHAR(15),datestamp DATE,timestamp time,pgpemail VARCHAR(255));

创建数据表例2。

  1. mysql> create table [table name] (personid int(50) not null auto_increment primary key,firstname varchar(35),middlename varchar(50),lastnamevarchar(50) default ‘bato’);

Linux MySQL主从复制(Replication)(MySQL数据同步)配置

当我们要做负载均衡的时候,我们必须考虑三个问题:
1、智能DNS的使用;
智能DNS我们可以用DNSPod来解决,看这篇文章:怎样用DNSPod做负载均衡
2、文件的同步;
而文件的同步可以通过rsync软件来解决,看这篇文章:rsync服务器架设
3、MySQL数据库的同步。
剩下是MySQL数据库的同步了,这节我们就来解决这个问题。
继续阅读Linux MySQL主从复制(Replication)(MySQL数据同步)配置