mysql引擎性能简单测试

[硬件配置]

CPU : AMD2500+ (1.8G)

内存: 1G/现代

硬盘: 80G/IDE



[软件配置]

OS : Windows XP SP2

SE : PHP5.2.1

DB : MySQL5.0.37

Web: IIS6





[MySQL表结构]



CREATE TABLE `myisam` (

   `id` int(11) NOT NULL auto_increment,

   `name` varchar(100) default NULL,

   `content` text,

  PRIMARY KEY   (`id`)

) ENGINE=MyISAM DEFAULT CHARSET=gbk;



CREATE TABLE `innodb` (

   `id` int(11) NOT NULL auto_increment,

   `name` varchar(100) default NULL,

   `content` text,

  PRIMARY KEY   (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=gbk;





[数据内容]



$name = "heiyeluren";

$content = "MySQL支持数个存储引擎作为对不同表的类型的处理器。MySQL存储引擎包括处理事务安全表的引擎和处理非事务安全表的引擎:· MyISAM管理非事务表。它提供高速存储和检索,以及全文搜索能力。MyISAM在所有MySQL配置里被支持,它是默认的存储引擎,除非你配置 MySQL默认使用另 外一个引擎。 ·MEMORY存储引擎提供“内存中”表。MERGE存储引擎允许集合将被处理同样的MyISAM表作为一个单独的表。就像MyISAM一样,MEMORY和MERGE存储引擎处理非事务表,这两个引擎也都被默认包含在MySQL中。释:MEMORY存储引擎正式地被确定为HEAP引擎。· InnoDB和BDB存储引擎提供事务安全表。BDB被包含在为支持它的操作系统发布的MySQL-Max二进制分发版里。InnoDB也默认被包括在所有MySQL 5.1二进制分发版里,你可以按照喜好通过配置MySQL来允许或禁止任一引擎。·EXAMPLE存储引擎是一个“存根”引擎,它不做什么。你可以用这个引擎创建表,但没有数据被存储于其中或从其中检索。这个引擎的目的是服务,在MySQL源代码中的一个例子,它演示说明如何开始编写新存储引擎。同样,它的主要兴趣是对开发者。";





[插入数据-1] (innodb_flush_log_at_trx_commit=1)

MyISAM 1W:3/s

InnoDB 1W:219/s



MyISAM 10W:29/s

InnoDB 10W:2092/s



MyISAM 100W:287/s

InnoDB 100W:没敢测试



[插入数据-2] (innodb_flush_log_at_trx_commit=0)

MyISAM 1W:3/s

InnoDB 1W:3/s



MyISAM 10W:30/s

InnoDB 10W:29/s



MyISAM 100W:273/s

InnoDB 100W:423/s



[插入数据3] (innodb_buffer_pool_size=1024M)

InnoDB 1W:3/s

InnoDB 10W:33/s

InnoDB 100W:607/s



[插入数据4] (innodb_buffer_pool_size=256M, innodb_flush_log_at_trx_commit=1, set autocommit=0)



InnoDB 1W:3/s

InnoDB 10W:26/s

InnoDB 100W:379/s







[MySQL 配置文件] (缺省配置)



# MySQL Server Instance Configuration File

[client]

port=3306
default-character-set=gbk

[mysqld]

port=3306

basedir="C:/mysql50/"

datadir="C:/mysql50/Data/"

default-character-set=gbk

default-storage-engine=INNODB

sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

max_connections=100



query_cache_size=0

table_cache=256

tmp_table_size=50M

thread_cache_size=8

myisam_max_sort_file_size=100G

myisam_max_extra_sort_file_size=100G

myisam_sort_buffer_size=100M

key_buffer_size=82M

read_buffer_size=64K

read_rnd_buffer_size=256K

sort_buffer_size=256K



innodb_additional_mem_pool_size=4M

innodb_flush_log_at_trx_commit=1

innodb_log_buffer_size=2M

innodb_buffer_pool_size=159M

innodb_log_file_size=80M

innodb_thread_concurrency=8









【总结】



可以看出 在MySQL 5.0里面,MyISAM和InnoDB存储引擎性能差别并不是很大,针对InnoDB来说,影响性能的主要是 innodb_flush_log_at_trx_commit 这个选项,如果设置为1的话,那么每次插入数据的时候都会自动提交,导致性能急剧下降,应该是跟刷新日志有关系,设置为0效率能够看到明显提升,当然,同样你可以SQL中提交“SET AUTOCOMMIT = 0”来设置达到好的性能。另外,还听说通过设置innodb_buffer_pool_size能够提升InnoDB的性能,但是我测试发现没有特别明显的提升。



基本上我们可以考虑使用InnoDB来替代我们的MyISAM引擎了,因为InnoDB自身很多良好的特点,比如事务支持、存储过程、视图、行级锁定等等,在并发很多的情况下,相信InnoDB的表现肯定要比MyISAM强很多,当然,相应的在my.cnf中的配置也是比较关键的,良好的配置,能够有效的加速你的应用。



如果不是很复杂的Web应用,非关键应用,还是可以继续考虑MyISAM的,这个具体情况可以自己斟酌。

MySQL replication 详细配置

1. 设置master
(1) 修改配置文件
# vim /etc/my.cf
在[mysqld]部分添加
server-id=1
log-bin=mysql-bin
改完后重启mysqld服务
# service mysqld restart
(2) 设置mysql数据库的root访问密码
# mysqladmin -u root password '123'
# mysql -u root -p  输入密码‘123’登陆mysql
mysql> grant replication slave on *.* to 'test'@'10.0.2.61' identified by '123';
说明:这里的test是为slave端设置的访问master端mysql数据的用户,密码为123,这里的10.0.2.61为slave的ip。
mysql> flush tables with read lock; 锁定数据库,此时不允许更改任何数据
mysql> show master status; 查看状态,这些数据是要记录的,一会要在slave端用到
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000022 |      229 |              |                  |
+------------------+----------+--------------+------------------+


2. 设置slave
# vim /etc/my.cnf 在[mysqld]部分加入
server-id=2 //设置数据库id,可以随便设置,但是不能和Master重复。
# scp -r 10.0.2.62:/var/lib/mysql/库名/* /var/lib/mysql/库名  这里的/var/lib/mysql 是数据库的datadir,不要搞混了。从master把所有数据库文件拷贝到slave,目的是数据的一致,mysql库就不用拷贝了,因为slave上也有一些配置保存在mysql库里。
# service mysqld restart
# mysql -u root -p  
mysql> slave stop; 停止slave服务
mysql> change master to
->master_host=‘10.0.2.61’, //主服务器的IP地址
->master_user='test', //同步数据库的用户
->master_password='123', //同步数据库的密码
->master_log_file='mysql-bin.000022', //主服务器二进制日志的文件名(前面要求记住的参数)
-> master_log_pos=229; //日志文件的开始位置(前面要求记住的参数)

注:有时需要指定主mysql的端口号,参数为 master_port=3306
mysql> unlock tables; master上打开锁定的数据库
mysql> slave start;   启动同步数据库的线程
mysql> show slave status\G;查看状态
确认以下两项参数都为yes
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

减少MySQL的Sleep进程有效方法

经常遇到很多朋友问到,他的MySQL中有很多Sleep进程,严重占用MySQL的资源,现在分析一下出现这种现象的原因和解决办法:

1,通常来说,MySQL出现大量Sleep进程是因为采用的PHP的MySQL长链接数据库方式,即使用了mysql_pconnect来打开链接数据库,解决办法就是使用“短”链接,即mysql_connect函数。
2,在使用mysql_connect短链接方式打开数据库,每个页面在打开数据库后,执行SQL完成,当页面脚本结束的时候,这个MySQL连接会自动关闭并且释放内存。但仍然出现大量Sleep进程,可以看看网站是否存在以下几个方面的问题。
A,硬盘上存在大量的静态文件,或者WEB服务器负荷太重,在处理HTTP请求响应变得太慢,这样也有可能导致出现大量Sleep进程,解决方法适当调整WEB服务参数和文件,一味的静态或者缓存化网页内容并不是灵丹妙药。
B,在网页脚本中,有些计算和应用可能非常耗时,比如在0秒的时候打开数据库执行完一段SQL代码后,网页脚本随即花了20秒钟进行一段复杂的运算,或者是require了一个庞大的PHP文件(比如含有几千个违规关键字的过滤函数),哪么这个时候在MySQL后台看到的进程中,这个20秒的过程MySQL并没有做任何事情了,一直处于Sleep状态,直到这个页面执行完毕或者达到wait_timeout值(被强行关闭),优化网页脚本,尽量让程序快速运行,或者在执行这段耗时的运行过程中,执行mysql_close把当前MySQL链接强行关闭。
C,在采集站中,MySQL中大量的Sleep进程这类现象尤其明显(比如很多网友问道DeDeCMS的MySQL中出现大量Sleep),因为大部的采集器页面在运行过程中,事先打开了一个MySQL链接(可能是为了验证用户权限等),然后开始使用file_get_contents之类的操作去获取一个远程的网页内容,如果这个远程的站点访问速度太慢,比如花了10秒时间才把网页取回,哪么当前采集脚本程序就一直阻塞在这里,并且MySQL啥事也没干,一直处于Sleep状态。解决方法同上,在发出file_get_contents采集远程网页的时候,使用mysql_close强行关闭MySQL的连接,等采集完成在适当需要的时候再重新mysql_connect即可。

总的说来,MySQL是一个非常高效快速的数据库,要让他发挥到最大的性能,同时也不要过量的去掘取他的优势所在,适当的分表(超过10G的表,在打开和关闭以前更新的时候效率明显下降很多),尽可能的优化SQL都可以做到事半功倍的。

mysql 忘记root密码怎么办

如果忘记root密码或其他用户密码,不要急,按下面操作即可。
1. 编辑mysql主配置文件 my.cnf
vim /etc/my.cnf  
在[mysqld]字段下添加参数  skip-grant  
2. 重启数据库服务
service mysqld restart
3. 这样就可以进入数据库不用授权了
mysql -uroot
4. 修改相应用户密码
use mysql;
update user set password=password(your password) where user="root";
flush privileges;

关于mysql

本帖最后由 wangjian 于 2011-7-26 21:15 编辑

有一个人给我发了么一个内容的东西,让我去mqsql机器上跑一下,怎么跑呀?一个名为txt的文件?
CREATE DATABASE `tuan` DEFAULT CHARACTER SET utf8;

USE `tuan`;

CREATE TABLE deal (
    id INTEGER NOT NULL AUTO_INCREMENT,
    city_id INTEGER,
        city_name VARCHAR(255),
    title VARCHAR(1024),
        merchant_id INTEGER,
        merchant_name VARCHAR(255),
    gp_deal_id INTEGER,
        deal_id INTEGER,
        gp_sellcount INTEGER default 0,
        sellcount INTEGER default 0,
        start_time TIMESTAMP,
        end_time TIMESTAMP,
        PRIMARY KEY (id)
) AUTO_INCREMENT=1000000000 DEFAULT CHARSET=utf8;
ALTER TABLE deal ADD INDEX index_deal_gp (gp_deal_id);
ALTER TABLE deal ADD INDEX index_deal_time (deal_id, start_time, end_time);


CREATE TABLE deal_upload (
    id INTEGER NOT NULL AUTO_INCREMENT,
        gp_deal_id INTEGER,
        deal_id INTEGER,
        ret_desc VARCHAR(255),
        ret_code SMALLINT,
        create_time TIMESTAMP,
        PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;
ALTER TABLE deal_upload ADD INDEX index_upload_gp (gp_deal_id);

create table deal_code_verify (
        id INTEGER NOT NULL AUTO_INCREMENT,
        gp_deal_id INTEGER,
        verify_code VARCHAR(20),
        sn VARCHAR(20),
        ret_desc VARCHAR(255),
        ret_code SMALLINT,
        use_time TIMESTAMP,
        create_time TIMESTAMP,
        PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;
ALTER TABLE deal_code_verify ADD INDEX index_verify_gp (gp_deal_id);

create table deal_code_query (
        id INTEGER NOT NULL AUTO_INCREMENT,
        gp_deal_id INTEGER,
        verify_code VARCHAR(20),
        ret_desc VARCHAR(255),
        ret_code SMALLINT,
        create_time TIMESTAMP,
        PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;
ALTER TABLE deal_code_query ADD INDEX index_query_gp (gp_deal_id);

create table deal_cancel (
        id INTEGER NOT NULL AUTO_INCREMENT,
        gp_deal_id INTEGER,
        ret_desc VARCHAR(255),
        ret_code SMALLINT,
        create_time TIMESTAMP,
        PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;
ALTER TABLE deal_cancel ADD INDEX index_cancel_gp (gp_deal_id);

create table deal_sellcount (
        id INTEGER NOT NULL AUTO_INCREMENT,
        ret_desc VARCHAR(255),
        ret_code SMALLINT,
        data  VARCHAR(2048),
        create_time TIMESTAMP,
        PRIMARY KEY (id)
) DEFAULT CHARSET=utf8;


create table sold (
        id integer auto_increment primary key,
        deal_id integer,
        cnt integer comment 'count sold in tuan',
        total_price decimal(12,2) comment 'total price',
        our_cnt integer comment 'count sold in our platform',
        index sold_deal_id (deal_id)
) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_general_ci;

create table sold_detail (
        id integer auto_increment primary key,
        deal_id integer,
        sn varchar(128) comment ' tuan serial no',
        no varchar(32) comment 'user  no',
        phone_no varchar(20) comment 'user phone no',
        created timestamp comment 'created time',
        index sold_detail_deal_id (deal_id)
) ENGINE=MyISAM CHARACTER SET utf8 COLLATE utf8_general_ci;

GRANT ALL PRIVILEGES ON tuan.* TO 'stardeals'@'%' IDENTIFIED BY '5742d34l5' WITH GRANT OPTION;
Tencent64:/data #

ignored in --skip-name-resolve mode

以前也看到过这个错误信息,不过今天想彻底的研究一下。
其实也不算错误,顶多就算是警告。查看错误日日志时,有如下信息:
110908 10:21:56 [Warning] 'user' entry 'root@server1‘ ignored in --skip-name-resolve mode.
110908 10:21:56 [Warning] 'user' entry '@server1' ignored in --skip-name-resolve mode.
网上查了下资料,才明白是这么回事:
skip-name-resolve 参数的目的是不再把域名解析成IP,这样可以加快数据库的反应时间。然而我们使用这个参数后,原来数据库中已经存在的域名就不能再被解析了。不妨先看看mysql库中相关的数据:

mysql> select user,host from user;
+------+------------------+
| user | host             |
+------+------------------+
| root | 127.0.0.1        |
|        | server1 |
| root | server1|
|        | localhost        |
| root | localhost        |
+------+------------------+

这里面的host列正好和错误日中中的那个warning相吻合。既然已经不能解析成IP了,也就是说里面的server1已经不再生效了。删除得了。
mysql> delete from user where host='server1';
Query OK, 2 rows affected (0.00 sec)

删除后,错误日志中则不再出现类似的警告信息。

MySQL的Query Cache工作原理分析

本帖最后由 lqph3387 于 2011-3-29 16:47 编辑

其实MySQL(和PHP搭配之最佳组合)有着很强大的功能,只是默认没有启用,这篇文章将为大家介绍MySQL(和PHP搭配之最佳组合)查询调整缓冲设置(query_cache),可以让MySQL(和PHP搭配之最佳组合)的速度提高至少5倍。

    查询缓存存储SELECT查询的文本以及发送给客户端的相应结果。如果随后收到一个相同的查询,服务器从查询缓存中重新得到查询结果,而不再需要解析和执行查询。

    如果你有一个不经常改变的表并且服务器收到该表的大量相同查询,查询缓存在这样的应用环境中十分有用。对于许多Web服务器来说存在这种典型情况,它根据数据库内容生成大量的动态页面

QueryCache(下面简称QC)是根据SQL语句来cache的。一个SQL查询如果以select开头,那么MySQL服务器将尝试对其使用 QC。每个Cache都是以SQL文本作为key来存的。在应用QC之前,SQL文本不会被作任何处理。也就是说,两个SQL语句,只要相差哪怕是一个字 符(例如大小写不一样;多一个空格等),那么这两个SQL将使用不同的一个CACHE。
不过SQL文本有可能会被客户端做一些处理。例如在官方的命令行客户端里,在发送SQL给服务器之前,会做如下处理:
过滤所有注释
去掉SQL文本前后的空格,TAB等字符。注意,是文本前面和后面的。中间的不会被去掉。
下 面的三条SQL里,因为SELECT大小写的关系,最后一条和其他两条在QC里肯定是用的不一样的存储位置。而第一条和第二条,区别在于后者有个注释,在 不同客户端,会有不一样的结果。所以,保险起见,请尽量不要使用动态的注释。在PHP的mysql扩展里,SQL的注释是不会被去掉的。也就是三条SQL 会被存储在三个不同的缓存里,虽然它们的结果都是一样的。
select * FROM people where name='surfchen';
select * FROM people where /*hey~*/name='surfchen';
SELECT * FROM people where name='surfchen';
目前只有select语句会被cache,其他类似show,use的语句则不会被cache。
因为QC是如此前端,如此简单的一个缓存系统,所以如果一个表被更新,那么和这个表相关的SQL的所有QC都会被失效。假设一个联合查询里涉及到了表A和表B,如果表A或者表B的其中一个被更新(update或者delete),这个查询的QC将会失效。
也 就是说,如果一个表被频繁更新,那么就要考虑清楚究竟是否应该对相关的一些SQL进行QC了。一个被频繁更新的表如果被应用了QC,可能会加重数据库的负 担,而不是减轻负担。我一般的做法是默认打开QC,而对一些涉及频繁更新的表的SQL语句加上SQL_NO_CACHE关键词来对其禁用CACHE。这样 可以尽可能避免不必要的内存操作,尽可能保持内存的连续性。
那些查询很分散的SQL语句,也不应该使用QC。例如用来查询用户和密码的语句 ——“select pass from user where name='surfchen'”。这样的语句,在一个系统里,很有可能只在一个用户登陆的时候被使用。每个用户的登陆所用到的查询,都是不一样的SQL 文本,QC在这里就几乎不起作用了,因为缓存的数据几乎是不会被用到的,它们只会在内存里占地方。
存储块
在本节里“存储块”和“block”是同一个意思
QC 缓存一个查询结果的时候,一般情况下不是一次性地分配足够多的内存来缓存结果的。而是在查询结果获得的过程中,逐块存储。当一个存储块被填满之后,一个新 的存储块将会被创建,并分配内存(allocate)。单个存储块的内存分配大小通过query_cache_min_res_unit参数控制,默认为 4KB。最后一个存储块,如果不能被全部利用,那么没使用的内存将会被释放。如果被缓存的结果很大,那么会可能会导致分配内存操作太频繁,系统系能也随之 下降;而如果被缓存的结果都很小,那么可能会导致内存碎片过多,这些碎片如果太小,就很有可能不能再被分配使用。
除了查询结果需要存储块之 外,每个SQL文本也需要一个存储块,而涉及到的表也需要一个存储块(表的存储块是所有线程共享的,每个表只需要一个存储块)。存储块总数量=查询结果数 量*2+涉及的数据库表数量。也就是说,第一个缓存生成的时候,至少需要三个存储块:表信息存储块,SQL文本存储块,查询结果存储块。而第二个查询如果 用的是同一个表,那么最少只需要两个存储块:SQL文本存储块,查询结果存储块。
通过观察Qcache_queries_in_cache和 Qcache_total_blocks可以知道平均每个缓存结果占用的存储块。它们的比例如果接近1:2,则说明当前的 query_cache_min_res_unit参数已经足够大了。如果Qcache_total_blocks比 Qcache_queries_in_cache多很多,则需要增加query_cache_min_res_unit的大小。
Qcache_queries_in_cache*query_cache_min_res_unit(sql 文本和表信息所在的block占用的内存很小,可以忽略)如果远远大于query_cache_size-Qcache_free_memory,那么可 以尝试减小query_cache_min_res_unit的值。
调整大小
如果Qcache_lowmem_prunes增长迅速,意味着很多缓存因为内存不够而被释放,而不是因为相关表被更新。尝试加大query_cache_size,尽量使Qcache_lowmem_prunes零增长。
启动参数
show variables like 'query_cache%'可以看到这些信息。
query_cache_limit:如果单个查询结果大于这个值,则不Cache
query_cache_size: 分配给QC的内存。如果设为0,则相当于禁用QC。要注意QC必须使用大约40KB来存储它的结构,如果设定小于40KB,则相当于禁用QC。QC存储的 最小单位是1024 byte,所以如果你设定了一个不是1024的倍数的值,这个值会被四舍五入到最接近当前值的等于1024的倍数的值。
query_cache_type:0 完全禁止QC,不受SQL语句控制(另外可能要注意的是,即使这里禁用,上面一个参数所设定的内存大小还是会被分配);1启用QC,可以在SQL语句使用 SQL_NO_CACHE禁用;2可以在SQL语句使用SQL_CACHE启用。
query_cache_min_res_unit:每次给QC结果分配内存的大小
状态
show status like 'Qcache%'可以看到这些信息。
Qcache_free_blocks: 当一个表被更新之后,和它相关的cache blocks将被free。但是这个block依然可能存在队列中,除非是在队列的尾部。这些blocks将会被统计到这个值来。可以用FLUSH QUERY CACHE语句来清空free blocks。
Qcache_free_memory:可用内存,如果很小,考虑增加query_cache_size
Qcache_hits:自mysql进程启动起,cache的命中数量
Qcache_inserts:自mysql进程启动起,被增加进QC的数量
Qcache_lowmem_prunes:由于内存过少而导致QC被删除的条数。加大query_cache_size,尽可能保持这个值0增长。
Qcache_not_cached:自mysql进程启动起,没有被cache的只读查询数量(包括select,show,use,desc等)
Qcache_queries_in_cache:当前被cache的SQL数量
Qcache_total_blocks: 在QC中的blocks数。一个query可能被多个blocks存储,而这几个blocks中的最后一个,未用满的内存将会被释放掉。例如一个QC结果 要占6KB内存,如果query_cache_min_res_unit是4KB,则最后将会生成3个blocks,第一个block用来存储sql语句 文本,这个不会被统计到query+cache_size里,第二个block为4KB,第三个block为2KB(先allocate4KB,然后释放 多余的2KB)。每个表,当第一个和它有关的SQL查询被CACHE的时候,会使用一个block来存储表信息。也就是说,block会被用在三处地方: 表信息,SQL文本,查询结果

查阅不少文档后,总结如下:
      查询缓存区适合select 操作较多,而insert update delete操作较少的情况,并且重复的SQL查询越多,效果越好

mysql 5.0 升级5.1

为了满足业务需求,实现数据表的分区功能,最近做了一次mysql版本升级。
步骤很简单:
   1. 解压5.1版本的二进制安装文件。
   2. 修改mysql 链接文件指向mysql5.1目录
   3. 修改5.0和5.1之间不兼容的cnf参数,如--log_slow_queries改为--slow_query_log
   4. 拉起mysql
   5. 运行mysql5.1的mysql_upgrade 创建mysql.plugin,以及修复部分权限表的结构
   6. 执行mysql_upgrade 过程中的修复提示
REPAIR TABLE `help_category`;
REPAIR TABLE `help_keyword`;
REPAIR TABLE `help_topic`;
REPAIR TABLE `proc`;
REPAIR TABLE `time_zone_name`;
    7. 检查表数据及功能。

附注:mysql 升级注意事项
检查所有的变化,尤其注意那些标志为 "不兼容的变化" 的部分。详情请看附录 "mysql_update MySQL升级时检查数据表"
可能某些发布版本会改变授权表的机制
查看所有重大的变化,详情请看MySQL手册的 "D.1.1.?Changes in release 5.1.10 (Not yet released)" 章节
以下是升级到MySQL 5.1之后会发生的一些变化:
服务器部分:
不兼容的变化:MySQL 5.1 实现了支持无需重启服务器就能在运行时加载或卸载API插件。这个特性需要用到mysql.plugin表,可以运行 "mysql_upgrade" 命令来创建该表
插件安装在系统变量 plugin_dir 所指的目录下。这个变量也控制着用户自定义函数(UDFs)所在目录,这相对以前的版本有所改变。在MySQL 5.1中,所有的UDFs库必须都安装到 plugin_dir 目录下,从旧版本升级的时候,必须把那些库文件都移动到这个目录下
不兼容的变化:系统变量 table_cache 改名为 table_open_cache
不兼容的变化:在MySQL 5.1.6 中 FULLTEXT 的索引结构发生变化了。当升级到 5.1.6 甚至更高之后,需要对每个包含 FULLTEXT 字段的数据表执行 "REPAIR TABLE" 语句
在 MySQL 5.1.6 以前,MySQL把普通的查询日志和慢查询都写到文件中。从5.1.6以后,这些日志可以灵活地选择是是写到日志文件中(跟以前一样)或者写到 mysql 数据库的 general_log 和 slow_log 表中。如果启用日志记录,这2种方式都可以使用。选项 --log-output 用来控制这2种日志的记录方式
从5.1.6开始,特殊字符集的数据库和表的标识符在创建相应目录和文件时都会用对应的字符集编码了
SQL分:

MYSQL 字符集问题(转)

前一段时间,一直被mysql的字符集困扰,今天就这方面的知识总结一下.
MySQL的字符集支持(Character Set Support)有两个方面:
     字符集(Character set)和排序方式(Collation)。
对于字符集的支持细化到四个层次:
     服务器(server),数据库(database),数据表(table)和连接(connection)。


1.MySQL默认字符集
  MySQL对于字符集的指定可以细化到一个数据库,一张表,一列,应该用什么字符集。

但是,传统的程序在创建数据库和数据表时并没有使用那么复杂的配置,它们用的是默认的配置,那么,默认的配置从何而来呢?

    (1)编译MySQL 时,指定了一个默认的字符集,这个字符集是 latin1;
    (2)安装MySQL 时,可以在配置文件 (my.ini) 中指定一个默认的的字符集,如果没指定,这个值继承自编译时指定的;
    (3)启动mysqld 时,可以在命令行参数中指定一个默认的的字符集,如果没指定,这个值继承自配置文件中的配置,此时 character_set_server 被设定为这个默认的字符集;
    (4)当创建一个新的数据库时,除非明确指定,这个数据库的字符集被缺省设定为character_set_server;
    (5)当选定了一个数据库时,character_set_database 被设定为这个数据库默认的字符集;
    (6)在这个数据库里创建一张表时,表默认的字符集被设定为 character_set_database,也就是这个数据库默认的字符集;
    (7)当在表内设置一栏时,除非明确指定,否则此栏缺省的字符集就是表默认的字符集;

简单的总结一下,如果什么地方都不修改,那么所有的数据库的所有表的所有栏位的都用 latin1 存储,不过我们如果安装 MySQL,一般都会选择多语言支持,也就是说,安装程序会自动在配置文件中把 default_character_set 设置为 UTF-8,这保证了缺省情况下,所有的数据库的所有表的所有栏位的都用 UTF-8 存储。


2.查看默认字符集(默认情况下,mysql的字符集是latin1(ISO_8859_1)
通常,查看系统的字符集和排序方式的设定可以通过下面的两条命令:
     mysql> SHOW VARIABLES LIKE 'character%';
+--------------------------+---------------------------------+
| Variable_name            | Value                           |
+--------------------------+---------------------------------+
| character_set_client     | latin1                          |
| character_set_connection | latin1                          |
| character_set_database   | latin1                          |
| character_set_filesystem | binary                          |
| character_set_results    | latin1                          |
| character_set_server     | latin1                          |
| character_set_system     | utf8                            |
| character_sets_dir       | D:"mysql-5.0.37"share"charsets" |
+--------------------------+---------------------------------+

  mysql> SHOW VARIABLES LIKE 'collation_%';
+----------------------+-----------------+
| Variable_name        | Value           |
+----------------------+-----------------+
| collation_connection | utf8_general_ci |
| collation_database   | utf8_general_ci |
| collation_server     | utf8_general_ci |
+----------------------+-----------------+

3.修改默认字符集
  (1) 最简单的修改方法,就是修改mysql的my.ini文件中的字符集键值,
如    default-character-set = utf8
      character_set_server =  utf8
   修改完后,重启mysql的服务,service mysql restart
   使用 mysql> SHOW VARIABLES LIKE 'character%';查看,发现数据库编码均已改成utf8
+--------------------------+---------------------------------+
| Variable_name            | Value                           |
+--------------------------+---------------------------------+
| character_set_client     | utf8                            |
| character_set_connection | utf8                            |
| character_set_database   | utf8                            |
| character_set_filesystem | binary                          |
| character_set_results    | utf8                            |
| character_set_server     | utf8                            |
| character_set_system     | utf8                            |
| character_sets_dir       | D:"mysql-5.0.37"share"charsets" |
+--------------------------+---------------------------------+

   (2) 还有一种修改字符集的方法,就是使用mysql的命令
     mysql> SET character_set_client = utf8 ;
     mysql> SET character_set_connection = utf8 ;
     mysql> SET character_set_database = utf8 ;
     mysql> SET character_set_results = utf8 ;
     mysql> SET character_set_server = utf8 ;

     mysql> SET collation_connection = utf8 ;
     mysql> SET collation_database = utf8 ;
     mysql> SET collation_server = utf8 ;


一般就算设置了表的默认字符集为utf8并且通过UTF-8编码发送查询,你会发现存入数据库的仍然是乱码。问题就出在这个connection连接层上。解决方法是在发送查询前执行一下下面这句:
SET NAMES 'utf8';

它相当于下面的三句指令:
SET character_set_client = utf8;
SET character_set_results = utf8;
SET character_set_connection = utf8;

总结:
因此,使用什么数据库版本,不管是3.x,还是4.0.x还是4.1.x,其实对我们来说不重要,重要的有二:
  1) 正确的设定数据库编码.MySQL4.0以下版本的字符集总是默认ISO8859-1,MySQL4.1在安装的时候会让你选择。如果你准备使用UTF- 8,那么在创建数据库的时候就要指定好UTF-8(创建好以后也可以改,4.1以上版本还可以单独指定表的字符集)
  2) 正确的设定数据库connection编码.设置好数据库的编码后,在连接数据库时候,应该指定connection的编码,比如使用jdbc连接时,指定连接为utf8方式.

is marked as crashed and should be repaired when using LOCK TABLES

备份数据库时,报错:
mysqldump: Got error: 145: Table './dzstat/stat_active_201110' is marked as crashed and should be repaired when using LOCK TABLES

进入数据库对该表进行检测:mysql> check table stat_active_201110;
+---------------------------+-------+----------+--------------------------------------------------------------------+
| Table                     | Op    | Msg_type | Msg_text                                                           |
+---------------------------+-------+----------+--------------------------------------------------------------------+
| dzstat.stat_active_201110 | check | warning  | Table is marked as crashed                                         |
| dzstat.stat_active_201110 | check | warning  | 1 client is using or hasn't closed the table properly              |
| dzstat.stat_active_201110 | check | error    | Found key at page 111371264 that points to record outside datafile |
| dzstat.stat_active_201110 | check | error    | Corrupt                                                            |
+---------------------------+-------+----------+--------------------------------------------------------------------+
4 rows in set (17.44 sec)
解决办法:mysql> repair table stat_active_201110;
+---------------------------+--------+----------+----------+
| Table                     | Op     | Msg_type | Msg_text |
+---------------------------+--------+----------+----------+
| dzstat.stat_active_201110 | repair | status   | OK       |
+---------------------------+--------+----------+----------+
1 row in set (29.81 sec)
再次检测:mysql> check table stat_active_201110;
+---------------------------+-------+----------+----------+
| Table                     | Op    | Msg_type | Msg_text |
+---------------------------+-------+----------+----------+
| dzstat.stat_active_201110 | check | status   | OK       |
+---------------------------+-------+----------+----------+
1 row in set (5.19 sec)
这样就ok了

不停止master增加slave

需求和环境:有一台Mysql master和slave A,  需要在不停止Master工作的情况下增加一个slave,即不能使用表锁、停止服务操作。

意义:此方法在扩容时,不需要停止服务即可完成扩容。

1.登陆A slave,停止备份,记录Read_Master_Log_Pos和Master_Log_File值

mysql -uroot  -p

stop slave

show slave status

2.使用mysqldump备份A slave,生成备份sql文件

mysqldump -uroot -p dbname > dbname_back.sql

3.使用A slave备份好的sql文件恢复到B slave中

mysql -uroot -p dbname < dbname_back.sql


4.在A slave和B slave上start slave

在B上

change master to master_host=’10.1.2.1‘, master_port=3306, master_user ='master', master_password='password', master_log_file ='mysql-bin.000001', master_log_pos=123;


A上start slave

libraries: libstdc++.so.5: cannot open shared object file: No such ……

我的系统是CentOS 5.5 64位的,在初始化mysql时,报错。
./scripts/mysql_install_db --user=mysql --datadir=/data/mysql/mysql0
WARNING: The host '5d6d-db-dd-lfctc' could not be looked up with resolveip.
This probably means that your libc libraries are not 100 % compatible
with this binary MySQL version. The MySQL daemon, mysqld, should work
normally with the exception that host name resolving will not work.
This means that you should use IP addresses instead of hostnames
when specifying MySQL privileges !
Installing MySQL system tables...
./bin/mysqld: error while loading shared libraries: libstdc++.so.5: cannot open shared object file: No such file or directory
Installation of system tables failed!

解决办法:
yum install -y compat-libstdc++-33.x86_64

使用MYSQL查询缓存

使用 Mysql 的查询缓存MySQL 的查询缓存是将客户端执行的 SELECT 语句和查询结构都缓存起来,如果再执行一个相同的查询,则不再进行解析和查询,直接将缓存的结果返回。这样的特性对于更新不频繁,以读操作为主的数据库有很大的性能提升。对于更新频繁的数据库则相对没有那么有效,因为数据的更新会将查询从查询缓存条目清空。
首先我们需要确认当前的数据库环境是否可以使用查询缓存特性,检查参数 have_query_cache :
mysql> show variables like 'have_query_cache';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| have_query_cache | YES |
+------------------+-------+
1 row in set (0.00 sec)
然后我们再查看当前的查询缓存的参数设置情况:
mysql> show variables like 'query_cache%';
+------------------------------+---------+
| Variable_name | Value |
+------------------------------+---------+
| query_cache_limit | 1048576 |
| query_cache_min_res_unit | 4096 |
| query_cache_size | 0 |
| query_cache_type | ON |
| query_cache_wlock_invalidate | OFF |
+------------------------------+---------+
5 rows in set (0.00 sec)
query_cache_size 为查询缓存的大小,默认值为 0 ,表示禁用查询缓存。如果需要启用查询缓存,则需要修改这个参数的值。需要注意的是,由于查询缓存本身需要 40K 左右来保存数据结构,所以如果设置这个参数,则这个参数的值不能小于 40K 。
query_cache_type 设置查询缓存的工作方式: 0 或者 OFF ,表示阻塞查询缓存; 1 或 ON 表示允许缓存,以 SELECT SQL_NO_CACHE 开始的查询语句除外。 2 或 DEMAND ,表示仅对以 SELECT SQL_CACHE 开始的那些查询语句启用缓存。可以根据需要设置该参数的值。
query_cache_limit 设置可以被缓存的具体查询结果的最大值,默认值是 1M ,结果超过该值则不缓存。
可以使用 FLUSH QUERY CACHE 或者 RESET QUERY CACHE 来维护查询缓存:
2 FLUSH QUERY CACHE 用来清理查询缓存碎片,以提高内存使用性能。该语句不会从缓存中移出任何查询。
2 RESET QUERY CACHE 语句从查询缓存中移出所有查询。 FLUSH TABLES 语句也执行同样的工作。
可以使用 SHOW STATUS 来监控查询缓存使用的情况:
mysql> show status like 'Qcache%';
+-------------------------+-------+
| Variable_name | Value |
+-------------------------+-------+
| Qcache_free_blocks | 1 |
| Qcache_free_memory | 90752 |
| Qcache_hits | 4 |
| Qcache_inserts | 2 |
| Qcache_lowmem_prunes | 0 |
| Qcache_not_cached | 1 |
| Qcache_queries_in_cache | 2 |
| Qcache_total_blocks | 7 |
+-------------------------+-------+
8 rows in set (0.00 sec)
Qcache_hits :表示从查询缓存中返回结果的次数。
Qcache_inserts :表示加入到查询缓存的次数。
如果加入查询缓存的次数很大,但是从查询缓存返回结果的次数很小,说明查询缓存的效果并不是很好,可能是 SQL 复用的不多,也可能是结果更新的很频繁不适于缓存。
Qcache_lowmem_prunes :表示由于内存不够而从缓存删除的查询数量。如果这个值比较大,说明查询缓存设置的可能偏小,也有可能是因此导致 Qcache_hits 不够理想。
Qcache_queries_in_cache :表示当前被缓存的查询的数量,一旦数据发生了变化,则查询会自动从缓存中清除,这个值也会减小。如果 Qcache_inserts 很大,但是 Qcache_lowmem_prunes 和 Qcache_queries_in_cache 都偏小,则可能是由于表变更频繁导致不能使用查询缓存。
Qcache_not_cached :表示没有被缓存的查询的数目,查询没有被缓存的原因可能是因为结果集超过参数的设置,或者查询的时候指定 SQL_NO_CACHE ,或者是按照 query_cache_type 设定的原则,不会被缓存。

mysql 复制一个表,复制一个表结构的sql 语句

首先进入MySQL的命令行:
use database_name;
create table table_name select * from original_table_name where 1=2;
这样,就生成了一个新的表,它的表结构就与原始表相同,但是没有原始表中的数据。
如果你想把数据也一起复制过来,可以通过输入:
create table table_name select * from original_table_name where 1=1;
这样,两张表就完全相同了。

mysqld_multi stop 不能停掉mysql

使用mysqld_multi start  启动了多个mysql实例,但是mysqld_multi stop 却不能停止,为啥呢?因为你还没有授权呢。

/usr/local/mysql/bin/mysqld_multi stop  

但是默认是停不掉的,需要我们做一个授权

grant shutdown on *.* to 'username'@'localhost' identified by 'password'

另外还需要在my.cnf配置文件中加上:

[mysqld_multi]
mysqld = /usr/local/mysql/bin/mysqld_safe
mysqladmin = /usr/local/mysql/bin/mysqladmin
user = username
password = password