CentOS 7源码编译安装mysql 5.7

安装约定

mysql安装路径:/usr/local/mysql
mysql数据库路径: /data/mysql
mysql配置文件路径:/usr/local/mysql/my.cnf

卸载mariadb

# rpm -qa | grep mariadb
# rpm -e --nodeps mariadb-libs-5.5.37-1.el7_0.x86_64  Packet name is the last query that 

用户组和用户创建

创建用户组

groupadd mysql

创建用户

useradd -g mysql mysql -s / bin / false

下载源码软件包

Http://dev.mysql.com/downloads/mysql/5.7.html#downloads
Http://download.savannah.gnu.org/releases/libunwind/
Https://github.com/gperftools/gperftools/releases

# cd /usr/local/src/
# wget http://download.savannah.gnu.org/releases/libunwind/libunwind-1.1.tar.gz
# wget http://gperftools.googlecode.com/files/gperftools-2.5.tar.gz
# wget http://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.x.tar.gz

安装libunwind

# tar zxvf libunwind-1.1.tar.gz
# cd libunwind-1.1
# ./configure
# make
# make install

安装gperftools

# cd ..
# tar zxvf gperftools-2.1.tar.gz
# cd gperftools-2.1
# ./configure
# make
# make install
# echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
# ldconfig

安装mysql

# cd ..
# tar zxvf mysql-5.7.x.tar.gz
# cd mysql-5.7.x

在编译之前,使用如下命令来查看可用的编译参数描述

# cmake . -LH | more

如果编译出现错误,删除CMakeCache.txt重新编译

rm -rf CMakeCache.txt

开始编译:

# cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql 
 -DMYSQL_DATADIR=/data/mysql 
 -DSYSCONFDIR=/etc 
 -DEXTRA_CHARSETS=all 
 -DDEFAULT_CHARSET=utf8 
 -DDEFAULT_COLLATION=utf8_general_ci 
 -DWITH_INNOBASE_STORAGE_ENGINE=1 
 -DENABLED_LOCAL_INFILE=1 
 -DMYSQL_UNIX_ADDR=/dev/shm/mysql.sock 
 -DMYSQL_TCP_PORT=3306 
 -DMYSQL_USER=mysql 
 -DWITH_DEBUG=0 
 -DDOWNLOAD_BOOST=1 
 -DWITH_BOOST=/usr/local/boost
# make
# make install
 ```

  change permission 
 ```
# chmod 755 /var/lib/mysql
# cd /usr/local/mysql
# chown -R mysql:mysql .

初始化mysql

/usr/local/mysql/bin/mysqld --initialize --basedir=/usr/local/mysql --datadir=/data/mysql --user=mysql --explicit_defaults_for_timestamp=1

创建一个mysql配置文件

# cp support-files/my-default.cnf /usr/local/mysql/my.cnf

MySQL性能调优 – 你必须了解的15个重要变量

1.DEFAULT_STORAGE_ENGINE

如果你已经在用MySQL 5.6或者5.7,并且你的数据表都是InnoDB,那么表示你已经设置好了。如果没有,确保把你的表转换为InnoDB并且设置default_storage_engine为InnoDB。
为什么?简而言之,因为InnoDB是MySQL(包括Percona Server和MariaDB)最好的存储引擎 – 它支持事务,高并发,有着非常好的性能表现(当配置正确时)。这里有详细的版本介绍为什么

2.INNODB_BUFFER_POOL_SIZE

这个是InnoDB最重要变量。实际上,如果你的主要存储引擎是InnoDB,那么对于你,这个变量对于MySQL是最重要的。
基本上,innodb_buffer_pool_size指定了MySQL应该分配给InnoDB缓冲池多少内存,InnoDB缓冲池用来存储缓存的数据,二级索引,脏数据(已经被更改但没有刷新到硬盘的数据)以及各种内部结构如自适应哈希索引。
根据经验,在一个独立的MySQL服务器应该分配给MySQL整个机器总内存的80%。如果你的MySQL运行在一个共享服务器,或者你想知道InnoDB缓冲池大小是否正确设置,详细请看这里

3.INNODB_LOG_FILE_SIZE

InnoDB重做日志文件的设置在MySQL社区也叫做事务日志。直到MySQL 5.6.8事务日志默认值innodb_log_file_size=5M是唯一最大的InnoDB性能杀手。从MySQL 5.6.8开始,默认值提升到48M,但对于许多稍繁忙的系统,还远远要低。
根据经验,你应该设置的日志大小能在你服务器繁忙时能存储1-2小时的写入量。如果不想这么麻烦,那么设置1-2G的大小会让你的性能有一个不错的表现。这个变量也相当重要,更详细的介绍请看这里
在进入下一个变量之前,让我们来快速提及一下innodb_log_buffer_size。“快速提及”是因为它常常不好理解并且往往被过度关注了。事实上大多数情况下你只需要使用小的缓冲 – 在事务被提交并写入到硬盘前足够保存你的小事务更改了。
当然,如果你有大量的大事务更改,那么,更改比默认innodb日志缓冲大小更大的值会对你的性能有一定的提高,但是你使用的是autocommit,或者你的事务更改小于几k,那还是保持默认的值吧。

4.INNODB_FLUSH_LOG_AT_TRX_COMMIT

默认下,innodb_flush_log_at_trx_commit设置为1表示InnoDB在每次事务提交后立即刷新同步数据到硬盘。如果你使用autocommit,那么你的每一个INSERT, UPDATE或DELETE语句都是一个事务提交。
同步是一个昂贵的操作(特别是当你没有写回缓存时),因为它涉及对硬盘的实际同步物理写入。所以如果可能,并不建议使用默认值。
两个可选的值是0和2:
* 0表示刷新到硬盘,但不同步(提交事务时没有实际的IO操作)
* 2表示不刷新和不同步(也没有实际的IO操作)
所以你如果设置它为0或2,则同步操作每秒执行一次。所以明显的缺点是你可能会丢失上一秒的提交数据。具体来说,你的事务已经提交了,但服务器马上断电了,那么你的提交相当于没有发生过。
显示的,对于金融机构,如银行,这是无法忍受的。不过对于大多数网站,可以设置为innodb_flush_log_at_trx_commit=0|2,即使服务器最终崩溃也没有什么大问题。毕竟,仅仅在几年前有许多网站还是用MyISAM,当崩溃时会丢失30s的数据(更不要提那令人抓狂的慢修复进程)。
那么,0和2之间的实际区别是什么?性能明显的差异是可以忽略不计,因为刷新到操作系统缓存的操作是非常快的。所以很明显应该设置为0,万一MySQL崩溃(不是整个机器),你不会丢失任何数据,因为数据已经在OS缓存,最终还是会同步到硬盘的。

5.SYNC_BINLOG

已经有大量的文档写到sync_binlog,以及它和innodb_flush_log_at_trx_commit的关系,下面我们来简单的介绍下:
a) 如果你的服务器没有设置从服务器,而且你不做备份,那么设置sync_binlog=0将对性能有好处。
b) 如果你有从服务器并且做备份,但你不介意当主服务器崩溃时在二进制日志丢失一些事件,那么为了更好的性能还是设置为sync_binlog=0.
c) 如果你有从服务器并且备份,你非常在意从服务器的一致性,以及能及时恢复到一个时间点(通过使用最新的一致性备份和二进制日志将数据库恢复到特定时间点的能力),那么你应该设置innodb_flush_log_at_trx_commit=1,并且需要认真考虑使用sync_binlog=1。
问题是sync_binlog=1代价比较高 – 现在每个事务也要同步一次到硬盘。你可能会想为什么不把两次同步合并成一次,想法正确 – 新版本的MySQL(5.6和5.7,MariaDB和Percona Server)已经能合并提交,那么在这种情况下sync_binlog=1的操作也不是这么昂贵了,但在旧的mysql版本中仍然会对性能有很大影响。

6.INNODB_FLUSH_METHOD

将innodb_flush_method设置为O_DIRECT以避免双重缓冲.唯一一种情况你不应该使用O_DIRECT是当你操作系统不支持时。但如果你运行的是Linux,使用O_DIRECT来激活直接IO。
不用直接IO,双重缓冲将会发生,因为所有的数据库更改首先会写入到OS缓存然后才同步到硬盘 – 所以InnoDB缓冲池和OS缓存会同时持有一份相同的数据。特别是如果你的缓冲池限制为总内存的50%,那意味着在写密集的环境中你可能会浪费高达50%的内存。如果没有限制为50%,服务器可能由于OS缓存的高压力会使用到swap。
简单地说,设置为innodb_flush_method=O_DIRECT。

7.INNODB_BUFFER_POOL_INSTANCES

MySQL 5.5引入了缓冲实例作为减小内部锁争用来提高MySQL吞吐量的手段。
在5.5版本这个对提升吞吐量帮助很小,然后在MySQL 5.6版本这个提升就非常大了,所以在MySQL5.5中你可能会保守地设置innodb_buffer_pool_instances=4,在MySQL 5.6和5.7中你可以设置为8-16个缓冲池实例。
你设置后观察会觉得性能提高不大,但在大多数高负载情况下,它应该会有不错的表现。
对了,不要指望这个设置能减少你单个查询的响应时间。这个是在高并发负载的服务器上才看得出区别。比如多个线程同时做许多事情。

8.INNODB_THREAD_CONCURRENCY

你可能会经常听到应该设置innodb_thread_concurrency=0然后就不要管它了。不过这个只在低负载服务器使用时才正确。然后,如果你的服务器的CPU或者IO使用接受饱和,特别是偶尔出现峰值,这时候系统想在超载时能正常处理查询,那么强烈建议关注innodb_thread_concurrency。
InnoDB有一种方法来控制并行执行的线程数 – 我们称为并发控制机制。大部分是由innodb_thread_concurrency值来控制的。如果设置为0,并发控制就关闭了,因此InnoDB会立即处理所有进来的请求(尽可能多的)。
在你有32CPU核心且只有4个请求时会没什么问题。不过想像下你只有4CPU核心和32个请求时 – 如果你让32个请求同时处理,你这个自找麻烦。因为这些32个请求只有4 CPU核心,显然地会比平常慢至少8倍(实际上是大于8倍),而然这些请求每个都有自己的外部和内部锁,这有很大可能堆积请求。
下面介绍如何更改这个变量,在mysql命令行提示符执行:

  1. SET global innodb_thread_concurrency=X;

对于大多数工作负载和服务器,设置为8是一个好开端,然后你可以根据服务器达到了这个限制而资源使用率利用不足时逐渐增加。可以通过show engine innodb statusG来查看目前查询处理情况,查找类似如下行:

  1. 22 queries inside InnoDB, 104 queries in queue

9.SKIP_NAME_RESOLVE

这一项不得不提及,因为仍然有很多人没有添加这一项。你应该添加skip_name_resolve来避免连接时DNS解析。
大多数情况下你更改这个会没有什么感觉,因为大多数情况下DNS服务器解析会非常快。不过当DNS服务器失败时,它会出现在你服务器上出现“unauthenticated connections” ,而就是为什么所有的请求都突然开始慢下来了。
所以不要等到这种事情发生才更改。现在添加这个变量并且避免基于主机名的授权。

10.INNODB_IO_CAPACITY, INNODB_IO_CAPACITY_MAX

* innodb_io_capacity:用来当刷新脏数据时,控制MySQL每秒执行的写IO量。
* innodb_io_capacity_max: 在压力下,控制当刷新脏数据时MySQL每秒执行的写IO量
首先,这与读取无关 – SELECT查询执行的操作。对于读操作,MySQL会尽最大可能处理并返回结果。至于写操作,MySQL在后台会循环刷新,在每一个循环会检查有多少数据需要刷新,并且不会用超过innodb_io_capacity指定的数来做刷新操作。这也包括更改缓冲区合并(在它们刷新到磁盘之前,更改缓冲区是辅助脏页存储的关键)。
第二,我需要解释一下什么叫“在压力下”,MySQL中称为”紧急情况”,是当MySQL在后台刷新时,它需要刷新一些数据为了让新的写操作进来。然后,MySQL会用到innodb_io_capacity_max。
那么,应该设置innodb_io_capacity和innodb_io_capacity_max为什么呢?
最好的方法是测量你的存储设置的随机写吞吐量,然后给innodb_io_capacity_max设置为你的设备能达到的最大IOPS。innodb_io_capacity就设置为它的50-75%,特别是你的系统主要是写操作时。
通常你可以预测你的系统的IOPS是多少。例如由8 15k硬盘组成的RAID10能做大约每秒1000随机写操作,所以你可以设置innodb_io_capacity=600和innodb_io_capacity_max=1000。许多廉价企业SSD可以做4,000-10,000 IOPS等。
这个值设置得不完美问题不大。但是,要注意默认的200和400会限制你的写吞吐量,因此你可能偶尔会捕捉到刷新进程。如果出现这种情况,可能是已经达到你硬盘的写IO吞吐量,或者这个值设置得太小限制了吞吐量。

11.INNODB_STATS_ON_METADATA

如果你跑的是MySQL 5.6或5.7,你不需要更改innodb_stats_on_metadata的默认值,因为它已经设置正确了。
不过在MySQL 5.5或5.1,强烈建议关闭这个变量 – 如果是开启,像命令show table status会立即查询INFORMATION_SCHEMA而不是等几秒再执行,这会使用到额外的IO操作。
从5.1.32版本开始,这个是动态变量,意味着你不需要重启MySQL服务器来关闭它。

12.INNODB_BUFFER_POOL_DUMP_AT_SHUTDOWN & INNODB_BUFFER_POOL_LOAD_AT_STARTUP

innodb_buffer_pool_dump_at_shutdown和innodb_buffer_pool_load_at_startup这两个变量与性能无关,不过如果你偶尔重启mysql服务器(如生效配置),那么就有关。当两个都激活时,MySQL缓冲池的内容(更具体地说,是缓存页)在停止MySQL时存储到一个文件。当你下次启动MySQL时,它会在后台启动一个线程来加载缓冲池的内容以提高预热速度到3-5倍。
两件事:
第一,它实际上没有在关闭时复制缓冲池内容到文件,仅仅是复制表空间ID和页面ID – 足够的信息来定位硬盘上的页面了。然后它就能以大量的顺序读非常快速的加载那些页面,而不是需要成千上万的小随机读。
第二,启动时是在后台加载内容,因为MySQL不需要等到缓冲池内容加载完成再开始接受请求(所以看起来不会有什么影响)。
从MySQL 5.7.7开始,默认只有25%的缓冲池页面在mysql关闭时存储到文件,但是你可以控制这个值 – 使用innodb_buffer_pool_dump_pct,建议75-100。
这个特性从MySQL 5.6才开始支持。

13.INNODB_ADAPTIVE_HASH_INDEX_PARTS

如果你运行着一个大量SELECT查询的MySQL服务器(并且已经尽可能优化),那么自适应哈希索引将下你的下一个瓶颈。自适应哈希索引是InnoDB内部维护的动态索引,可以提高最常用的查询模式的性能。这个特性可以重启服务器关闭,不过默认下在mysql的所有版本开启。
这个技术非常复杂,在大多数情况下它会对大多数类型的查询直到加速的作用。不过,当你有太多的查询往数据库,在某一个点上它会花过多的时间等待AHI锁和闩锁。
如果你的是MySQL 5.7,没有这个问题 – innodb_adaptive_hash_index_parts默认设置为8,所以自适应哈希索引被切割为8个分区,因为不存在全局互斥。
不过在mysql 5.7前的版本,没有AHI分区数量的控制。换句话说,有一个全局互斥锁来保护AHI,可能导致你的select查询经常撞墙。
所以如果你运行的是5.1或5.6,并且有大量的select查询,最简单的方案就是切换成同一版本的Percona Server来激活AHI分区。

14.QUERY_CACHE_TYPE

如果人认为查询缓存效果很好,肯定应该使用它。好吧,有时候是有用的。不过这个只在你在低负载时有用,特别是在低负载下大多数是读取,小量写或者没有。
如果是那样的情况,设置query_cache_type=ON和query_cache_size=256M就好了。不过记住不能把256M设置更高的值了,否则会由于查询缓存失效时,导致引起严重的服务器停顿。
如果你的MySQL服务器高负载动作,建议设置query_cache_size=0和query_cache_type=OFF,并重启服务器生效。那样Mysql就会停止在所有的查询使用查询缓存互斥锁。

15.TABLE_OPEN_CACHE_INSTANCES

从MySQL 5.6.6开始,表缓存能分割到多个分区。
表缓存用来存放目前已打开表的列表,当每一个表打开或关闭互斥体就被锁定 – 即使这是一个隐式临时表。使用多个分区绝对减少了潜在的争用。
从MySQL 5.7.8开始,table_open_cache_instances=16是默认的配置。

INNODB_LOG_FILE_SIZE:设置MySQL重做日志大小

什么是InnoDB事务日志

你有没有在文本编辑器中使用过撤消或重做的功能,想像一下编辑器在那种场景下的操作?我确信你应该使用过。你相信吗?事务型数据库有同样的功能。可能不完全一样,但原理是相同的。
就像当你编辑文字时始终有能力撤消数步的重要性一样,重做和撤消功能也对事务型数据一样重要。为什么呢?主要有两个原因:
1.回滚事务(那是撤消)
2.在数据库崩溃的情况下回放已提交的事务(那是重做)

撤消

当你使用的是事务存储引擎(假设是InnoDB),你更改一个记录时,更改并没有马上写入数据文件。
首先,它们被写入到一个硬盘上特定的文件叫做事务日志。同时,它们也更改了内存 – InnoDB缓冲池。现在新InnoDB页面包含了已更改的记录叫脏数据。
被复制到硬盘上特别区域的原始未被更改的页面叫做回滚段。
如果有人在提交之前使用ROLLBACK中断了一个事务,撤消操作就发生了 – 你的记录已经被还原到原始状态。
由于更改还没有被写入到数据文件,这个操作相当简单 – InnoDB仅仅需要从回滚段中提取旧页面,从内存中擦除脏页,并在事务日志中标记那个事务已经回滚。
所以你看,数据文件从没有被更改,因为在执行随机写操作以把脏数据刷新到硬盘之前你已经把所有更改取消了。

重做

当你提交事务,然后InnoDB确认你的提交,更改准备写入到实际的数据文件。
现在你认为它们会被马上写入到硬盘的数据文件,事实上不是这样的。为什么?因为这样做效率非常低。反而,更改仅仅被写入到事务日志(因为是顺序写,速度会很快,称为重做日志记录),而更改的记录仍然在日志中 – InnoDB缓冲池的脏页,过一定的时间才刷新到硬盘。
这时候MySQL崩溃了!
猜猜MySQL会怎样做?
如果MySQL(实际上是InnoDB)没有重做日志,仅仅是保留了脏页在内存中 – 所有未被刷新到硬盘已提交的事务将会永久丢失。
幸运的是,所以的更改总会写入到事务日志,
所以InnoDB需要做的就是在重做日志中找到上一次的checkpoint(已同步数据到硬盘的位置),然后重做未同步到硬盘已提交的事务。

日志大小

你可能想知道的一个事就是如何正确设置innodb_log_file_size的大小。规则很简单:
* 小日志文件使写入速度更慢,崩溃恢复速度更快
* 大日志文件使写入更快,崩溃恢复速度更慢
由于事务日志相当于一个写缓冲,而小日志文件会很快的被写满,这时候就需要频繁地刷新到硬盘,速度就慢了。如果产生大量的写操作,MySQL可能就不能足够快地刷新数据,那么写性能将会降低。
大的日志文件,另一方面,在刷新操作发生之前给你足够的空间来使用。反过来允许InnoDB填充更多的页面。
对于崩溃恢复 – 大的重做日志意味着在服务器启动前更多的数据需要读取,更多的更改需要重做,这就是为什么崩溃恢复慢了。

重做日志大小

最后,让我们来谈谈如何找出重做日志的正确大小。
幸运的是,你不需要费力算出正确的大小,这里有一个经验法则:
在服务器繁忙期间,检查重做日志的总大小是否够写入1-2小时。
你如何知道InnoDB写入多少,下面有一个方法:

  1. mysql> pager grep seq
  2. mysql> show engine innodb statusG select sleep(60); show engine innodb statusG
  3. Log sequence number 1777308180429
  4. Log sequence number 1777354541591
  5.  
  6. mysql> nopager
  7. mysql> select (1777354541591-1777308180429)*60/1024/1024;
  8. +——————————————–+
  9. | (1777354541591-1777308180429)*60/1024/1024 |
  10. +——————————————–+
  11. |                              2652.80696869 |
  12. +——————————————–+
  13. 1 row in set (0.00 sec)

在这个60s的采样情况下,InnoDB每小时写入2.6GB数据。所以如果innodb_log_files_in_group没有更改(默认是2,是InnoDB重复日志的最小数字),然后设置innodb_log_file_size为2560M,那么你实际上两个日志文件加起来有5GB,够你写两小时数据了。

更改重做日志大小

更改innodb_log_file_size的难易程度和能设置多大取决于你现在使用的MySQL版本。
特别地,如果你使用的是5.6之前的版本,你不能仅仅的更改变量,期望服务器会自动重启。
好了,下面是步骤:
1.在my.cnf更改innodb_log_file_size
2.停止mysql服务器
3.删除旧的日志,通过执行命令rm -f /var/lib/mysql/ib_logfile*
4.启动mysql服务器 – 应该需要比之前长点的时间,因为需要创建新的事务日志。
最后,需要注意的是,有些mysql版本(比如5.6.2)限制了重做日志大小为4GB。所以在你设置innodb_log_file_size为2G或者更多时,请先检查一下MySQL的版本这方面的限制。

INNODB_BUFFER_POOL_SIZE:设置最佳内存值

什么是INNODB BUFFER POOL

计算机使用它们的大部分内存来提升对经常访问的数据的性能。这就是我们所知的缓存,是系统的一个非常重要的组成部分,因为访问硬盘的数据可能会慢到100到100000倍,这取决你访问的数据量。
MyISAM是使用操作系统的文件系统缓存来缓存那些经常被查询的数据。然而InnoDB使用的是一种非常不同的方法。
不依赖操作系统的缓存,InnoDB自己在InnoDB Buffer Pool处理缓存。经过这篇文章你会学到它是如何工作的,为什么以那种方式来实施是一个不错的想法。

InnoDB缓冲池不仅仅是一个缓存

InnoDB缓冲池实际上用于多个目的,它用来:
* 数据缓存 – 这绝对是它的最重要的目的
* 索引缓存 – 这使用是的同一个缓冲池
* 缓冲 – 更改的数据(通常称为脏数据)在被刷新到硬盘之前先存放到缓冲
* 存储内部结构 – 一些结构如自适应哈希索引或者行锁也都存储在InnoDB缓冲池
下面是一个经典的把innodb-buffer-pool-size设置为62G的InnoDB缓冲池页的分布情况:
MySQL
正如你所看到的,Buffer Pool大多是用于普通的InnoDB页面,但大约10%用作其它目的。
这张表的单位是InnoDB页。单个页面大小实际上是16K,所以你可以乘以16,384来得到以字节为单位更直观的使用情况。

InnoDB缓冲池的大小

那么innodb-buffer-pool-size的大小应该设置为什么呢?下面我们就开始谈到这个。

独立服务器

在一个独立的只使用InnoDB引擎的MySQL服务器中,根据经验,推荐设置innodb-buffer-pool-size为服务器总可用内存的80%。
为什么不是90%或者100%呢?
因为其它的东西也需要内存:
* 每个查询至少需要几K的内存(有时候是几M)
* 有各种其它内部的MySQL结构和缓存
* InnoDB有一些结构是不用缓冲池的内存的(字典缓存,文件系统,锁系统和页哈希表等)
* 也有一些MySQL文件是在OS缓存里的(binary日志,relay日志,innodb事务日志等)
* 此处,你也必须为操作系统留出些内存

共享服务器

如果你的MySQL服务器与其它应用共享资源,那么上面80%的经验就不那么适用了。
在这样的环境下,设置一个对的数字有点难度。
首先让我们来统计一下InnoDB表的实际占用大小。执行如下查询:

  1. SELECT engine,
  2.   count(*) as TABLES,
  3.   concat(round(sum(table_rows)/1000000,2),’M’) rows,
  4.   concat(round(sum(data_length)/(1024*1024*1024),2),’G’) DATA,
  5.   concat(round(sum(index_length)/(1024*1024*1024),2),’G’) idx,
  6.   concat(round(sum(data_length+index_length)/(1024*1024*1024),2),’G’) total_size,
  7.   round(sum(index_length)/sum(data_length),2) idxfrac
  8. FROM information_schema.TABLES
  9. WHERE table_schema not in (‘mysql’, ‘performance_schema’, ‘information_schema’)
  10. GROUP BY engine
  11. ORDER BY sum(data_length+index_length) DESC LIMIT 10;

这会给出一个参考,让你知道如果你想缓存整个数据集应该为InnoDB缓冲池设置多少内存合适。
不过大多数情况你不需要那样做,你只需要缓存你经常使用的数据集。
设置好之后,我们来看看如何检查InnoDB缓冲池大小是否设置足够。
在终端中,执行如下命令:

  1. $ mysqladmin ext -ri1 | grep Innodb_buffer_pool_reads
  2. | Innodb_buffer_pool_reads                 | 1832098003     |
  3. | Innodb_buffer_pool_reads                 | 595            |
  4. | Innodb_buffer_pool_reads                 | 915            |
  5. | Innodb_buffer_pool_reads                 | 734            |
  6. | Innodb_buffer_pool_reads                 | 622            |
  7. | Innodb_buffer_pool_reads                 | 710            |
  8. | Innodb_buffer_pool_reads                 | 664            |
  9. | Innodb_buffer_pool_reads                 | 987            |
  10. | Innodb_buffer_pool_reads                 | 1287           |
  11. | Innodb_buffer_pool_reads                 | 967            |
  12. | Innodb_buffer_pool_reads                 | 1181           |
  13. | Innodb_buffer_pool_reads                 | 949            |

你所看到的是从硬盘读取数据到缓冲池的次数(每秒)。上面的数据已经相当高了(幸运的是,这个服务器的IO设备能处理每秒4000的IO操作),如果这个是OLTP系统,我建议提高innodb缓冲池的大小和如果必要增加服务器内存。

更改InnoDB缓冲池

最后,介绍如何更改innodb-buffer-pool-size。
如果你运行的是MySQL 5.7,那么非常幸运,你可以在线更改这个变量,只需要以root身份执行如下查询:

  1. mysql> SET GLOBAL innodb_buffer_pool_size=size_in_bytes;

这还没完,你仍然需要更改my.cnf文件,不过至少你不需要重启服务器让它生效。从mysql的错误日志中我们可以看到它生效的过程:

  1. [Note] InnoDB: Resizing buffer pool from 134217728 to 21474836480. (unit=134217728)
  2. [Note] InnoDB: disabled adaptive hash index.
  3. [Note] InnoDB: buffer pool 0 : 159 chunks (1302369 blocks) were added.
  4. [Note] InnoDB: buffer pool 0 : hash tables were resized.
  5. [Note] InnoDB: Resized hash tables at lock_sys, adaptive hash index, dictionary.
  6. [Note] InnoDB: Completed to resize buffer pool from 134217728 to 21474836480.
  7. [Note] InnoDB: Re-enabled adaptive hash index.

在更早的mysql版本就需要重启了,所以:
1. 在my.cnf中设置一个innodb_buffer_pool_size合适的值
2.重启mysql服务器

DEFAULT_STORAGE_ENGINE:选择正确的MySQL存储引擎

现在让我们把MySQL存储引擎的问题放在一边。如果你的MySQL表都是用的InnoDB而你不需要关心InnoDB是如何运作的,你已经设置了,但不确定是否生效。这些问题将在下面会提到。

关于存储引擎

MySQL自20多年前成立以来一直支持可插拔存储引擎,但在一段相当长的时间里MyISAM一直是默认的存储引擎,许多人运行MySQL甚至对底层存储引擎一点都不了解。毕竟,MySQL刚开始是为小型网站的小型数据库设计的,许多应用已经习惯使用MyISAM存储引擎。

刚开始没什么问题,一切正常,但现在的问题是:MyISAM没有考虑到应用到高并发高负载,多核CPU和RAID阵列的场景,也不能弹性扩展。所以网站流量越来越多后,他们不能扩展,因为MySQL查询会在表级锁上等待数秒(MyISAM只支持这种锁机制)。他们不想每次MySQL崩溃时损坏他们的业务数据。

INNODB存储引擎

许多人并不知道,自MySQL存在以来MyISAM存储引擎就有一个兄弟叫InnoDB。并且高并发负载,性能和弹性(也包括原子性,一致性和隔离)正是它的特长。
当然,在InnoDB发展过程中也有过一些问题(尤其是2006年5.0.30之前的版本的性能问题),但在这之后的10年时间里,InnoDB已经在你能想到的领域(或者没有)得到了证明,而MyISAM已经很少被关注了。
因此,从MySQL 5.5.5开始,InnoDB成为默认的存储引擎,现在你几乎找不到大型MySQL数据库的安装使用MyISAM而不是InnoDB。
下面让我来告诉你如何快速地统计和列出在你系统的所有MyISAM表,方便你开始计划迁移。

你使用的存储引擎

下面的查询展示你所用的存储引擎以及它们的一些统计信息,包括表数量,大小等。

  1. mysql> SELECT engine,
  2.   count(*) as TABLES,
  3.   concat(round(sum(table_rows)/1000000,2),’M’) rows,
  4.   concat(round(sum(data_length)/(1024*1024*1024),2),’G’) DATA,
  5.   concat(round(sum(index_length)/(1024*1024*1024),2),’G’) idx,
  6.   concat(round(sum(data_length+index_length)/(1024*1024*1024),2),’G’) total_size,
  7.   round(sum(index_length)/sum(data_length),2) idxfrac
  8.  FROM information_schema.TABLES
  9. WHERE table_schema not in (‘mysql’, ‘performance_schema’, ‘information_schema’)
  10. GROUP BY engine
  11. ORDER BY sum(data_length+index_length) DESC LIMIT 10;
  12. +——–+——–+———+——–+——–+————+———+
  13. | engine | TABLES | rows    | DATA   | idx    | total_size | idxfrac |
  14. +——–+——–+———+——–+——–+————+———+
  15. | InnoDB |    181 | 457.58M | 92.34G | 54.58G | 146.92G    |    0.59 |
  16. | MyISAM |     13 | 22.91M  | 7.85G  | 2.12G  | 9.97G      |    0.27 |
  17. +——–+——–+———+——–+——–+————+———+
  18. 2 rows in set (0.22 sec)

获取以大小排序的MyISAM表列表,执行如下查询:

  1. SELECT
  2.     concat(table_schema, ‘.’, table_name) tbl,
  3.     engine,
  4.     concat(round(table_rows/1000000,2),’M’) rows,
  5.     concat(round(data_length/(1024*1024*1024),2),’G’) DATA,
  6.     concat(round(index_length/(1024*1024*1024),2),’G’) idx,
  7.     concat(round((data_length+index_length)/(1024*1024*1024),2),’G’) total_size,
  8.     round(index_length/data_length,2) idxfrac
  9.  FROM information_schema.TABLES
  10. WHERE table_schema not in (‘mysql’, ‘performance_schema’, ‘information_schema’)
  11.   AND engine = ‘MyISAM’
  12. ORDER BY data_length+index_length DESC;

需要记住的是,更改默认的存储引擎为InnoDB或者升级MySQL并不会自动把你的表转换为InnoDB。目前为止,你需要一个表一个表地转换,或者使用脚本。
需要注意的是,小的MyISAM表也一样需要转换,因为只要有一个MyISAM用在join语句里,那么整个查询都是用表级锁,所以这将对并发有很大影响。所以确保你把所有的MyISAM表转为InnoDB表。

转换为INNODB

建议在你着手转换引擎为InnoDB之前,最好先熟悉理解一下InnoDB的配置。准备好后,执行如下查询来转换:

  1. SET @DB_NAME = ‘your_database’;
  2.  
  3. SELECT  CONCAT(‘ALTER TABLE `’, table_name, ‘` ENGINE=InnoDB;’) AS sql_statements
  4. FROM    information_schema.tables AS tb
  5. WHERE   table_schema = @DB_NAME
  6. AND     `ENGINE` = ‘MyISAM’
  7. AND     `TABLE_TYPE` = ‘BASE TABLE’
  8. ORDER BY table_name DESC;

MySQL管理教程(一):MySQL性能调优 – 选择最佳硬件

电脑硬件变化非常快。 因此,不会提供特定的硬件建议。 但是,在购买服务器硬件时可以提高一些建议。

主板选择

第一个考虑是你应该总是购买64位硬件,因为mysqld可以利用64位操作系统支持每进程大量的内存。 在32位操作系统上,每个进程只能使用大约2.4 Gb的RAM,而mysqld当前是单线程的。 确保主板可以支持足够的RAM。 如果服务器要在高负载环境中使用,我们建议主板能够支持16 Gb RAM。
虽然你现在可能不需要它,但不要到时候需要更多的RAM了,而发现你的主板不支持更多的内存。
当涉及到RAM,所需的内存数量将根据您的应用程序大不相同。 如果整个数据库的大小为1 Gb,并且不会随时间增加,则服务器不需要8 Gb的RAM。 然而,许多应用程序具有比可用存储器的量大得多的数据库。 最重要的是数据库的工作集的大小。 数据库的工作集是每次处理的数据量。 如果数据库大小为100 Gb,但有一个工作集为10 Gb(只有10%需要在RAM中随时),那么给mysqld实例分配16 Gb内存就够用了。 工作集中的数据量随数据的使用方式而变化。

硬盘驱动器选择

您的I/O子系统通常是服务器中最难以准确预测的要求之一。 硬盘驱动器的当前选项包括传统的SCSI驱动器,SATA(串行ATA)驱动器,SAS(串行连接SCSI)驱动器和新的固态驱动器。 SATA驱动器的可靠性不如SAS驱动器。 除非服务器是非常低端的,它应该使用SAS驱动器。

RAID选择

在大型生产系统中,通常会有一个硬件RAID控制器或RAID通过操作系统级软件配置。 RAID代表独立磁盘冗余阵列。 顾名思义,RAID是将具有某些数据镜像的单元的磁盘组合在一起。 有各种级别的RAID。 下面列出了用于数据库服务器的最常用级别。
RAID 0:只有一个数据副本,但数据分散在多个磁盘上(条带化)。 如果一个磁盘发生故障,则所有数据从所有磁盘丢失。
RAID 1:两个大小相等的磁盘组合形成一个冗余阵列。 每个磁盘是另一个的副本(镜像)。 如果一个磁盘发生故障,则所有数据都完好无损。
RAID 5:以防止数据丢失任何一个磁盘的方式组合三个或更多磁盘; 阵列的存储容量减少一个磁盘。
RAID 10:RAID 1(镜像)和RAID 0(条带化)的组合。 阵列的存储容量是硬盘驱动器总容量的50%,但每个驱动器都是镜像的。
在寻找RAID控制器时,应选择支持所需RAID级别的控制器。 此外,大多数硬件RAID控制器具有RAM高速缓存。 这用作从数组读取和写入数组的缓冲区。 当选择控制器的规格时,找电池支持的写缓存。 这意味着控制器上的高速缓存使用电池,使得如果电力丢失,则高速缓存的内容保持一段时间。 这使您可以安全地使用写回功能,这意味着,当RAID控制器从服务器接收到写入请求时,它可以立即向操作系统返回写入完成的信号。 这可以提供良好的性能提升,因为操作系统不必等待硬盘驱动器实际将数据写入盘片并且发信号通知完成。 与系统RAM一样,RAID控制器上的RAM缓存越多越好。

固态硬盘

固态硬盘得到了很大的关注。 固态硬盘驱动器没有像传统磁盘那样的旋转头。 这些器件具有非易失性闪存或基于DRAM。 主要优点包括快速随机存取读取,因为没有磁头移动读取和写入。 基于DRAM的驱动器也具有极快的写入速度。 此时,与传统的硬盘驱动器相比,固态驱动器的成本比较高。

借助MySQLTuner提高MySQL性能及稳定性

MySQLTuner是一个用Perl编写的脚本,帮助你提高MySQL性能及稳定性。它通过检索当前配置变量和状态数据,提供一些基本性能建议。

安装使用MySQLTuner

1.下载MySQLTuner

  1. wget http://mysqltuner.pl/ -O mysqltuner.pl

2.运行程序

  1. perl mysqltuner.pl

3.输出如下

  1. >>  MySQLTuner 1.4.0 – Major Hayden <[email protected]>
  2.  >>  Bug reports, feature requests, and downloads at http://mysqltuner.com/
  3.  >>  Run with ‘–help’ for additional options and output filtering
  4. Please enter your MySQL administrative login: root
  5. Please enter your MySQL administrative password:
  6. [OK] Currently running supported MySQL version 5.5.41-0+wheezy1
  7. [OK] Operating on 64-bit architecture
  8.  
  9. ——– Storage Engine Statistics ——————————————-
  10. [–] Status: +ARCHIVE +BLACKHOLE +CSV -FEDERATED +InnoDB +MRG_MYISAM
  11. [–] Data in InnoDB tables: 1M (Tables: 11)
  12. [–] Data in PERFORMANCE_SCHEMA tables: 0B (Tables: 17)
  13. [!!] Total fragmented tables: 11
  14.  
  15. ——– Security Recommendations  ——————————————-
  16. [OK] All database users have passwords assigned
  17.  
  18. ——– Performance Metrics ————————————————-
  19. [–] Up for: 47s (113 q [2.404 qps], 42 conn, TX: 19K, RX: 7K)
  20. [–] Reads / Writes: 100% / 0%
  21. [–] Total buffers: 192.0M global + 2.7M per thread (151 max threads)
  22. [OK] Maximum possible memory usage: 597.8M (60% of installed RAM)
  23. [OK] Slow queries: 0% (0/113)
  24. [OK] Highest usage of available connections: 0% (1/151)
  25. [OK] Key buffer size / total MyISAM indexes: 16.0M/99.0K
  26. [!!] Query cache efficiency: 0.0% (0 cached / 71 selects)
  27. [OK] Query cache prunes per day: 0
  28. [OK] Temporary tables created on disk: 25% (54 on disk / 213 total)
  29. [OK] Thread cache hit rate: 97% (1 created / 42 connections)
  30. [OK] Table cache hit rate: 24% (52 open / 215 opened)
  31. [OK] Open file limit used: 4% (48/1K)
  32. [OK] Table locks acquired immediately: 100% (62 immediate / 62 locks)
  33. [OK] InnoDB buffer pool / data size: 128.0M/1.2M
  34. [OK] InnoDB log waits: 0
  35. ——– Recommendations —————————————————–
  36. General recommendations:
  37.     Run OPTIMIZE TABLE to defragment tables for better performance
  38.     Enable the slow query log to troubleshoot bad queries
  39. Variables to adjust:
  40.     query_cache_limit (> 1M, or use smaller result sets)

我们可以根据Recommendations下面建议修改MySQL的配置来的调优性能。

MySQL主要性能参数

key_buffer:
更改key_buffer为MySQL分配更多的内存,这可以大大加快你的数据库。 当使用MyISAM表引擎时,key_buffer大小通常不会超过系统内存的25%,而InnoDB最多可占70%。 如果该值设置得太高,则资源被浪费。 根据MySQL的文档,对于256MB RAM(或更多)具有许多表的服务器,建议使用64M的设置,而具有128MB RAM和较少表的服务器可以设置为16M(默认值)。
max_allowed_packet:
允许发送的数据包的最大大小。 数据包是单个SQL状态,单个行发送到客户端,或日志从主机发送到从机。 如果你知道你的MySQL服务器将要处理大数据包,最好提高到你最大的数据包的大小。 如果此值设置得太小,您将在错误日志中收到错误。
thread_stack:
此值包含每个线程的堆栈大小。 MySQL认为thread_stack变量的默认值足以正常使用; 但是,如果出现了与thread_stack相关的错误,则可以调大此值。
thread_cache_size:
如果thread_cache_size是“turned off”(设置为0),则所有新建的连接都需要为它们创建一个新的线程,当连接断开时,线程被销毁。 否则,此值设置要存储在缓存中的未使用线程的数量,直到它们需要用于连接。 通常,此设置对性能影响不大,除非您每分钟接收数百个连接,此时应该刷新该值,以便大多数连接使用到缓存线程。
max_connections:
设置并发连接的最大数量。 最好考虑过去的最大连接数,然后设置它,以便在该数字和max_connections值之间有一些缓冲区。

分析统计MySQL general日志 找出查询次数最多的SQL

当我们需要优化MySQL查询时,第一想到的是开启慢日志,慢日志可以看到执行消耗超过一定时间的SQL语句和未使用索引的SQL。但如果我们想分析所有SQL查询的分布,即哪类SQL查询次数最多的时候,我们可以开启general log来统计。

 

开启general log

 

  1. mysql> show  variables like ‘%general%’;

+——————+————————————-+
| Variable_name | Value |
+——————+————————————-+
| general_log | OFF |
| general_log_file | /usr/local/mysql/data/localhost.log |
+——————+————————————-+

  1. mysql> set global general_log = "ON";

 

analysis-general-log.py脚本

 

  1. #!/usr/bin/python
  2.  
  3. # sort and count mysql general log
  4. # Author: Jason
  5. # Url: devops.webres.wang
  6. # Email: admin#webres.wang
  7. # Created: UTC 2015-02-15 17:51:53
  8.  
  9. import re
  10. import sys
  11. import os
  12.  
  13. if len(sys.argv) == 2:
  14.     logPath = sys.argv[1]
  15.     if not os.path.exists(logPath):
  16.         print ("file " + logPath + " does not exists.")
  17.         sys.exit(1)
  18. else:
  19.     print ("Usage: " + sys.argv[0] + " logPath")
  20.     sys.exit(1)
  21.  
  22. logFo = open(logPath)
  23. match = 0
  24.  
  25. for line in logFo:
  26.     line = re.sub(r"n","",line)
  27.     if match == 0:
  28.         # match line begin with numbers
  29.         lineMatch = re.match(r"s+[0-9]+s+.*",line,flags=re.I)
  30.         if lineMatch:
  31.             lineTmp = lineMatch.group(0)
  32.             match = match + 1
  33.             continue
  34.  
  35.     elif match == 1:
  36.         # match line begin with numbers
  37.         lineMatch = re.match(r"s+[0-9]+s+.*",line,flags=re.I)
  38.         if lineMatch:
  39.             # match only query
  40.             lineMatchQuery = re.match(r".*Querys+(.*)",lineTmp,flags=re.I)
  41.             if lineMatchQuery:
  42.                 lineTmp = lineMatchQuery.group(1)
  43.                 # remove extra space
  44.                 lineTmp = re.sub(r"s+", " ",lineTmp)
  45.                 # replace values (value) to values (x)
  46.                 lineTmp = re.sub(r"valuess*(.*?)", "values (x)",lineTmp,flags=re.I)
  47.                 # replace filed = ‘value’ to filed = ‘x’
  48.                 lineTmp = re.sub(r"(=|>|<|>=|<=)s*(‘|").*?2","\1 ‘x’",lineTmp)
  49.                 # replace filed = value to filed = x
  50.                 lineTmp = re.sub(r"(=|>|<|>=|<=)s*[0-9]+","\1 x",lineTmp)
  51.                 # replace like ‘value’ to like ‘x’
  52.                 lineTmp = re.sub(r"likes+(‘|").*?1","like ‘x’",lineTmp,flags=re.I)
  53.                 # replace in (value) to in (x)
  54.                 lineTmp = re.sub(r"ins+(.*?)","in (x)",lineTmp,flags=re.I)
  55.                 # replace limit x,y to limit
  56.                 lineTmp = re.sub(r"limit.*","limit",lineTmp,flags=re.I)
  57.                 
  58.                 print (lineTmp)
  59.  
  60.             match = 1
  61.             lineTmp = lineMatch.group(0)
  62.         else:   
  63.             lineTmp += line
  64.             match = 1
  65.  
  66. logFo.close()

使用方法:

  1. analysis-general-log.py general.log | sort | uniq -c | sort -nr


1032 SELECT * FROM wp_comments WHERE ( comment_approved = ‘x’ OR comment_approved = ‘x’ ) AND comment_post_ID = x ORDER BY comment_date_gmt DESC
653 SELECT post_id, meta_key, meta_value FROM wp_postmeta WHERE post_id in (x) ORDER BY meta_id ASC
527 SELECT FOUND_ROWS()
438 SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy = ‘x’ AND t.term_id = x limit
341 SELECT option_value FROM wp_options WHERE option_name = ‘x’ limit
329 SELECT t.*, tt.*, tr.object_id FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON tt.term_id = t.term_id INNER JOIN wp_term_relationships AS tr ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy in (x) AND tr.object_id in (x) ORDER BY t.name ASC
311 SELECT wp_posts.* FROM wp_posts WHERE 1= x AND wp_posts.ID in (x) AND wp_posts.post_type = ‘x’ AND ((wp_posts.post_status = ‘x’)) ORDER BY wp_posts.post_date DESC
219 SELECT wp_posts.* FROM wp_posts WHERE ID in (x)
218 SELECT tr.object_id FROM wp_term_relationships AS tr INNER JOIN wp_term_taxonomy AS tt ON tr.term_taxonomy_id = tt.term_taxonomy_id WHERE tt.taxonomy in (x) AND tt.term_id in (x) ORDER BY tr.object_id ASC
217 SELECT wp_posts.* FROM wp_posts WHERE 1= x AND wp_posts.ID in (x) AND wp_posts.post_type = ‘x’ AND ((wp_posts.post_status = ‘x’)) ORDER BY wp_posts.menu_order ASC
202 SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1= x AND wp_posts.post_type = ‘x’ AND (wp_posts.post_status = ‘x’) ORDER BY wp_posts.post_date DESC limit
118 SET NAMES utf8
115 SET SESSION sql_mode= ‘x’
115 SELECT @@SESSION.sql_mode
112 SELECT option_name, option_value FROM wp_options WHERE autoload = ‘x’
111 SELECT user_id, meta_key, meta_value FROM wp_usermeta WHERE user_id in (x) ORDER BY umeta_id ASC
108 SELECT YEAR(min(post_date_gmt)) AS firstdate, YEAR(max(post_date_gmt)) AS lastdate FROM wp_posts WHERE post_status = ‘x’
108 SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy in (x) AND tt.count > x ORDER BY tt.count DESC limit
107 SELECT t.*, tt.* FROM wp_terms AS t INNER JOIN wp_term_taxonomy AS tt ON t.term_id = tt.term_id WHERE tt.taxonomy in (x) AND t.term_id in (x) ORDER BY t.name ASC
107 SELECT * FROM wp_users WHERE ID = ‘x’
106 SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1= x AND wp_posts.post_type = ‘x’ AND (wp_posts.post_status = ‘x’) AND post_date > ‘x’ ORDER BY wp_posts.post_date DESC limit
106 SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1= x AND wp_posts.post_type = ‘x’ AND (wp_posts.post_status = ‘x’) AND post_date > ‘x’ ORDER BY RAND() DESC limit
105 SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1= x AND wp_posts.post_type = ‘x’ AND (wp_posts.post_status = ‘x’) AND post_date > ‘x’ ORDER BY wp_posts.comment_count DESC limit

MySQL数据库MyISAM存储引擎转为Innodb

之前公司的数据库存储引擎全部为MyISAM,数据量和访问量都不是很大,所以一直都没什么问题。但是最近出现了MySQL数据表经常被锁的情况,直接导致了用户连接网站时超时而返回502,于是决定把存储引擎转为Innodb的,以解决MyISAM的表锁问题。下面将操作步骤记录一下。
1、导出centos数据库的表结构

  1. mysqldump -d -uxxx -p centos > centos_table.sql

其中-d参数表示不导出数据,只导出表结构
2、替换centos_table.sql里的MyISAM为INNODB

  1. sed -i ‘s/MyISAM/INNODB/g’ centos_table.sql

3、新建数据库centos_new,并导入表结构

  1. mysql > create database centos_new;
  2. mysql -uroot -p centos_new < centos_table.sql

可以通过show table status来检查表引擎是否为INNODB。
4、导出centos的数据

  1. mysqldump -t -uroot -p centos > centos_data.sql

其中-t参数表示只导数据,不导表结构
5、导入数据到centos_new

  1. mysql -uroot -p centos_new < centos_data.sql

最后如果你想把centos_new数据库名更改为centos,可以参考如何更改MySQL数据库名称

安全快速更改MySQL数据库名称

MySQL似乎没有更改数据库名称的语句(也许是我不知道),如果你有数据库服务器的管理权限,可以直接更改一下目录名即可,但如果没有权限,可以通过更改表名达到修改数据库名的目的。
下面是把centos数据库更改为centos_old。
1、新建数据库centos_old.

  1. mysql > create database centos_old;

2、使用select concat拼成所有rename table的语句。

  1. mysql -uroot -p -e "select concat(‘rename table centos.’,table_name,’ to centos_old.’,table_name,’;’) from information_schema.TABLES where TABLE_SCHEMA=’centos’;" > rename_mysql_name.sql

打开rename_mysql_name.sql,把第一行删除。
rename_mysql_name.sql内容大概为:

  1. rename table centos.wp_commentmeta to centos_old.wp_commentmeta;
  2. rename table centos.wp_comments to centos_old.wp_comments;
  3. rename table centos.wp_forum_forums to centos_old.wp_forum_forums;
  4. rename table centos.wp_forum_groups to centos_old.wp_forum_groups;
  5. rename table centos.wp_forum_posts to centos_old.wp_forum_posts;
  6. rename table centos.wp_forum_threads to centos_old.wp_forum_threads;
  7. rename table centos.wp_forum_usergroup2user to centos_old.wp_forum_usergroup2user;
  8. rename table centos.wp_forum_usergroups to centos_old.wp_forum_usergroups;
  9. rename table centos.wp_links to centos_old.wp_links;
  10. rename table centos.wp_options to centos_old.wp_options;
  11. rename table centos.wp_postmeta to centos_old.wp_postmeta;
  12. rename table centos.wp_posts to centos_old.wp_posts;
  13. rename table centos.wp_term_relationships to centos_old.wp_term_relationships;
  14. rename table centos.wp_term_taxonomy to centos_old.wp_term_taxonomy;
  15. rename table centos.wp_terms to centos_old.wp_terms;
  16. rename table centos.wp_usermeta to centos_old.wp_usermeta;
  17. rename table centos.wp_users to centos_old.wp_users;

3、执行rename语句

  1. mysql -uroot -p < rename_mysql_name.sql

这样就完成了centos数据库名更改为centos_old的操作。